From 4c28d6e0517510f063f3470458012666b508efd4 Mon Sep 17 00:00:00 2001 From: "Documenter.jl" Date: Wed, 9 Oct 2024 08:12:09 +0000 Subject: [PATCH] build based on 83dee98 --- stable | 2 +- v0.18 | 2 +- v0.18.15/.documenter-siteinfo.json | 1 + v0.18.15/apidocs/apidocs/index.html | 2 + v0.18.15/apidocs/metal-api/.gitkeep | 0 v0.18.15/apidocs/metal-api/index.html | 20 + v0.18.15/assets/documenter.js | 1056 +++++++++++++++ v0.18.15/assets/favicon.ico | Bin 0 -> 34494 bytes v0.18.15/assets/logo.svg | 26 + v0.18.15/assets/terminalizer/allocate.yml | 1198 +++++++++++++++++ v0.18.15/assets/themes/documenter-dark.css | 7 + v0.18.15/assets/themes/documenter-light.css | 9 + v0.18.15/assets/themeswap.js | 84 ++ v0.18.15/assets/warner.js | 52 + v0.18.15/assets/youtube.css | 17 + .../development/client_libraries/index.html | 2 + v0.18.15/development/contributing/index.html | 2 + .../MEP1/Distributed-API-Working.png | Bin 0 -> 53600 bytes .../proposals/MEP1/Distributed-API.png | Bin 0 -> 49935 bytes .../proposals/MEP1/Distributed-Deployment.png | Bin 0 -> 34547 bytes .../proposals/MEP1/Distributed.drawio | 1 + .../proposals/MEP1/Distributed.png | Bin 0 -> 31547 bytes .../proposals/MEP1/README/index.html | 2 + .../proposals/MEP10/README/index.html | 87 ++ .../proposals/MEP11/README/index.html | 2 + .../proposals/MEP12/README/index.html | 7 + .../proposals/MEP12/partitioning-1.svg | 1 + .../proposals/MEP12/partitioning-2.svg | 1 + .../proposals/MEP12/partitioning-3.svg | 1 + .../proposals/MEP12/partitioning.drawio.svg | 486 +++++++ .../proposals/MEP12/partitioning/index.html | 2 + .../proposals/MEP14/README/index.html | 2 + .../proposals/MEP2/README/index.html | 2 + .../proposals/MEP3/README/index.html | 2 + .../proposals/MEP4/README/index.html | 14 + .../proposals/MEP5/README/index.html | 2 + .../development/proposals/MEP5/shared.drawio | 121 ++ .../development/proposals/MEP5/shared.png | Bin 0 -> 49790 bytes .../proposals/MEP5/shared_advanced.drawio | 187 +++ .../proposals/MEP5/shared_advanced.png | Bin 0 -> 90372 bytes .../proposals/MEP6/README/index.html | 38 + .../MEP6/dmz-internet_private.drawio | 178 +++ .../proposals/MEP6/dmz-internet_private.svg | 1 + .../proposals/MEP6/dmz-internet_public.drawio | 184 +++ .../proposals/MEP6/dmz-internet_public.svg | 1 + .../proposals/MEP8/README/index.html | 367 +++++ .../proposals/MEP8/filesystems.drawio | 43 + .../proposals/MEP8/filesystems.png | Bin 0 -> 24073 bytes .../proposals/MEP9/README/index.html | 13 + .../proposals/MEP9/architecture.drawio.svg | 324 +++++ v0.18.15/development/proposals/index.html | 2 + v0.18.15/development/roadmap/index.html | 2 + .../csi-driver-lvm/CONTRIBUTING/index.html | 2 + .../external/csi-driver-lvm/README/index.html | 16 + .../CONTRIBUTING/index.html | 2 + .../firewall-controller/DEVELOP/index.html | 21 + .../firewall-controller/README/index.html | 125 ++ .../firewall-controller/architecture.svg | 1 + .../external/metalctl/CONTRIBUTING/index.html | 2 + v0.18.15/external/metalctl/README/index.html | 38 + .../metalctl/docs/metalctl/index.html | 25 + .../metalctl/docs/metalctl_audit/index.html | 24 + .../docs/metalctl_audit_describe/index.html | 26 + .../docs/metalctl_audit_list/index.html | 41 + .../docs/metalctl_completion/index.html | 24 + .../docs/metalctl_completion_bash/index.html | 25 + .../docs/metalctl_completion_fish/index.html | 25 + .../metalctl_completion_powershell/index.html | 25 + .../docs/metalctl_completion_zsh/index.html | 25 + .../metalctl/docs/metalctl_context/index.html | 40 + .../docs/metalctl_context_short/index.html | 24 + .../docs/metalctl_filesystemlayout/index.html | 24 + .../index.html | 39 + .../index.html | 39 + .../index.html | 39 + .../index.html | 24 + .../metalctl_filesystemlayout_edit/index.html | 24 + .../metalctl_filesystemlayout_list/index.html | 25 + .../index.html | 26 + .../metalctl_filesystemlayout_try/index.html | 26 + .../index.html | 39 + .../docs/metalctl_firewall/index.html | 24 + .../docs/metalctl_firewall_create/index.html | 110 ++ .../metalctl_firewall_describe/index.html | 24 + .../docs/metalctl_firewall_list/index.html | 34 + .../docs/metalctl_firewall_ssh/index.html | 25 + .../docs/metalctl_firmware/index.html | 24 + .../docs/metalctl_firmware_delete/index.html | 28 + .../docs/metalctl_firmware_list/index.html | 28 + .../docs/metalctl_firmware_upload/index.html | 24 + .../metalctl_firmware_upload_bios/index.html | 27 + .../metalctl_firmware_upload_bmc/index.html | 27 + .../metalctl/docs/metalctl_health/index.html | 24 + .../metalctl/docs/metalctl_image/index.html | 24 + .../docs/metalctl_image_apply/index.html | 39 + .../docs/metalctl_image_create/index.html | 44 + .../docs/metalctl_image_delete/index.html | 39 + .../docs/metalctl_image_describe/index.html | 24 + .../docs/metalctl_image_edit/index.html | 24 + .../docs/metalctl_image_list/index.html | 32 + .../docs/metalctl_image_update/index.html | 39 + .../metalctl/docs/metalctl_login/index.html | 25 + .../metalctl/docs/metalctl_logout/index.html | 24 + .../metalctl/docs/metalctl_machine/index.html | 24 + .../docs/metalctl_machine_apply/index.html | 39 + .../docs/metalctl_machine_console/index.html | 29 + .../index.html | 25 + .../docs/metalctl_machine_create/index.html | 96 ++ .../docs/metalctl_machine_delete/index.html | 40 + .../docs/metalctl_machine_describe/index.html | 24 + .../docs/metalctl_machine_edit/index.html | 24 + .../docs/metalctl_machine_identify/index.html | 24 + .../metalctl_machine_identify_off/index.html | 25 + .../metalctl_machine_identify_on/index.html | 25 + .../docs/metalctl_machine_ipmi/index.html | 47 + .../metalctl_machine_ipmi_events/index.html | 27 + .../docs/metalctl_machine_issues/index.html | 50 + .../metalctl_machine_issues_list/index.html | 25 + .../docs/metalctl_machine_list/index.html | 47 + .../docs/metalctl_machine_lock/index.html | 26 + .../docs/metalctl_machine_logs/index.html | 25 + .../docs/metalctl_machine_power/index.html | 24 + .../metalctl_machine_power_bios/index.html | 24 + .../metalctl_machine_power_cycle/index.html | 24 + .../metalctl_machine_power_disk/index.html | 24 + .../metalctl_machine_power_off/index.html | 24 + .../docs/metalctl_machine_power_on/index.html | 24 + .../metalctl_machine_power_pxe/index.html | 24 + .../metalctl_machine_power_reset/index.html | 24 + .../metalctl_machine_reinstall/index.html | 26 + .../docs/metalctl_machine_reserve/index.html | 26 + .../index.html | 24 + .../index.html | 26 + .../index.html | 26 + .../docs/metalctl_machine_update/index.html | 42 + .../docs/metalctl_markdown/index.html | 24 + .../metalctl/docs/metalctl_network/index.html | 24 + .../docs/metalctl_network_allocate/index.html | 31 + .../docs/metalctl_network_apply/index.html | 39 + .../docs/metalctl_network_create/index.html | 53 + .../docs/metalctl_network_delete/index.html | 39 + .../docs/metalctl_network_describe/index.html | 24 + .../docs/metalctl_network_edit/index.html | 24 + .../docs/metalctl_network_free/index.html | 24 + .../docs/metalctl_network_ip/index.html | 24 + .../docs/metalctl_network_ip_apply/index.html | 39 + .../metalctl_network_ip_create/index.html | 46 + .../metalctl_network_ip_delete/index.html | 39 + .../metalctl_network_ip_describe/index.html | 24 + .../docs/metalctl_network_ip_edit/index.html | 24 + .../metalctl_network_ip_issues/index.html | 24 + .../docs/metalctl_network_ip_list/index.html | 33 + .../metalctl_network_ip_update/index.html | 39 + .../docs/metalctl_network_list/index.html | 36 + .../docs/metalctl_network_update/index.html | 48 + .../docs/metalctl_partition/index.html | 24 + .../docs/metalctl_partition_apply/index.html | 39 + .../metalctl_partition_capacity/index.html | 27 + .../docs/metalctl_partition_create/index.html | 46 + .../docs/metalctl_partition_delete/index.html | 39 + .../metalctl_partition_describe/index.html | 24 + .../docs/metalctl_partition_edit/index.html | 24 + .../docs/metalctl_partition_list/index.html | 25 + .../docs/metalctl_partition_update/index.html | 39 + .../metalctl/docs/metalctl_project/index.html | 24 + .../docs/metalctl_project_apply/index.html | 39 + .../docs/metalctl_project_create/index.html | 47 + .../docs/metalctl_project_delete/index.html | 39 + .../docs/metalctl_project_describe/index.html | 24 + .../docs/metalctl_project_edit/index.html | 24 + .../docs/metalctl_project_list/index.html | 28 + .../docs/metalctl_project_update/index.html | 39 + .../metalctl/docs/metalctl_size/index.html | 24 + .../docs/metalctl_size_apply/index.html | 39 + .../docs/metalctl_size_create/index.html | 45 + .../docs/metalctl_size_delete/index.html | 39 + .../docs/metalctl_size_describe/index.html | 24 + .../docs/metalctl_size_edit/index.html | 24 + .../metalctl_size_imageconstraint/index.html | 24 + .../index.html | 39 + .../index.html | 39 + .../index.html | 39 + .../index.html | 24 + .../index.html | 24 + .../index.html | 25 + .../index.html | 26 + .../index.html | 39 + .../docs/metalctl_size_list/index.html | 25 + .../docs/metalctl_size_reservation/index.html | 24 + .../index.html | 39 + .../index.html | 46 + .../index.html | 39 + .../index.html | 24 + .../metalctl_size_reservation_edit/index.html | 24 + .../metalctl_size_reservation_list/index.html | 29 + .../index.html | 43 + .../index.html | 28 + .../docs/metalctl_size_suggest/index.html | 28 + .../docs/metalctl_size_update/index.html | 39 + .../metalctl/docs/metalctl_switch/index.html | 24 + .../index.html | 40 + .../docs/metalctl_switch_console/index.html | 24 + .../docs/metalctl_switch_delete/index.html | 40 + .../docs/metalctl_switch_describe/index.html | 24 + .../docs/metalctl_switch_detail/index.html | 30 + .../docs/metalctl_switch_edit/index.html | 24 + .../docs/metalctl_switch_list/index.html | 31 + .../docs/metalctl_switch_port/index.html | 25 + .../metalctl_switch_port_describe/index.html | 25 + .../docs/metalctl_switch_port_down/index.html | 25 + .../docs/metalctl_switch_port_up/index.html | 25 + .../docs/metalctl_switch_replace/index.html | 24 + .../docs/metalctl_switch_ssh/index.html | 24 + .../docs/metalctl_switch_update/index.html | 39 + .../metalctl/docs/metalctl_tenant/index.html | 24 + .../docs/metalctl_tenant_apply/index.html | 39 + .../docs/metalctl_tenant_create/index.html | 47 + .../docs/metalctl_tenant_delete/index.html | 39 + .../docs/metalctl_tenant_describe/index.html | 24 + .../docs/metalctl_tenant_edit/index.html | 24 + .../docs/metalctl_tenant_list/index.html | 28 + .../docs/metalctl_tenant_update/index.html | 39 + .../metalctl/docs/metalctl_update/index.html | 24 + .../docs/metalctl_update_check/index.html | 24 + .../docs/metalctl_update_do/index.html | 25 + .../metalctl/docs/metalctl_version/index.html | 24 + .../metalctl/docs/metalctl_vpn/index.html | 24 + .../metalctl/docs/metalctl_vpn_key/index.html | 29 + .../metalctl/docs/metalctl_whoami/index.html | 24 + .../external/mini-lab/CONTRIBUTING/index.html | 2 + v0.18.15/external/mini-lab/README/index.html | 70 + v0.18.15/external/mini-lab/docs/overview.png | Bin 0 -> 314999 bytes v0.18.15/index.html | 2 + v0.18.15/installation/deployment/index.html | 317 +++++ v0.18.15/installation/mgmt_net_layer3.drawio | 1 + v0.18.15/installation/mgmt_net_layer3.png | Bin 0 -> 298312 bytes v0.18.15/installation/monitoring/index.html | 2 + v0.18.15/installation/troubleshoot/index.html | 35 + v0.18.15/installation/updates/index.html | 2 + v0.18.15/objects.inv | Bin 0 -> 7940 bytes v0.18.15/overview/2-layer-leaf-spine.drawio | 37 + v0.18.15/overview/2-layer-leaf-spine.svg | 1 + v0.18.15/overview/3-layer-leaf-spine.drawio | 55 + v0.18.15/overview/3-layer-leaf-spine.svg | 1 + v0.18.15/overview/architecture/index.html | 4 + v0.18.15/overview/comparison/index.html | 2 + v0.18.15/overview/evpn-vtep.drawio | 50 + v0.18.15/overview/evpn-vtep.svg | 1 + v0.18.15/overview/gpu-support/index.html | 23 + v0.18.15/overview/hardware/index.html | 2 + .../overview/isolated-kubernetes.drawio.svg | 284 ++++ .../overview/isolated-kubernetes/index.html | 179 +++ v0.18.15/overview/kubernetes/index.html | 2 + .../metal-stack-architecture.drawio.svg | 1103 +++++++++++++++ .../overview/metal-stack-control-plane.svg | 1 + v0.18.15/overview/metal-stack-partition.svg | 1 + v0.18.15/overview/networking/index.html | 354 +++++ v0.18.15/overview/os/index.html | 2 + .../overview/provisioning_sequence.drawio.svg | 921 +++++++++++++ v0.18.15/overview/storage/index.html | 12 + v0.18.15/overview/vrf-simple.drawio | 41 + v0.18.15/overview/vrf-simple.svg | 1 + v0.18.15/quickstart/index.html | 2 + v0.18.15/search_index.js | 3 + v0.18.15/siteinfo.js | 1 + versions.js | 2 +- 266 files changed, 13512 insertions(+), 3 deletions(-) create mode 100644 v0.18.15/.documenter-siteinfo.json create mode 100644 v0.18.15/apidocs/apidocs/index.html create mode 100644 v0.18.15/apidocs/metal-api/.gitkeep create mode 100644 v0.18.15/apidocs/metal-api/index.html create mode 100644 v0.18.15/assets/documenter.js create mode 100644 v0.18.15/assets/favicon.ico create mode 100644 v0.18.15/assets/logo.svg create mode 100644 v0.18.15/assets/terminalizer/allocate.yml create mode 100644 v0.18.15/assets/themes/documenter-dark.css create mode 100644 v0.18.15/assets/themes/documenter-light.css create mode 100644 v0.18.15/assets/themeswap.js create mode 100644 v0.18.15/assets/warner.js create mode 100644 v0.18.15/assets/youtube.css create mode 100644 v0.18.15/development/client_libraries/index.html create mode 100644 v0.18.15/development/contributing/index.html create mode 100644 v0.18.15/development/proposals/MEP1/Distributed-API-Working.png create mode 100644 v0.18.15/development/proposals/MEP1/Distributed-API.png create mode 100644 v0.18.15/development/proposals/MEP1/Distributed-Deployment.png create mode 100644 v0.18.15/development/proposals/MEP1/Distributed.drawio create mode 100644 v0.18.15/development/proposals/MEP1/Distributed.png create mode 100644 v0.18.15/development/proposals/MEP1/README/index.html create mode 100644 v0.18.15/development/proposals/MEP10/README/index.html create mode 100644 v0.18.15/development/proposals/MEP11/README/index.html create mode 100644 v0.18.15/development/proposals/MEP12/README/index.html create mode 100644 v0.18.15/development/proposals/MEP12/partitioning-1.svg create mode 100644 v0.18.15/development/proposals/MEP12/partitioning-2.svg create mode 100644 v0.18.15/development/proposals/MEP12/partitioning-3.svg create mode 100644 v0.18.15/development/proposals/MEP12/partitioning.drawio.svg create mode 100644 v0.18.15/development/proposals/MEP12/partitioning/index.html create mode 100644 v0.18.15/development/proposals/MEP14/README/index.html create mode 100644 v0.18.15/development/proposals/MEP2/README/index.html create mode 100644 v0.18.15/development/proposals/MEP3/README/index.html create mode 100644 v0.18.15/development/proposals/MEP4/README/index.html create mode 100644 v0.18.15/development/proposals/MEP5/README/index.html create mode 100644 v0.18.15/development/proposals/MEP5/shared.drawio create mode 100644 v0.18.15/development/proposals/MEP5/shared.png create mode 100644 v0.18.15/development/proposals/MEP5/shared_advanced.drawio create mode 100644 v0.18.15/development/proposals/MEP5/shared_advanced.png create mode 100644 v0.18.15/development/proposals/MEP6/README/index.html create mode 100644 v0.18.15/development/proposals/MEP6/dmz-internet_private.drawio create mode 100644 v0.18.15/development/proposals/MEP6/dmz-internet_private.svg create mode 100644 v0.18.15/development/proposals/MEP6/dmz-internet_public.drawio create mode 100644 v0.18.15/development/proposals/MEP6/dmz-internet_public.svg create mode 100644 v0.18.15/development/proposals/MEP8/README/index.html create mode 100644 v0.18.15/development/proposals/MEP8/filesystems.drawio create mode 100644 v0.18.15/development/proposals/MEP8/filesystems.png create mode 100644 v0.18.15/development/proposals/MEP9/README/index.html create mode 100644 v0.18.15/development/proposals/MEP9/architecture.drawio.svg create mode 100644 v0.18.15/development/proposals/index.html create mode 100644 v0.18.15/development/roadmap/index.html create mode 100644 v0.18.15/external/csi-driver-lvm/CONTRIBUTING/index.html create mode 100644 v0.18.15/external/csi-driver-lvm/README/index.html create mode 100644 v0.18.15/external/firewall-controller/CONTRIBUTING/index.html create mode 100644 v0.18.15/external/firewall-controller/DEVELOP/index.html create mode 100644 v0.18.15/external/firewall-controller/README/index.html create mode 100644 v0.18.15/external/firewall-controller/architecture.svg create mode 100644 v0.18.15/external/metalctl/CONTRIBUTING/index.html create mode 100644 v0.18.15/external/metalctl/README/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_audit/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_audit_describe/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_audit_list/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_completion/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_completion_bash/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_completion_fish/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_completion_powershell/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_completion_zsh/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_context/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_context_short/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_filesystemlayout/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_filesystemlayout_apply/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_filesystemlayout_create/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_filesystemlayout_delete/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_filesystemlayout_describe/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_filesystemlayout_edit/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_filesystemlayout_list/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_filesystemlayout_match/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_filesystemlayout_try/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_filesystemlayout_update/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_firewall/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_firewall_create/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_firewall_describe/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_firewall_list/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_firewall_ssh/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_firmware/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_firmware_delete/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_firmware_list/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_firmware_upload/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_firmware_upload_bios/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_firmware_upload_bmc/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_health/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_image/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_image_apply/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_image_create/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_image_delete/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_image_describe/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_image_edit/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_image_list/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_image_update/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_login/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_logout/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_machine/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_machine_apply/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_machine_console/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_machine_consolepassword/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_machine_create/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_machine_delete/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_machine_describe/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_machine_edit/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_machine_identify/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_machine_identify_off/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_machine_identify_on/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_machine_ipmi/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_machine_ipmi_events/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_machine_issues/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_machine_issues_list/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_machine_list/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_machine_lock/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_machine_logs/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_machine_power/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_machine_power_bios/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_machine_power_cycle/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_machine_power_disk/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_machine_power_off/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_machine_power_on/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_machine_power_pxe/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_machine_power_reset/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_machine_reinstall/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_machine_reserve/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_machine_update-firmware/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_machine_update-firmware_bios/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_machine_update-firmware_bmc/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_machine_update/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_markdown/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_network/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_network_allocate/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_network_apply/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_network_create/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_network_delete/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_network_describe/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_network_edit/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_network_free/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_network_ip/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_network_ip_apply/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_network_ip_create/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_network_ip_delete/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_network_ip_describe/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_network_ip_edit/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_network_ip_issues/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_network_ip_list/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_network_ip_update/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_network_list/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_network_update/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_partition/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_partition_apply/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_partition_capacity/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_partition_create/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_partition_delete/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_partition_describe/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_partition_edit/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_partition_list/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_partition_update/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_project/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_project_apply/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_project_create/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_project_delete/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_project_describe/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_project_edit/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_project_list/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_project_update/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_size/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_size_apply/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_size_create/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_size_delete/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_size_describe/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_size_edit/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_size_imageconstraint/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_size_imageconstraint_apply/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_size_imageconstraint_create/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_size_imageconstraint_delete/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_size_imageconstraint_describe/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_size_imageconstraint_edit/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_size_imageconstraint_list/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_size_imageconstraint_try/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_size_imageconstraint_update/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_size_list/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_size_reservation/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_size_reservation_apply/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_size_reservation_create/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_size_reservation_delete/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_size_reservation_describe/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_size_reservation_edit/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_size_reservation_list/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_size_reservation_update/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_size_reservation_usage/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_size_suggest/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_size_update/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_switch/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_switch_connected-machines/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_switch_console/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_switch_delete/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_switch_describe/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_switch_detail/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_switch_edit/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_switch_list/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_switch_port/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_switch_port_describe/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_switch_port_down/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_switch_port_up/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_switch_replace/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_switch_ssh/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_switch_update/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_tenant/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_tenant_apply/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_tenant_create/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_tenant_delete/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_tenant_describe/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_tenant_edit/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_tenant_list/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_tenant_update/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_update/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_update_check/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_update_do/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_version/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_vpn/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_vpn_key/index.html create mode 100644 v0.18.15/external/metalctl/docs/metalctl_whoami/index.html create mode 100644 v0.18.15/external/mini-lab/CONTRIBUTING/index.html create mode 100644 v0.18.15/external/mini-lab/README/index.html create mode 100644 v0.18.15/external/mini-lab/docs/overview.png create mode 100644 v0.18.15/index.html create mode 100644 v0.18.15/installation/deployment/index.html create mode 100644 v0.18.15/installation/mgmt_net_layer3.drawio create mode 100644 v0.18.15/installation/mgmt_net_layer3.png create mode 100644 v0.18.15/installation/monitoring/index.html create mode 100644 v0.18.15/installation/troubleshoot/index.html create mode 100644 v0.18.15/installation/updates/index.html create mode 100644 v0.18.15/objects.inv create mode 100644 v0.18.15/overview/2-layer-leaf-spine.drawio create mode 100644 v0.18.15/overview/2-layer-leaf-spine.svg create mode 100644 v0.18.15/overview/3-layer-leaf-spine.drawio create mode 100644 v0.18.15/overview/3-layer-leaf-spine.svg create mode 100644 v0.18.15/overview/architecture/index.html create mode 100644 v0.18.15/overview/comparison/index.html create mode 100644 v0.18.15/overview/evpn-vtep.drawio create mode 100644 v0.18.15/overview/evpn-vtep.svg create mode 100644 v0.18.15/overview/gpu-support/index.html create mode 100644 v0.18.15/overview/hardware/index.html create mode 100644 v0.18.15/overview/isolated-kubernetes.drawio.svg create mode 100644 v0.18.15/overview/isolated-kubernetes/index.html create mode 100644 v0.18.15/overview/kubernetes/index.html create mode 100644 v0.18.15/overview/metal-stack-architecture.drawio.svg create mode 100644 v0.18.15/overview/metal-stack-control-plane.svg create mode 100644 v0.18.15/overview/metal-stack-partition.svg create mode 100644 v0.18.15/overview/networking/index.html create mode 100644 v0.18.15/overview/os/index.html create mode 100644 v0.18.15/overview/provisioning_sequence.drawio.svg create mode 100644 v0.18.15/overview/storage/index.html create mode 100644 v0.18.15/overview/vrf-simple.drawio create mode 100644 v0.18.15/overview/vrf-simple.svg create mode 100644 v0.18.15/quickstart/index.html create mode 100644 v0.18.15/search_index.js create mode 100644 v0.18.15/siteinfo.js diff --git a/stable b/stable index f500c39d9d..a6403d034c 120000 --- a/stable +++ b/stable @@ -1 +1 @@ -v0.18.14 \ No newline at end of file +v0.18.15 \ No newline at end of file diff --git a/v0.18 b/v0.18 index f500c39d9d..a6403d034c 120000 --- a/v0.18 +++ b/v0.18 @@ -1 +1 @@ -v0.18.14 \ No newline at end of file +v0.18.15 \ No newline at end of file diff --git a/v0.18.15/.documenter-siteinfo.json b/v0.18.15/.documenter-siteinfo.json new file mode 100644 index 0000000000..39cef3724a --- /dev/null +++ b/v0.18.15/.documenter-siteinfo.json @@ -0,0 +1 @@ +{"documenter":{"julia_version":"1.9.4","generation_timestamp":"2024-10-09T08:11:48","documenter_version":"1.3.0"}} \ No newline at end of file diff --git a/v0.18.15/apidocs/apidocs/index.html b/v0.18.15/apidocs/apidocs/index.html new file mode 100644 index 0000000000..e6d3b18369 --- /dev/null +++ b/v0.18.15/apidocs/apidocs/index.html @@ -0,0 +1,2 @@ + +API Documentation · metal-stack
diff --git a/v0.18.15/apidocs/metal-api/.gitkeep b/v0.18.15/apidocs/metal-api/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/v0.18.15/apidocs/metal-api/index.html b/v0.18.15/apidocs/metal-api/index.html new file mode 100644 index 0000000000..91d8c0f867 --- /dev/null +++ b/v0.18.15/apidocs/metal-api/index.html @@ -0,0 +1,20 @@ + + + + metal-api + + + + + + + + + + + diff --git a/v0.18.15/assets/documenter.js b/v0.18.15/assets/documenter.js new file mode 100644 index 0000000000..f451139be9 --- /dev/null +++ b/v0.18.15/assets/documenter.js @@ -0,0 +1,1056 @@ +// Generated by Documenter.jl +requirejs.config({ + paths: { + 'highlight-julia': 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/languages/julia.min', + 'headroom': 'https://cdnjs.cloudflare.com/ajax/libs/headroom/0.12.0/headroom.min', + 'jqueryui': 'https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.13.2/jquery-ui.min', + 'highlight-yaml': 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/languages/yaml.min', + 'katex-auto-render': 'https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.16.8/contrib/auto-render.min', + 'jquery': 'https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.0/jquery.min', + 'headroom-jquery': 'https://cdnjs.cloudflare.com/ajax/libs/headroom/0.12.0/jQuery.headroom.min', + 'katex': 'https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.16.8/katex.min', + 'highlight': 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/highlight.min', + 'highlight-julia-repl': 'https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.8.0/languages/julia-repl.min', + }, + shim: { + "highlight-julia": { + "deps": [ + "highlight" + ] + }, + "highlight-yaml": { + "deps": [ + "highlight" + ] + }, + "katex-auto-render": { + "deps": [ + "katex" + ] + }, + "headroom-jquery": { + "deps": [ + "jquery", + "headroom" + ] + }, + "highlight-julia-repl": { + "deps": [ + "highlight" + ] + } +} +}); +//////////////////////////////////////////////////////////////////////////////// +require(['jquery', 'katex', 'katex-auto-render'], function($, katex, renderMathInElement) { +$(document).ready(function() { + renderMathInElement( + document.body, + { + "delimiters": [ + { + "left": "$", + "right": "$", + "display": false + }, + { + "left": "$$", + "right": "$$", + "display": true + }, + { + "left": "\\[", + "right": "\\]", + "display": true + } + ] +} + + ); +}) + +}) +//////////////////////////////////////////////////////////////////////////////// +require(['jquery', 'highlight', 'highlight-julia', 'highlight-julia-repl', 'highlight-yaml'], function($) { +$(document).ready(function() { + hljs.highlightAll(); +}) + +}) +//////////////////////////////////////////////////////////////////////////////// +require(['jquery'], function($) { + +let timer = 0; +var isExpanded = true; + +$(document).on("click", ".docstring header", function () { + let articleToggleTitle = "Expand docstring"; + + debounce(() => { + if ($(this).siblings("section").is(":visible")) { + $(this) + .find(".docstring-article-toggle-button") + .removeClass("fa-chevron-down") + .addClass("fa-chevron-right"); + } else { + $(this) + .find(".docstring-article-toggle-button") + .removeClass("fa-chevron-right") + .addClass("fa-chevron-down"); + + articleToggleTitle = "Collapse docstring"; + } + + $(this) + .find(".docstring-article-toggle-button") + .prop("title", articleToggleTitle); + $(this).siblings("section").slideToggle(); + }); +}); + +$(document).on("click", ".docs-article-toggle-button", function (event) { + let articleToggleTitle = "Expand docstring"; + let navArticleToggleTitle = "Expand all docstrings"; + let animationSpeed = event.noToggleAnimation ? 0 : 400; + + debounce(() => { + if (isExpanded) { + $(this).removeClass("fa-chevron-up").addClass("fa-chevron-down"); + $(".docstring-article-toggle-button") + .removeClass("fa-chevron-down") + .addClass("fa-chevron-right"); + + isExpanded = false; + + $(".docstring section").slideUp(animationSpeed); + } else { + $(this).removeClass("fa-chevron-down").addClass("fa-chevron-up"); + $(".docstring-article-toggle-button") + .removeClass("fa-chevron-right") + .addClass("fa-chevron-down"); + + isExpanded = true; + articleToggleTitle = "Collapse docstring"; + navArticleToggleTitle = "Collapse all docstrings"; + + $(".docstring section").slideDown(animationSpeed); + } + + $(this).prop("title", navArticleToggleTitle); + $(".docstring-article-toggle-button").prop("title", articleToggleTitle); + }); +}); + +function debounce(callback, timeout = 300) { + if (Date.now() - timer > timeout) { + callback(); + } + + clearTimeout(timer); + + timer = Date.now(); +} + +}) +//////////////////////////////////////////////////////////////////////////////// +require([], function() { +function addCopyButtonCallbacks() { + for (const el of document.getElementsByTagName("pre")) { + const button = document.createElement("button"); + button.classList.add("copy-button", "fa-solid", "fa-copy"); + button.setAttribute("aria-label", "Copy this code block"); + button.setAttribute("title", "Copy"); + + el.appendChild(button); + + const success = function () { + button.classList.add("success", "fa-check"); + button.classList.remove("fa-copy"); + }; + + const failure = function () { + button.classList.add("error", "fa-xmark"); + button.classList.remove("fa-copy"); + }; + + button.addEventListener("click", function () { + copyToClipboard(el.innerText).then(success, failure); + + setTimeout(function () { + button.classList.add("fa-copy"); + button.classList.remove("success", "fa-check", "fa-xmark"); + }, 5000); + }); + } +} + +function copyToClipboard(text) { + // clipboard API is only available in secure contexts + if (window.navigator && window.navigator.clipboard) { + return window.navigator.clipboard.writeText(text); + } else { + return new Promise(function (resolve, reject) { + try { + const el = document.createElement("textarea"); + el.textContent = text; + el.style.position = "fixed"; + el.style.opacity = 0; + document.body.appendChild(el); + el.select(); + document.execCommand("copy"); + + resolve(); + } catch (err) { + reject(err); + } finally { + document.body.removeChild(el); + } + }); + } +} + +if (document.readyState === "loading") { + document.addEventListener("DOMContentLoaded", addCopyButtonCallbacks); +} else { + addCopyButtonCallbacks(); +} + +}) +//////////////////////////////////////////////////////////////////////////////// +require(['jquery', 'headroom', 'headroom-jquery'], function($, Headroom) { + +// Manages the top navigation bar (hides it when the user starts scrolling down on the +// mobile). +window.Headroom = Headroom; // work around buggy module loading? +$(document).ready(function () { + $("#documenter .docs-navbar").headroom({ + tolerance: { up: 10, down: 10 }, + }); +}); + +}) +//////////////////////////////////////////////////////////////////////////////// +require(['jquery'], function($) { + +$(document).ready(function () { + let meta = $("div[data-docstringscollapsed]").data(); + + if (meta?.docstringscollapsed) { + $("#documenter-article-toggle-button").trigger({ + type: "click", + noToggleAnimation: true, + }); + } +}); + +}) +//////////////////////////////////////////////////////////////////////////////// +require(['jquery'], function($) { + +/* +To get an in-depth about the thought process you can refer: https://hetarth02.hashnode.dev/series/gsoc + +PSEUDOCODE: + +Searching happens automatically as the user types or adjusts the selected filters. +To preserve responsiveness, as much as possible of the slow parts of the search are done +in a web worker. Searching and result generation are done in the worker, and filtering and +DOM updates are done in the main thread. The filters are in the main thread as they should +be very quick to apply. This lets filters be changed without re-searching with minisearch +(which is possible even if filtering is on the worker thread) and also lets filters be +changed _while_ the worker is searching and without message passing (neither of which are +possible if filtering is on the worker thread) + +SEARCH WORKER: + +Import minisearch + +Build index + +On message from main thread + run search + find the first 200 unique results from each category, and compute their divs for display + note that this is necessary and sufficient information for the main thread to find the + first 200 unique results from any given filter set + post results to main thread + +MAIN: + +Launch worker + +Declare nonconstant globals (worker_is_running, last_search_text, unfiltered_results) + +On text update + if worker is not running, launch_search() + +launch_search + set worker_is_running to true, set last_search_text to the search text + post the search query to worker + +on message from worker + if last_search_text is not the same as the text in the search field, + the latest search result is not reflective of the latest search query, so update again + launch_search() + otherwise + set worker_is_running to false + + regardless, display the new search results to the user + save the unfiltered_results as a global + update_search() + +on filter click + adjust the filter selection + update_search() + +update_search + apply search filters by looping through the unfiltered_results and finding the first 200 + unique results that match the filters + + Update the DOM +*/ + +/////// SEARCH WORKER /////// + +function worker_function(documenterSearchIndex, documenterBaseURL, filters) { + importScripts( + "https://cdn.jsdelivr.net/npm/minisearch@6.1.0/dist/umd/index.min.js" + ); + + let data = documenterSearchIndex.map((x, key) => { + x["id"] = key; // minisearch requires a unique for each object + return x; + }); + + // list below is the lunr 2.1.3 list minus the intersect with names(Base) + // (all, any, get, in, is, only, which) and (do, else, for, let, where, while, with) + // ideally we'd just filter the original list but it's not available as a variable + const stopWords = new Set([ + "a", + "able", + "about", + "across", + "after", + "almost", + "also", + "am", + "among", + "an", + "and", + "are", + "as", + "at", + "be", + "because", + "been", + "but", + "by", + "can", + "cannot", + "could", + "dear", + "did", + "does", + "either", + "ever", + "every", + "from", + "got", + "had", + "has", + "have", + "he", + "her", + "hers", + "him", + "his", + "how", + "however", + "i", + "if", + "into", + "it", + "its", + "just", + "least", + "like", + "likely", + "may", + "me", + "might", + "most", + "must", + "my", + "neither", + "no", + "nor", + "not", + "of", + "off", + "often", + "on", + "or", + "other", + "our", + "own", + "rather", + "said", + "say", + "says", + "she", + "should", + "since", + "so", + "some", + "than", + "that", + "the", + "their", + "them", + "then", + "there", + "these", + "they", + "this", + "tis", + "to", + "too", + "twas", + "us", + "wants", + "was", + "we", + "were", + "what", + "when", + "who", + "whom", + "why", + "will", + "would", + "yet", + "you", + "your", + ]); + + let index = new MiniSearch({ + fields: ["title", "text"], // fields to index for full-text search + storeFields: ["location", "title", "text", "category", "page"], // fields to return with results + processTerm: (term) => { + let word = stopWords.has(term) ? null : term; + if (word) { + // custom trimmer that doesn't strip @ and !, which are used in julia macro and function names + word = word + .replace(/^[^a-zA-Z0-9@!]+/, "") + .replace(/[^a-zA-Z0-9@!]+$/, ""); + + word = word.toLowerCase(); + } + + return word ?? null; + }, + // add . as a separator, because otherwise "title": "Documenter.Anchors.add!", would not + // find anything if searching for "add!", only for the entire qualification + tokenize: (string) => string.split(/[\s\-\.]+/), + // options which will be applied during the search + searchOptions: { + prefix: true, + boost: { title: 100 }, + fuzzy: 2, + }, + }); + + index.addAll(data); + + /** + * Used to map characters to HTML entities. + * Refer: https://github.com/lodash/lodash/blob/main/src/escape.ts + */ + const htmlEscapes = { + "&": "&", + "<": "<", + ">": ">", + '"': """, + "'": "'", + }; + + /** + * Used to match HTML entities and HTML characters. + * Refer: https://github.com/lodash/lodash/blob/main/src/escape.ts + */ + const reUnescapedHtml = /[&<>"']/g; + const reHasUnescapedHtml = RegExp(reUnescapedHtml.source); + + /** + * Escape function from lodash + * Refer: https://github.com/lodash/lodash/blob/main/src/escape.ts + */ + function escape(string) { + return string && reHasUnescapedHtml.test(string) + ? string.replace(reUnescapedHtml, (chr) => htmlEscapes[chr]) + : string || ""; + } + + /** + * Make the result component given a minisearch result data object and the value + * of the search input as queryString. To view the result object structure, refer: + * https://lucaong.github.io/minisearch/modules/_minisearch_.html#searchresult + * + * @param {object} result + * @param {string} querystring + * @returns string + */ + function make_search_result(result, querystring) { + let search_divider = `
`; + let display_link = + result.location.slice(Math.max(0), Math.min(50, result.location.length)) + + (result.location.length > 30 ? "..." : ""); // To cut-off the link because it messes with the overflow of the whole div + + if (result.page !== "") { + display_link += ` (${result.page})`; + } + + let textindex = new RegExp(`${querystring}`, "i").exec(result.text); + let text = + textindex !== null + ? result.text.slice( + Math.max(textindex.index - 100, 0), + Math.min( + textindex.index + querystring.length + 100, + result.text.length + ) + ) + : ""; // cut-off text before and after from the match + + text = text.length ? escape(text) : ""; + + let display_result = text.length + ? "..." + + text.replace( + new RegExp(`${escape(querystring)}`, "i"), // For first occurrence + '$&' + ) + + "..." + : ""; // highlights the match + + let in_code = false; + if (!["page", "section"].includes(result.category.toLowerCase())) { + in_code = true; + } + + // We encode the full url to escape some special characters which can lead to broken links + let result_div = ` + +
+
${escape(result.title)}
+
${result.category}
+
+

+ ${display_result} +

+
+ ${display_link} +
+
+ ${search_divider} + `; + + return result_div; + } + + self.onmessage = function (e) { + let query = e.data; + let results = index.search(query, { + filter: (result) => { + // Only return relevant results + return result.score >= 1; + }, + }); + + // Pre-filter to deduplicate and limit to 200 per category to the extent + // possible without knowing what the filters are. + let filtered_results = []; + let counts = {}; + for (let filter of filters) { + counts[filter] = 0; + } + let present = {}; + + for (let result of results) { + cat = result.category; + cnt = counts[cat]; + if (cnt < 200) { + id = cat + "---" + result.location; + if (present[id]) { + continue; + } + present[id] = true; + filtered_results.push({ + location: result.location, + category: cat, + div: make_search_result(result, query), + }); + } + } + + postMessage(filtered_results); + }; +} + +// `worker = Threads.@spawn worker_function(documenterSearchIndex)`, but in JavaScript! +const filters = [ + ...new Set(documenterSearchIndex["docs"].map((x) => x.category)), +]; +const worker_str = + "(" + + worker_function.toString() + + ")(" + + JSON.stringify(documenterSearchIndex["docs"]) + + "," + + JSON.stringify(documenterBaseURL) + + "," + + JSON.stringify(filters) + + ")"; +const worker_blob = new Blob([worker_str], { type: "text/javascript" }); +const worker = new Worker(URL.createObjectURL(worker_blob)); + +/////// SEARCH MAIN /////// + +// Whether the worker is currently handling a search. This is a boolean +// as the worker only ever handles 1 or 0 searches at a time. +var worker_is_running = false; + +// The last search text that was sent to the worker. This is used to determine +// if the worker should be launched again when it reports back results. +var last_search_text = ""; + +// The results of the last search. This, in combination with the state of the filters +// in the DOM, is used compute the results to display on calls to update_search. +var unfiltered_results = []; + +// Which filter is currently selected +var selected_filter = ""; + +$(document).on("input", ".documenter-search-input", function (event) { + if (!worker_is_running) { + launch_search(); + } +}); + +function launch_search() { + worker_is_running = true; + last_search_text = $(".documenter-search-input").val(); + worker.postMessage(last_search_text); +} + +worker.onmessage = function (e) { + if (last_search_text !== $(".documenter-search-input").val()) { + launch_search(); + } else { + worker_is_running = false; + } + + unfiltered_results = e.data; + update_search(); +}; + +$(document).on("click", ".search-filter", function () { + if ($(this).hasClass("search-filter-selected")) { + selected_filter = ""; + } else { + selected_filter = $(this).text().toLowerCase(); + } + + // This updates search results and toggles classes for UI: + update_search(); +}); + +/** + * Make/Update the search component + */ +function update_search() { + let querystring = $(".documenter-search-input").val(); + + if (querystring.trim()) { + if (selected_filter == "") { + results = unfiltered_results; + } else { + results = unfiltered_results.filter((result) => { + return selected_filter == result.category.toLowerCase(); + }); + } + + let search_result_container = ``; + let modal_filters = make_modal_body_filters(); + let search_divider = `
`; + + if (results.length) { + let links = []; + let count = 0; + let search_results = ""; + + for (var i = 0, n = results.length; i < n && count < 200; ++i) { + let result = results[i]; + if (result.location && !links.includes(result.location)) { + search_results += result.div; + count++; + links.push(result.location); + } + } + + if (count == 1) { + count_str = "1 result"; + } else if (count == 200) { + count_str = "200+ results"; + } else { + count_str = count + " results"; + } + let result_count = `
${count_str}
`; + + search_result_container = ` +
+ ${modal_filters} + ${search_divider} + ${result_count} +
+ ${search_results} +
+
+ `; + } else { + search_result_container = ` +
+ ${modal_filters} + ${search_divider} +
0 result(s)
+
+
No result found!
+ `; + } + + if ($(".search-modal-card-body").hasClass("is-justify-content-center")) { + $(".search-modal-card-body").removeClass("is-justify-content-center"); + } + + $(".search-modal-card-body").html(search_result_container); + } else { + if (!$(".search-modal-card-body").hasClass("is-justify-content-center")) { + $(".search-modal-card-body").addClass("is-justify-content-center"); + } + + $(".search-modal-card-body").html(` +
Type something to get started!
+ `); + } +} + +/** + * Make the modal filter html + * + * @returns string + */ +function make_modal_body_filters() { + let str = filters + .map((val) => { + if (selected_filter == val.toLowerCase()) { + return `${val}`; + } else { + return `${val}`; + } + }) + .join(""); + + return ` +
+ Filters: + ${str} +
`; +} + +}) +//////////////////////////////////////////////////////////////////////////////// +require(['jquery'], function($) { + +// Modal settings dialog +$(document).ready(function () { + var settings = $("#documenter-settings"); + $("#documenter-settings-button").click(function () { + settings.toggleClass("is-active"); + }); + // Close the dialog if X is clicked + $("#documenter-settings button.delete").click(function () { + settings.removeClass("is-active"); + }); + // Close dialog if ESC is pressed + $(document).keyup(function (e) { + if (e.keyCode == 27) settings.removeClass("is-active"); + }); +}); + +}) +//////////////////////////////////////////////////////////////////////////////// +require(['jquery'], function($) { + +$(document).ready(function () { + let search_modal_header = ` + + `; + + let initial_search_body = ` +
Type something to get started!
+ `; + + let search_modal_footer = ` + + `; + + $(document.body).append( + ` + + ` + ); + + document.querySelector(".docs-search-query").addEventListener("click", () => { + openModal(); + }); + + document + .querySelector(".close-search-modal") + .addEventListener("click", () => { + closeModal(); + }); + + $(document).on("click", ".search-result-link", function () { + closeModal(); + }); + + document.addEventListener("keydown", (event) => { + if ((event.ctrlKey || event.metaKey) && event.key === "/") { + openModal(); + } else if (event.key === "Escape") { + closeModal(); + } + + return false; + }); + + // Functions to open and close a modal + function openModal() { + let searchModal = document.querySelector("#search-modal"); + + searchModal.classList.add("is-active"); + document.querySelector(".documenter-search-input").focus(); + } + + function closeModal() { + let searchModal = document.querySelector("#search-modal"); + let initial_search_body = ` +
Type something to get started!
+ `; + + searchModal.classList.remove("is-active"); + document.querySelector(".documenter-search-input").blur(); + + if (!$(".search-modal-card-body").hasClass("is-justify-content-center")) { + $(".search-modal-card-body").addClass("is-justify-content-center"); + } + + $(".documenter-search-input").val(""); + $(".search-modal-card-body").html(initial_search_body); + } + + document + .querySelector("#search-modal .modal-background") + .addEventListener("click", () => { + closeModal(); + }); +}); + +}) +//////////////////////////////////////////////////////////////////////////////// +require(['jquery'], function($) { + +// Manages the showing and hiding of the sidebar. +$(document).ready(function () { + var sidebar = $("#documenter > .docs-sidebar"); + var sidebar_button = $("#documenter-sidebar-button"); + sidebar_button.click(function (ev) { + ev.preventDefault(); + sidebar.toggleClass("visible"); + if (sidebar.hasClass("visible")) { + // Makes sure that the current menu item is visible in the sidebar. + $("#documenter .docs-menu a.is-active").focus(); + } + }); + $("#documenter > .docs-main").bind("click", function (ev) { + if ($(ev.target).is(sidebar_button)) { + return; + } + if (sidebar.hasClass("visible")) { + sidebar.removeClass("visible"); + } + }); +}); + +// Resizes the package name / sitename in the sidebar if it is too wide. +// Inspired by: https://github.com/davatron5000/FitText.js +$(document).ready(function () { + e = $("#documenter .docs-autofit"); + function resize() { + var L = parseInt(e.css("max-width"), 10); + var L0 = e.width(); + if (L0 > L) { + var h0 = parseInt(e.css("font-size"), 10); + e.css("font-size", (L * h0) / L0); + // TODO: make sure it survives resizes? + } + } + // call once and then register events + resize(); + $(window).resize(resize); + $(window).on("orientationchange", resize); +}); + +// Scroll the navigation bar to the currently selected menu item +$(document).ready(function () { + var sidebar = $("#documenter .docs-menu").get(0); + var active = $("#documenter .docs-menu .is-active").get(0); + if (typeof active !== "undefined") { + sidebar.scrollTop = active.offsetTop - sidebar.offsetTop - 15; + } +}); + +}) +//////////////////////////////////////////////////////////////////////////////// +require(['jquery'], function($) { + +// Theme picker setup +$(document).ready(function () { + // onchange callback + $("#documenter-themepicker").change(function themepick_callback(ev) { + var themename = $("#documenter-themepicker option:selected").attr("value"); + if (themename === "auto") { + // set_theme(window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'); + window.localStorage.removeItem("documenter-theme"); + } else { + // set_theme(themename); + window.localStorage.setItem("documenter-theme", themename); + } + // We re-use the global function from themeswap.js to actually do the swapping. + set_theme_from_local_storage(); + }); + + // Make sure that the themepicker displays the correct theme when the theme is retrieved + // from localStorage + if (typeof window.localStorage !== "undefined") { + var theme = window.localStorage.getItem("documenter-theme"); + if (theme !== null) { + $("#documenter-themepicker option").each(function (i, e) { + e.selected = e.value === theme; + }); + } + } +}); + +}) +//////////////////////////////////////////////////////////////////////////////// +require(['jquery'], function($) { + +// update the version selector with info from the siteinfo.js and ../versions.js files +$(document).ready(function () { + // If the version selector is disabled with DOCUMENTER_VERSION_SELECTOR_DISABLED in the + // siteinfo.js file, we just return immediately and not display the version selector. + if ( + typeof DOCUMENTER_VERSION_SELECTOR_DISABLED === "boolean" && + DOCUMENTER_VERSION_SELECTOR_DISABLED + ) { + return; + } + + var version_selector = $("#documenter .docs-version-selector"); + var version_selector_select = $("#documenter .docs-version-selector select"); + + version_selector_select.change(function (x) { + target_href = version_selector_select + .children("option:selected") + .get(0).value; + window.location.href = target_href; + }); + + // add the current version to the selector based on siteinfo.js, but only if the selector is empty + if ( + typeof DOCUMENTER_CURRENT_VERSION !== "undefined" && + $("#version-selector > option").length == 0 + ) { + var option = $( + "" + ); + version_selector_select.append(option); + } + + if (typeof DOC_VERSIONS !== "undefined") { + var existing_versions = version_selector_select.children("option"); + var existing_versions_texts = existing_versions.map(function (i, x) { + return x.text; + }); + DOC_VERSIONS.forEach(function (each) { + var version_url = documenterBaseURL + "/../" + each + "/"; + var existing_id = $.inArray(each, existing_versions_texts); + // if not already in the version selector, add it as a new option, + // otherwise update the old option with the URL and enable it + if (existing_id == -1) { + var option = $( + "" + ); + version_selector_select.append(option); + } else { + var option = existing_versions[existing_id]; + option.value = version_url; + option.disabled = false; + } + }); + } + + // only show the version selector if the selector has been populated + if (version_selector_select.children("option").length > 0) { + version_selector.toggleClass("visible"); + } +}); + +}) diff --git a/v0.18.15/assets/favicon.ico b/v0.18.15/assets/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..641e27d512aecf60823d69bdb928b0cef64a1a7c GIT binary patch literal 34494 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 + + diff --git a/v0.18.15/assets/terminalizer/allocate.yml b/v0.18.15/assets/terminalizer/allocate.yml new file mode 100644 index 0000000000..e696a238b1 --- /dev/null +++ b/v0.18.15/assets/terminalizer/allocate.yml @@ -0,0 +1,1198 @@ +# The configurations that used for the recording, feel free to edit them +config: + + # Specify a command to be executed + # like `/bin/bash -l`, `ls`, or any other commands + # the default is bash for Linux + # or powershell.exe for Windows + command: bash -l + + # Specify the current working directory path + # the default is the current working directory path + cwd: /home/schge01/Meetup + + # Export additional ENV variables + env: + recording: true + + # Explicitly set the number of columns + # or use `auto` to take the current + # number of columns of your shell + cols: 140 + + # Explicitly set the number of rows + # or use `auto` to take the current + # number of rows of your shell + rows: 30 + + # Amount of times to repeat GIF + # If value is -1, play once + # If value is 0, loop indefinitely + # If value is a positive number, loop n times + repeat: -1 + + # Quality + # 1 - 100 + quality: 100 + + # Delay between frames in ms + # If the value is `auto` use the actual recording delays + frameDelay: auto + + # Maximum delay between frames in ms + # Ignored if the `frameDelay` isn't set to `auto` + # Set to `auto` to prevent limiting the max idle time + maxIdleTime: auto + + # The surrounding frame box + # The `type` can be null, window, floating, or solid` + # To hide the title use the value null + # Don't forget to add a backgroundColor style with a null as type + frameBox: + type: null + title: null + style: + backgroundColor: black + + # Add a watermark image to the rendered gif + # You need to specify an absolute path for + # the image on your machine or a URL, and you can also + # add your own CSS styles + watermark: + imagePath: null + style: + position: absolute + right: 15px + bottom: 15px + width: 100px + opacity: 0.9 + + # Cursor style can be one of + # `block`, `underline`, or `bar` + cursorStyle: block + + # Font family + # You can use any font that is installed on your machine + # in CSS-like syntax + fontFamily: 'Monospace, "Noto Color Emoji"' + + # The size of the font + fontSize: 18 + + # The height of lines + lineHeight: 1 + + # The spacing between letters + letterSpacing: 0 + + # Theme + theme: + background: "transparent" + foreground: "#afafaf" + cursor: "#c7c7c7" + black: "#232628" + red: "#fc4384" + green: "#b3e33b" + yellow: "#ffa727" + blue: "#75dff2" + magenta: "#ae89fe" + cyan: "#708387" + white: "#d5d5d0" + brightBlack: "#626566" + brightRed: "#ff7fac" + brightGreen: "#c8ed71" + brightYellow: "#ebdf86" + brightBlue: "#75dff2" + brightMagenta: "#ae89fe" + brightCyan: "#b1c6ca" + brightWhite: "#f9f9f4" + +# Records, feel free to edit them +records: + - delay: 0 + content: '$ metalctl machine console 00000000-0000-0000-0000-ac1f6b7aeb76 --ipmi' + - delay: 4000 + content: "\r\n" + - delay: 823 + content: "[SOL Session operational. Use ~? for help]\r\n" + - delay: 1190 + content: "\e[32mINFO\e[0m[09-21|12:44:46] wait for install timeout retrying... \e[32mstatuscode\e[0m=304 \e[32mcaller\e[0m=wait.go:40\r\n" + - delay: 4601 + content: "\e[36mDBUG\e[0m[09-21|12:44:51] lldp \e[36mneigh\e[0m=\"Name:fra-equ01-leaf01 Desc:Cumulus Linux version 3.7.6 running on Accton AS7712-32X Chassis:Mac:b8:6a:97:74:00:3a Port:Mac:b8:6a:97:74:00:4c\" \e[36mcaller\e[0m=lldpclient.go:72\r\n\e[36mDBUG\e[0m[09-21|12:44:51] lldp \e[36mneigh\e[0m=\"Name:fra-equ01-leaf02 Desc:Cumulus Linux version 3.7.6 running on Accton AS7712-32X Chassis:Mac:b8:6a:97:73:f8:3a Port:Mac:b8:6a:97:73:f8:4c\" \e[36mcaller\e[0m=lldpclient.go:72\r\n" + - delay: 2118 + content: "\e[36mDBUG\e[0m[09-21|12:45:01] lldp \e[36mneigh\e[0m=\"Name:fra-equ01-leaf02 Desc:Cumulus Linux version 3.7.6 running on Accton AS7712-32X Chassis:Mac:b8:6a:97:73:f8:3a" + - delay: 16 + content: " Port:Mac:b8:6a:97:73:f8:4c\" \e[36mcaller\e[0m=lldpclient.go:72\r\n\e[36mDBUG\e[0m[09-21|12:45:01] lldp \e[36mneigh\e[0m=\"Name:fra-equ01-leaf01 Desc:Cumulus Linux version 3" + - delay: 95 + content: ".7.6 running on Accton AS7712-32X Chassis:Mac:b8:6a:97:74:00:3a Port:Mac:b8:6a:97:74:00:4c\" \e[36mcaller\e[0m=lldpclient.go:72\r\n" + - delay: 2837 + content: "\e[32mINFO\e[0m[09-21|12:45:04] wait finished \e[32mstatuscode\e[0m=200 \e[32mresponse\e[0m=\"{\\n \\\"allocation\\\": {\\n \\\"created\\\": \\\"2019-09-21T12:44:59.148Z\\\",\\n \\\"description\\\": \\\"test\\\",\\n \\\"hostname\\\": \\\"test-01\\\",\\n \\\"image\\\": {\\n \\\"changed\\\": \\\"2019-09-19T09:19:16.874Z\\\",\\n \\\"created\\\": \\\"2019-08-26T14:18:51.412Z\\\",\\n \\\"description\\\": \\\"Ubuntu 19.04\\\",\\n \\\"features\\\": [\\n \\\"machine\\\"\\n ],\\n \\\"id\\\": \\\"ubuntu-19.04\\\",\\n \\\"name\\\": \\\"Ubuntu 19.04\\\",\\n \\\"url\\\": \\\"http://192.168.2.1:9000/metal/images/os/ubuntu/19.04/img.tar.lz4\\\"\\n },\\n \\\"name\\\": \\\"test-01\\\",\\n \\\"networks\\\": [\\n {\\n \\\"asn\\\": 4200056321,\\n \\\"destinationprefixes\\\": [],\\n \\\"ips\\\": [\\n \\\"10.0.220.1\\\"\\n ],\\n \\\"nat\\\": false,\\n \\\"networkid\\\": \\\"dc021f35-97dc-45a0-ac63-d3a6f3a5d0b1\\\",\\n \\\"prefixes\\\": [\\n \\\"10.0.220.0/22\\\"\\n ],\\n \\\"private\\\": true,\\n \\\"underlay\\\": false,\\n \\\"vrf\\\": 325\\n }\\n ],\\n \\\"project\\\": \\\"9f105aa8-90a8-410b-9f7b-d" + - delay: 10 + content: >- + a5bb44b47d2\",\n \"ssh_pub_keys\": [\n \"ssh-rsa + AAAAB3NzaC1yc2EAAAADAQABAAACAQCyrvgF8v6Cg8rxC4dbmgRabnXClAzQAnnInGH+kKgTbG31e9sYxOdTUU6dUu6/05DB1pABJ1qf01sjcBkcNjDeV0fZkHrf4Ygi0ftjL03GGTychVNl0bFX + - delay: 17 + content: >- + vMfd6o97G1bT0c3IBHMYjaYXKy2dwcSzKwcEhuwiUZHDVwI30srbCleKiDc1S8R3spvGXu0JhmBhUpd6sz6r5k0z3J8jdzeK7BVccpZhyloMZ9gNFkALrBi/sN4novXrNgPo9FQP1ISOAdycvKoGXh5wAVzWeJpRKaNwHDDg02iHBJ3lcc8f0F5oia9vDy5pdCqy+m9g + - delay: 19 + content: >- + pYVrBp6fZdKaTUsItyDj0rExWvD1w3KISkUZLTbUrJDJqsif7i+z3PC9Eygf/ls3kavwJKDMJSH5KrAivYLKm08+TlifGhKNvoqhPrTrHFFmrSFKG71U6bplL16hfZFsYU8VoJfRMoTC9mb4FCNF2ObxlAWlaA4TS5885osMxCN3yNsLaqbAaVNa3kHORApflU4sk6qx + - delay: 16 + content: >- + GlK/7PduldmhPUxYv7gSyBckJs+9WvDJGWeA14HzIpT267Ii5gT5s00vNO3SO8cWlPTlCcf72ocz1/zVRkOMPIpCvDuOnVLE7GohSRLoGY6bO/60GQ3ABaPIpN4xLo08Uib8BPCRl972xLB+ILzTYj3sIpe0ISzeh0mrhQ== + gerrit.schwerthelm@x-cellent.co + - delay: 19 + content: >- + m\"\n ],\n \"succeeded\": false\n },\n \"changed\": + \"2019-09-21T12:44:59.149Z\",\n \"created\": + \"2019-08-26T14:19:32.808Z\",\n \"events\": {\n + \"incomplete_provisioning_cycles\": \"0\",\n \"last + - delay: 15 + content: >- + _event_time\": \"2019-09-21T12:44:32.812Z\",\n \"log\": [\n {\n + \"event\": \"Waiting\",\n \"message\": \"waiting for + installation\",\n \"time\": \"2019-09-21T07:12:40.601Z\"\n },\n {\n + - delay: 18 + content: ' \"event\": \"Registering\",\n \"message\": \"start registering\",\n \"time\": \"2019-09-21T07:12:34.032Z\"\n },\n {\n \"event\": \"Preparing\",\n \"message\": \"starting metal-hamm' + - delay: 17 + content: >- + er\",\n \"time\": \"2019-09-21T07:12:32.811Z\"\n },\n {\n + \"event\": \"PXE Booting\",\n \"message\": \"machine sent extended dhcp + request\",\n \"time\": \"2019-09-21T07:10:15.262Z\"\n + - delay: 20 + content: ' },\n {\n \"event\": \"PXE Booting\",\n \"message\": \"machine sent extended dhcp request\",\n \"time\": \"2019-09-21T07:09:43.376Z\"\n }\n ]\n },\n \"hardware\": {\n \"cpu_cores\": 16' + - delay: 15 + content: >- + ,\n \"disks\": [\n {\n \"name\": \"nvme0n1\",\n \"size\": + 800166076416\n },\n {\n \"name\": \"nvme1n1\",\n \"size\": + 800166076416\n }\n ],\n \"memory\": 101635428352,\n \"nics\ + - delay: 19 + content: >- + ": [\n {\n \"mac\": \"ac:1f:6b:94:ca:70\",\n \"name\": + \"eth0\"\n },\n {\n \"mac\": \"ac:1f:6b:94:ca:71\",\n \"name\": + \"eth1\"\n },\n {\n \"mac\": \"ac:1f:6b:94:ca:72\",\n + - delay: 18 + content: ' \"name\": \"eth2\"\n },\n {\n \"mac\": \"ac:1f:6b:94:ca:73\",\n \"name\": \"eth3\"\n },\n {\n \"mac\": \"ac:1f:6b:7a:eb:76\",\n \"name\": \"eth4\"\n },\n {\n \"mac\": \"ac:' + - delay: 16 + content: >- + 1f:6b:7a:eb:77\",\n \"name\": \"eth5\"\n },\n {\n \"mac\": + \"00:00:00:00:00:00\",\n \"name\": \"lo\"\n }\n ]\n },\n \"id\": + \"00000000-0000-0000-0000-ac1f6b7aeb76\",\n \"ledstate\": {\ + - delay: 16 + content: >- + n \"description\": \"Machine registered\",\n \"value\": \"LED-OFF\"\n + },\n \"liveliness\": \"Alive\",\n \"partition\": {\n \"bootconfig\": + {\n \"commandline\": \"console=ttyS1,115200n8 ip=dhcp ca + - delay: 19 + content: >- + rrier_timeout=10\",\n \"imageurl\": + \"https://blobstore.fi-ts.io/metal/images/metal-hammer/metal-hammer-initrd.img.lz4\",\n + \"kernelurl\": \"https://blobstore.fi-ts.io/metal/images/metal-hammer/st + - delay: 16 + content: >- + able/metal-hammer-kernel\"\n },\n \"changed\": + \"2019-09-19T09:19:16.934Z\",\n \"created\": + \"2019-08-26T14:18:51.479Z\",\n \"description\": \"Metal Test environment + in Frankfurt Equinix 01\",\n + - delay: 18 + content: >- + \"id\": \"fra-equ01\",\n \"mgmtserviceaddress\": + \"fra-equ01-mgmt-service:2222\",\n \"name\": \"Frankfurt Equinix 01\",\n + \"privatenetworkprefixlength\": 22\n },\n \"rackid\": + \"fra-equ01-rack01\", + - delay: 19 + content: >- + \n \"size\": {\n \"changed\": \"2019-09-19T09:19:17.047Z\",\n + \"constraints\": [\n {\n \"max\": 24,\n \"min\": 16,\n + \"type\": \"cores\"\n },\n {\n \"max\": 120000000000,\n \"mi + - delay: 15 + content: >- + n\": 80000000000,\n \"type\": \"memory\"\n },\n {\n \"max\": + 4000000000000,\n \"min\": 500000000000,\n \"type\": \"storage\"\n + }\n ],\n \"created\": \"2019-08-26T14:18:51.628Z\",\n + - delay: 18 + content: ' \"description\": \"Compute for the very large masses\",\n \"id\": \"c1-xlarge-x86\",\n \"name\": \"c1-xlarge-x86\"\n },\n \"state\": {\n \"description\": \"\",\n \"value\": \"\"\n },\n \"tags\":' + - delay: 17 + content: " [\\n \\\"machine.metal-stack.io/network.primary.asn=4200056321\\\",\\n \\\"machine.metal-stack.io/rack=fra-equ01-rack01\\\",\\n \\\"machine.metal-stack.io/chassis=C217BAH31AG0535\\\"\\n ]\\n}\" \e[32mcaller\e[0m=wait.go:51" + - delay: 18 + content: "\r\n\e[32mINFO\e[0m[09-21|12:45:04] stopped waiting got \e[32mmachine\e[0m=\"{Allocation:0xc00030a2d0 Changed:0xc0003ee630 Created:0xc0003ee640 Description: Events:0xc000576390 Hardware:" + - delay: 17 + content: >- + 0xc0006f4000 ID:0xc0003ee8f0 Ledstate:0xc0003ee900 Liveliness:0xc0003ee930 + Name: Partition:0xc0000c4b40 Rackid:0xc0003ee970 Size:0xc000236320 + State:0xc0003ee9f0 Tags:[machine.metal-stack.io/network.prim + - delay: 18 + content: "ary.asn=4200056321 machine.metal-stack.io/rack=fra-equ01-rack01 machine.metal-stack.io/chassis=C217BAH31AG0535]}\" \e[32mcaller\e[0m=wait.go:58\r\n\e[32mINFO\e[0m[09-21|12:45:04] getdisk " + - delay: 17 + content: " \e[32mimageID\e[0m=ubuntu-19.04 \e[32mcaller\e[0m=disk.go:206\r\n\e[32mINFO\e[0m[09-21|12:45:04] event \e[32mevent\e[0m=0xc0003eebc0 \e[32mmessage\e[0m=\"start installat" + - delay: 16 + content: "ion\" \e[32mcaller\e[0m=event.go:62\r\nPOST /machine/00000000-0000-0000-0000-ac1f6b7aeb76/event HTTP/1.1\r\r\nHost: 10.255.255.4:4242\r\r\nUser-Agent: Go-http-client/1.1\r\r\nContent-Length: 54\r\r\nAccept: applicatio" + - delay: 19 + content: "n/json\r\r\nContent-Type: application/json\r\r\nAccept-Encoding: gzip\r\r\n\r\r\n{\"event\":\"Installing\",\"message\":\"start installation\"}\r\n\r\nHTTP/1.1 200 OK\r\r\nTransfer-Encoding: chunked\r\r\nDate: Sat, 21 Sep 2019 12:4" + - delay: 17 + content: "5:04 GMT\r\r\n\r\r\n0\r\r\n\r\r\n\r\n\e[32mINFO\e[0m[09-21|12:45:04] partition disk \e[32mdisk\e[0m=\"{Device:/dev/nvme0n1 Partitions:[/dev/nvme0n1p1 /dev/nvme0n1p2 /dev/nvme0n1p3]}\" \e[32mcalle" + - delay: 92 + content: "r\e[0m=sgdisk.go:17\r\nCreating new GPT entries.\r\n" + - delay: 870 + content: "GPT data structures destroyed! You may now partition the disk using fdisk or\r\nother utilities.\r\n\e[32mINFO\e[0m[09-21|12:45:05] sgdisk create partitions \e[32mcommand\e[0m=\"[-n=1:0:300M -c=1:efi -t=1:ef00 -u=1:C12A7328-F81F-11D2-BA4B-00A0C93EC93B -n=2:0:5000M -c=2:root -t=2:8300 -n=3:0:0 -c=3:varlib -t=3:8300 /dev/nvme0n1]\" \e[32mcaller\e[0m=sgdisk.go:25\r\nCreating new GPT entries.\r\nSetting name!\r\npartNum is 0\r\nREALLY setting name!\r\nSetting name!\r\npartNum is 1\r\nREALLY setting name!\r\nSetting name!\r\npartNum is 2\r\nREALLY setting name!\r\n" + - delay: 1019 + content: "The operation has completed successfully.\r\n\e[32mINFO\e[0m[09-21|12:45:06] mount \e[32mdisk\e[0m=\"{Device:/dev/nvme0n1 Partitions:[/dev/nvme0n1p1 /dev/nvme0n1p2 /dev/nvme0n1p3]}\" \e[32mcaller\e[0m=mount.go:36\r\n\e[32mINFO\e[0m[09-21|12:45:06] create filesystem \e[32mdevice\e[0m=/dev/nvme0n1p2 \e[32mfilesystem\e[0m=ext4 \e[32mcaller\e[0m=mkfs.go:19\r\nmke2fs 1.43.4 (31-Jan-2017)\r\next2fs_check_if_mount: Can't check if filesystem is mounted due to missing mtab file while determining whether /dev/nvme0n1p2 is mounted.\r\nfs_types for mke2fs.conf resolution: 'ext4'\r\nDiscarding device blocks: 4096/1202944\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b \b\b\b\b\b\b\b\b\b\b\b\b\b\b\bdone \r\nFilesystem label=root\r\nOS type: Linux\r\nBlock size=4096 (log=2)\r\nFragment size=4096 (log=2)\r\nStride=0 blocks, Stripe width=0 blocks\r\n300736 inodes, 1202944 blocks\r\n60147 blocks (5.00%) reserved for the super user\r\nFirst data block=0\r\nMaximum filesystem blocks=1233125376\r\n37 block groups\r\n32768 blocks per group, 32768 fragments per group\r\n8128 inodes per group\r\nFilesystem UUID: 85974557-9beb-4400-a6a9-c1d65f301160\r\nSuperblock backups stored on blocks: \r\n\t32768, 98304, 163840, 229376, 294912, 819200, 884736\r\n\r\nAllocating group tables: 0/37\b\b\b\b\b \b\b\b\b\bdone \r\nWriting inode tables: 0/37\b\b\b\b\b \b\b\b\b\bdone \r\nCreat" + - delay: 54 + content: "ing journal (16384 blocks): done\r\nWriting superblocks and filesystem accounting information: 0/37\b\b\b\b\b \b\b\b\b\b" + - delay: 176 + content: "done\r\n\r\n\e[32mINFO\e[0m[09-21|12:45:06] partition properties \e[32mdevice\e[0m=/dev/nvme0n1p2 \e[32mproperties\e[0m=\"map[DEVNAME:/dev/nvme0n1p2 LABEL:root PARTLABEL:root PARTUUID:9fdb5e9" + - delay: 23 + content: "6-ca2f-4d48-8681[20086.141482] FAT-fs (nvme0n1p1): utf8 is not a recommended IO charset for FAT filesystems, filesystem will be case sensitive!\r\n-de25d948343f TYPE:ext4 UUID:85974557-9beb-4400-a6a9-c1" + - delay: 11 + content: "d65f301160]\" \e[32mcaller\e[0m=mount.go:53\r\n\e[32mINFO\e[0m[09-21|12:45:06] mount \e[32msource\e[0m=/dev/nvme0n1p2 \e[32mtarget\e[0m=/rootfs \e[32mfstype\e[0m=ext4 \e[32mcaller" + - delay: 18 + content: "\e[0m=mount.go:65\r\n\e[32mINFO\e[0m[09-21|12:45:06] create filesystem \e[32mdevice\e[0m=/dev/nvme0n1p1 \e[32mfilesystem\e[0m=vfat \e[32mcaller\e[0m=mkfs.go:19\r\nmkfs.fat 4.1 (2017-01-24)\r\n" + - delay: 16 + content: "/dev/nvme0n1p1 has 64 heads and 32 sectors per track,\r\nhidden sectors 0x0800;\r\nlogical sector size is 512,\r\nusing 0xf8 media descriptor, with 612353 sectors;\r\ndrive number 0x80;\r\nfilesystem has 2 32-b" + - delay: 19 + content: "it FATs and 8 sectors per cluster.\r\nFAT size is 600 sectors, and provides 76390 clusters.\r\nThere are 32 reserved sectors.\r\nVolume ID is b52e82fe, volume label EFI .\r\n\e[32mINFO\e[0m[09-21|12:45:0" + - delay: 16 + content: "6] partition properties \e[32mdevice\e[0m=/dev/nvme0n1p1 \e[32mproperties\e[0m=\"map[DEVNAME:/dev/nvme0n1p1 LABEL:EFI PARTLABEL:efi PARTUUID:c12a7328-f81f-11d2-ba4b-00a0c93ec93b TYPE:vf" + - delay: 20 + content: "at UUID:B52E-82FE]\" \e[32mcaller\e[0m=mount.go:53\r\n\e[32mINFO\e[0m[09-21|12:45:06] mount \e[32msource\e[0m=/dev/nvme0n1p1 \e[32mtarget\e[0m=/rootfs/boot/efi \e[32mfstype\e[0m=" + - delay: 15 + content: "vfat \e[32mcaller\e[0m=mount.go:65\r\n\e[32mINFO\e[0m[09-21|12:45:06] create filesystem \e[32mdevice\e[0m=/dev/nvme0n1p3 \e[32mfilesystem\e[0m=ext4 \e[32mcaller\e[0m=mkfs.go:19\r\nmke2fs 1.43" + - delay: 18 + content: ".4 (31-Jan-2017)\r\next2fs_check_if_mount: Can't check if filesystem is mounted due to missing mtab file while determining whether /dev/nvme0n1p3 is mounted.\r\nfs_types for mke2fs.conf resolution: 'ext4'" + - delay: 31 + content: "\r\nDiscarding device blocks: 4096/194072785\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b 19402752/194072785\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b \b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\bdone \r\nFilesystem label=varlib\r" + - delay: 17 + content: "\nOS type: Linux\r\nBlock size=4096 (log=2)\r\nFragment size=4096 (log=2)\r\nStride=0 blocks, Stripe width=0 blocks\r\n48521216 inodes, 194072785 blocks\r\n9703639 blocks (5.00%) reserved for the super user\r\nFir" + - delay: 17 + content: "st data block=0\r\nMaximum filesystem blocks=2342518784\r\n5923 block groups\r\n32768 blocks per group, 32768 fragments per group\r\n8192 inodes per group\r\nFilesystem UUID: 13c046bd-1077-4c64-b006-7efe6e1ea66" + - delay: 18 + content: "2\r\nSuperblock backups stored on blocks: \r\n\t32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208, \r\n\t4096000, 7962624, 11239424, 20480000, 23887872, 71663616, 78675968, \r\n\t102400000\r\n" + - delay: 17 + content: "\r\nAllocating group tables: 0/5923\b\b\b\b\b\b\b\b\b \b\b\b\b\b\b\b\b\bdone \r\nWriting inode tables: 0/5923\b\b\b\b\b\b\b\b\b \b\b\b\b\b\b\b\b\bdone \r\nCreating jo" + - delay: 95 + content: 'urnal (262144 blocks): ' + - delay: 837 + content: "done\r\nWriting superblocks and filesystem accounting information: 0/5923\b\b\b\b\b\b\b\b\b \b\b\b\b\b\b\b\b\b" + - delay: 3482 + content: "\e[36mDBUG\e[0m[09-21|12:45:11] lldp \e[36mneigh\e[0m=\"Name:fra-equ01-leaf02 Desc:Cumulus Linux version 3.7.6 running on Accton AS7712-32X Chassis:Mac:b8:6a:97:73:f8:3a Port:Mac:b8:6a:97:73:f8:4c\" \e[36mcaller\e[0m=lldpclient.go:72\r\n\e[36mDBUG\e[0m[09-21|12:45:11] lldp \e[36mneigh\e[0m=\"Name:fra-equ01-leaf01 Desc:Cumulus Linux version 3" + - delay: 28 + content: ".7.6 running on Accton AS7712-32X Chassis:Mac:b8:6a:97:74:00:3a Port:Mac:b8:6a:97:74:00:4c\" \e[36mcaller\e[0m=lldpclient.go:72\r\n" + - delay: 1610 + content: "done\r\n\r\n\e[32mINFO\e[0m[09-21|12:45:13] partition properties \e[32mdevice\e[0m=/dev/nvme0n1p3 \e[32mproperties\e[0m=\"map[DEVNAME:/dev/nvme0n1p3 LABEL:varlib PARTLABEL:varlib PARTUUID:3a483688-a43a-40bc-808d-f2f86ca6d9ec TYPE:ext4 UUID:13c046bd-1077-4c64-b006-7efe6e1ea662]\" \e[32mcaller\e[0m=mount.go:53\r\n\e[32mINFO\e[0m[09-21|12:45:13] mount \e[32msource\e" + - delay: 12 + content: "[0m=/dev/nvme0n1p3 \e[32mtarget\e[0m=/rootfs/var/lib \e[32mfstype\e[0m=ext4 \e[32mcaller\e[0m=mount.go:65\r\n\e[32mINFO\e[0m[09-21|12:45:13] pull image \e[32mimage\e[0m=http://192.16" + - delay: 19 + content: "8.2.1:9000/metal/images/os/ubuntu/19.04/img.tar.lz4 \e[32mcaller\e[0m=image.go:22\r\n\e[32mINFO\e[0m[09-21|12:45:13] download \e[32mfrom\e[0m=http://192.168.2.1:9000/metal/imag" + - delay: 97 + content: "es/os/ubuntu/19.04/img.tar.lz4 \e[32mto\e[0m=/tmp/os.tgz \e[32mcaller\e[0m=image.go:130\r\n\r 0 B / 522.29 MiB [----------------------------------------------------] 0.00%" + - delay: 100 + content: "\r 15.24 MiB / 522.29 MiB [>--------------------------] 2.92% 76.07 MiB/s 00m06s" + - delay: 279 + content: "\r 30.88 MiB / 522.29 MiB [=>-------------------------] 5.91% 77.10 MiB/s 00m06s" + - delay: 123 + content: "\r 46.48 MiB / 522.29 MiB [==>------------------------] 8.90% 77.37 MiB/s 00m05s" + - delay: 197 + content: "\r 62.11 MiB / 522.29 MiB [===>-----------------------] 11.89% 77.55 MiB/s 00m05s" + - delay: 296 + content: "\r 77.87 MiB / 522.29 MiB [====>----------------------] 14.91% 77.78 MiB/s 00m05s" + - delay: 204 + content: "\r 93.56 MiB / 522.29 MiB [====>----------------------] 17.91% 77.89 MiB/s 00m05s" + - delay: 101 + content: "\r 109.13 MiB / 522.29 MiB [=====>--------------------] 20.89% 77.87 MiB/s 00m05s" + - delay: 308 + content: "\r 124.52 MiB / 522.29 MiB [======>-------------------] 23.84% 77.74 MiB/s 00m05s" + - delay: 92 + content: "\r 139.84 MiB / 522.29 MiB [======>-------------------] 26.77% 77.61 MiB/s 00m04s" + - delay: 215 + content: "\r 155.11 MiB / 522.29 MiB [=======>------------------] 29.70% 77.48 MiB/s 00m04s" + - delay: 206 + content: "\r 170.42 MiB / 522.29 MiB [========>-----------------] 32.63% 77.39 MiB/s 00m04s" + - delay: 179 + content: "\r 185.74 MiB / 522.29 MiB [=========>----------------] 35.56% 77.32 MiB/s 00m04s" + - delay: 232 + content: "\r 201.08 MiB / 522.29 MiB [==========>---------------] 38.50% 77.26 MiB/s 00m04s" + - delay: 202 + content: "\r 216.37 MiB / 522.29 MiB [==========>---------------] 41.43% 77.20 MiB/s 00m03s" + - delay: 205 + content: "\r 231.57 MiB / 522.29 MiB [===========>--------------] 44.34% 77.12 MiB/s 00m03s" + - delay: 182 + content: "\r 246.51 MiB / 522.29 MiB [============>-------------] 47.20% 76.96 MiB/s 00m03s" + - delay: 228 + content: "\r 261.72 MiB / 522.29 MiB [=============>------------] 50.11% 76.91 MiB/s 00m03s" + - delay: 203 + content: "\r 277.00 MiB / 522.29 MiB [=============>------------] 53.03% 76.87 MiB/s 00m03s" + - delay: 205 + content: "\r 292.31 MiB / 522.29 MiB [==============>-----------] 55.97% 76.85 MiB/s 00m02s" + - delay: 204 + content: "\r 307.70 MiB / 522.29 MiB [===============>----------] 58.91% 76.85 MiB/s 00m02s" + - delay: 205 + content: "\r 322.90 MiB / 522.29 MiB [================>---------] 61.82% 76.81 MiB/s 00m02s" + - delay: 204 + content: "\r 338.02 MiB / 522.29 MiB [================>---------] 64.72% 76.75 MiB/s 00m02s" + - delay: 205 + content: "\r 353.37 MiB / 522.29 MiB [=================>--------] 67.66% 76.75 MiB/s 00m02s" + - delay: 206 + content: "\r 368.64 MiB / 522.29 MiB [==================>-------] 70.58% 76.73 MiB/s 00m01s" + - delay: 205 + content: "\r 383.87 MiB / 522.29 MiB [===================>------] 73.50% 76.70 MiB/s 00m01s" + - delay: 204 + content: "\r 399.00 MiB / 522.29 MiB [===================>------] 76.39% 76.66 MiB/s 00m01s" + - delay: 205 + content: "\r 414.02 MiB / 522.29 MiB [====================>-----] 79.27% 76.60 MiB/s 00m01s" + - delay: 205 + content: "\r 429.26 MiB / 522.29 MiB [=====================>----] 82.19% 76.58 MiB/s 00m01s" + - delay: 98 + content: "\r 444.36 MiB / 522.29 MiB [============================>----] 85.08% 76.54 MiB/s" + - delay: 209 + content: "\r 459.62 MiB / 522.29 MiB [=============================>---] 88.00% 76.53 MiB/s" + - delay: 191 + content: "\r 474.79 MiB / 522.29 MiB [=============================>---] 90.91% 76.51 MiB/s" + - delay: 218 + content: "\r 490.05 MiB / 522.29 MiB [==============================>--] 93.83% 76.50 MiB/s" + - delay: 206 + content: "\r 505.38 MiB / 522.29 MiB [===============================>-] 96.76% 76.50 MiB/s" + - delay: 205 + content: "\r 520.45 MiB / 522.29 MiB [=================================] 99.65% 76.47 MiB/s\r 522.29 MiB / 522.29 MiB [==============================] 100.00% 76.45 MiB/s 6s\r\n\e[32mINFO\e[0m[09-21|12:45:20] download \e[32mfrom\e[0m=http://192.168.2.1:9000/metal/images/os/ubuntu/19.04/img.tar.lz4.md5 \e[32mto\e[0m=/tmp/os" + - delay: 6 + content: ".tgz.md5 \e[32mcaller\e[0m=image.go:130\r\n\r 0 B / 46 B [----------------------------------------------------------] 0.00%\r 46 B / 46 B [=========================================] 100.00% 530.92 KiB/s 0" + - delay: 96 + content: "s\r\n\e[32mINFO\e[0m[09-21|12:45:20] check md5 \e[32mcaller\e[0m=image.go:34\r\n" + - delay: 1330 + content: "\e[32mINFO\e[0m[09-21|12:45:21] check md5 \e[32msource md5\e[0m=96e5a043733c9abcc898db00bc5d260f \e[32mexpected md5\e[0m=96e5a043733c9abcc898db00bc5d260f \e[32mcaller\e[0m=image.go:119\r\n\e[32mINFO\e[0m[09-21|12:45:21] pull image done \e[32mimage\e[0m=http://192.168.2.1:9000/metal/images/os/ubuntu/19.04/img.tar.lz4 \e[32mcaller\e[0m=image.go:40\r\n\e[32mINFO\e[0m[09-21|12:45:21] burn image \e[32mimage\e[0m=http://192.168.2.1:9000/metal/images/os/ubuntu/19.04/img.tar.lz4 \e[32mcaller\e[0m=image.go:46\r\n\e[32mINFO\e[0m[09-21|12:45:21] l" + - delay: 65 + content: "z4 \e[32msize\e[0m=0 \e[32mcaller\e[0m=image.go:66\r\n\r 0 B / 1.02 GiB 0.00%" + - delay: 102 + content: "\r 72.00 MiB / 1.02 GiB [=>--------------------------] 6.89% 359.29 MiB/s 00m02s" + - delay: 57 + content: "\e[36mDBUG\e[0m[09-21|12:45:21] lldp \e[36mneigh\e[0m=\"Name:fra-equ01-leaf02 Desc:Cumulus Linux version 3.7.6 running on Accton AS7712-32X Chassis:Mac:b8:6a:97:73:f8:3a" + - delay: 17 + content: " Port:Mac:b8:6a:97:73:f8:4c\" \e[36mcaller\e[0m=lldpclient.go:72\r\n\e[36mDBUG\e[0m[09-21|12:45:21] lldp \e[36mneigh\e[0m=\"Name:fra-equ01-leaf01 Desc:Cumulus Linux version 3" + - delay: 86 + content: ".7.6 running on Accton AS7712-32X Chassis:Mac:b8:6a:97:74:00:3a Port:Mac:b8:6a:97:74:00:4c\" \e[36mcaller\e[0m=lldpclient.go:72\r\n\r 128.00 MiB / 1.02 GiB [===>-----------------------] 12.25% 319.50 MiB/s" + - delay: 99 + content: ' 00m01s' + - delay: 186 + content: "\r 184.00 MiB / 1.02 GiB [====>----------------------] 17.61% 306.21 MiB" + - delay: 14 + content: /s 00m02s + - delay: 101 + content: "\r 248.00 MiB / 1.02 GiB [======>--------------------] 23.74% 30" + - delay: 98 + content: 9.58 MiB/s 00m02s + - delay: 100 + content: "\r 305.75 MiB / 1.02 GiB [=======>-------------------] 29.27% 30" + - delay: 102 + content: 5.35 MiB/s 00m02s + - delay: 99 + content: "\r 359.66 MiB / 1.02 GiB [=========>-----------------] 3" + - delay: 100 + content: 4.43% 299.34 MiB/s 00m02s + - delay: 101 + content: "\r 401.08 MiB / 1.02 GiB [==========>----------------] 3" + - delay: 98 + content: 8.40% 286.13 MiB/s 00m02s + - delay: 101 + content: "\r 444.00 MiB / 1.02 GiB [===========>---------------] 4" + - delay: 100 + content: 2.50% 277.14 MiB/s 00m01s + - delay: 214 + content: "\r 488.00 MiB / 1.02 GiB [============>--------------] 46.72% 270.76 MiB/s 00m01s" + - delay: 85 + content: "\r 540.00 MiB / 1.02 GiB [=============>---------" + - delay: 100 + content: '----] 51.70% 269.65 MiB/s 00m01s' + - delay: 100 + content: "\r 588.00 MiB / 1.02 GiB [===============>-------" + - delay: 100 + content: '----] 56.29% 266.92 MiB/s 00m01s' + - delay: 101 + content: "\r 632.00 MiB / 1.02 GiB [===============" + - delay: 99 + content: '=>----------] 60.50% 262.99 MiB/s 00m01s' + - delay: 100 + content: "\r 672.00 MiB / 1.02 GiB [=======" + - delay: 100 + content: '==========>---------] 64.33% 258.12 MiB/s 00m01s' + - delay: 100 + content: "\r 716.00 MiB / 1.02 GiB [=======" + - delay: 101 + content: '===========>--------] 68.54% 255.38 MiB/s 00m01s' + - delay: 100 + content: "\r 760.00 MiB / 1.02 GiB [=======" + - delay: 144 + content: '=================>---------] 72.76% 253.00 MiB/s' + - delay: 57 + content: "\r 806.48 MiB / 1.02 GiB [=======" + - delay: 100 + content: '===================>-------] 77.21% 251.69 MiB/s' + - delay: 100 + content: "\r 849.04 MiB / 1.02 GiB [=======" + - delay: 100 + content: '====================>------] 81.28% 249.39 MiB/s' + - delay: 99 + content: "\r 880.54 MiB / 1.02 GiB " + - delay: 100 + content: '[============================>-----] 84.30% 244.27 MiB/s' + - delay: 100 + content: "\r 929.31 MiB / 1" + - delay: 100 + content: '.02 GiB [==============================>---] 88.96% 244.24 MiB/s' + - delay: 100 + content: "\r 978.14 MiB / 1" + - delay: 100 + content: '.02 GiB [===============================>--] 93.64% 244.21 MiB/s' + - delay: 100 + content: "\r 1.00 GiB / 1.0" + - delay: 101 + content: '2 GiB [====================================] 98.03% 243.49 MiB/s' + - delay: 100 + content: "\r 1.06 GiB / 1.0" + - delay: 100 + content: '2 GiB [====================================] 103.77% 246.04 MiB/s' + - delay: 99 + content: "\r 1.11 G" + - delay: 101 + content: 'iB / 1.02 GiB [====================================] 108.77% 246.67 MiB/s' + - delay: 99 + content: "\r 1.13 G" + - delay: 100 + content: 'iB / 1.02 GiB [====================================] 111.23% 241.74 MiB/s' + - delay: 292 + content: "\r 1.16 GiB / 1.02 GiB [====================================] 113.73% 237.29 MiB/s\r 1.19 GiB / 1.02 GiB [=================================] 116.32% 234.31 MiB/s 5s\r\n\e[32mINFO\e[0m[09-21|12:45:26] burn took \e[32mduration\e[0m=5.185945648s \e[32mcaller\e[0m" + - delay: 66 + content: "=image.go:93\r\n\e[32mINFO\e[0m[09-21|12:45:26] mount \e[32msource\e[0m=proc \e[32mtarget\e[0m=/rootfs/proc \e[32mfstype\e[0m=proc \e[32mflags\e[0m=0 \e[32mdata\e[0m= \e[32mcaller\e" + - delay: 19 + content: "[0m=mount.go:98\r\n\e[32mINFO\e[0m[09-21|12:45:26] mount \e[32msource\e[0m=sys \e[32mtarget\e[0m=/rootfs/sys \e[32mfstype\e[0m=sysfs \e[32mflags\e[0m=0 \e[32mdata\e[0m= \e[32mcalle" + - delay: 18 + content: "r\e[0m=mount.go:98\r\n\e[32mINFO\e[0m[09-21|12:45:26] mount \e[32msource\e[0m=efivarfs \e[32mtarget\e[0m=/rootfs/sys/firmware/efi/efivars \e[32mfstype\e[0m=efivarfs \e[32mflags\e" + - delay: 28 + content: "[0m=0 \e[32mdata\e[0m= \e[32mcaller\e[0m=mount.go:98\r\n\e[32mINFO\e[0m[09-21|12:45:26] mount \e[32msource\e[0m=tmpfs \e[32mtarget\e[0m=/rootfs/tmp \e[32mfstype\e[0m=tmpfs \e[32mfl" + - delay: 17 + content: "ags\e[0m=0 \e[32mdata\e[0m= \e[32mcaller\e[0m=mount.go:98\r\n\e[32mINFO\e[0m[09-21|12:45:26] mount \e[32msource\e[0m=/dev \e[32mtarget\e[0m=/rootfs/dev \e[32mfstype\e[0m= \e[32mflag" + - delay: 18 + content: "s\e[0m=4096 \e[32mdata\e[0m= \e[32mcaller\e[0m=mount.go:98\r\n\e[32mINFO\e[0m[09-21|12:45:26] install \e[32mimage\e[0m=http://192.168.2.1:9000/metal/images/os/ubuntu/19.04/img.ta" + - delay: 25 + content: "r.lz4 \e[32mcaller\e[0m=install.go:94\r\n\e[32mINFO\e[0m[09-21|12:45:26] write installation configuration \e[32mcaller\e[0m=install.go:202\r\n\e[32mINFO\e[0m[09-21|12:45:26] running /install.sh on " + - delay: 9 + content: " \e[32mprefix\e[0m=/rootfs \e[32mcaller\e[0m=install.go:111\r\nUUID=\"85974557-9beb-4400-a6a9-c1d65f301160\" / ext4 defaults 0 1\r\nUUID=\"13c046bd-1077-4c64-b006-7efe6e1ea662\" /var/lib ext4 defaults 0" + - delay: 17 + content: " 1\r\nUUID=\"B52E-82FE\" /boot/efi vfat defaults 0 2\r\ntmpfs /tmp tmpfs defaults,noatime,nosuid,nodev,noexec,mode=1777,size=512M 0 0\r\ncreating user 'metal'\r\nset password for metal to 8VhHQ2asGpyVHHGQ expir" + - delay: 18 + content: "es after 1 day.\r\nNew password: Retype new password: passwd: password updated successfully\r\n{\"level\":\"info\",\"time\":\"2019-09-21T14:45:26.875+0200\",\"caller\":\"cmd/root.go:73\",\"message\":\"running app versio" + - delay: 17 + content: "n: devel (efeb2092), tags/stable-0-gefeb209, 2019-09-18T13:58:16Z\"}\r\n{\"level\":\"info\",\"time\":\"2019-09-21T14:45:26.875+0200\",\"caller\":\"netconf/knowledgebase.go:76\",\"message\":\"loading: /etc/metal/install" + - delay: 18 + content: ".yaml\"}\r\n{\"level\":\"info\",\"time\":\"2019-09-21T14:45:26.875+0200\",\"caller\":\"netconf/configurator.go:139\",\"message\":\"rendering interfaces.machine.tpl to /etc/network/interfaces (mode: %!u(os.FileMode=384)" + - delay: 17 + content: "i)\"}\r\n{\"level\":\"info\",\"time\":\"2019-09-21T14:45:26.876+0200\",\"caller\":\"netconf/interfaces.go:82\",\"message\":\"running 'ifup --syntax-check --all --interfaces /etc/metal/networker/interfaces_333931137 to " + - delay: 97 + content: "validate changes.'\"}\r\n" + - delay: 225 + content: "{\"level\":\"info\",\"time\":\"2019-09-21T14:45:27.250+0200\",\"caller\":\"netconf/configurator.go:139\",\"message\":\"rendering hosts.tpl to /etc/hosts (mode: %!u(os.FileMode=384)i)\"}\r\n{\"level\":\"info\",\"time\":\"2019-09-21T14:45:27.251+0200\",\"caller\":\"netconf/configurator.go:139\",\"message\":\"rendering hostname.tpl to /etc/hostname (mode: %!u(os.FileMode=420)i)\"}\r\n{\"level\":\"info\",\"time\":\"2019-09-21T14:45:27.251+0200\",\"caller\":\"netconf/configurator.go:139\",\"message\":\"rendering frr.machine.tpl to /etc/frr/frr.conf (mode: %!u(os.FileMode=384)i)\"}\r\n{\"level\":\"info\",\"time\":\"2019-09-21T14:45:27.251+0200\",\"caller\":\"netc" + - delay: 53 + content: "onf/frr.go:87\",\"message\":\"running 'vtysh --dryrun --inputfile /etc/metal/networker/frr_236382206' to validate changes.'\"}\r\n{\"level\":\"info\",\"time\":\"2019-09-21T14:45:27.354+0200\",\"caller\":\"netconf/confi" + - delay: 18 + content: "gurator.go:139\",\"message\":\"rendering systemd.link.tpl to /etc/systemd/network/10-lan0.link (mode: %!u(os.FileMode=420)i)\"}\r\n{\"level\":\"info\",\"time\":\"2019-09-21T14:45:27.354+0200\",\"caller\":\"netconf/syst" + - delay: 17 + content: "emd.go:80\",\"message\":\"Skipping validation since there is no known way to validate (.network|.link) files in advance.\"}\r\n{\"level\":\"info\",\"time\":\"2019-09-21T14:45:27.354+0200\",\"caller\":\"netconf/configur" + - delay: 17 + content: "ator.go:139\",\"message\":\"rendering systemd.network.tpl to /etc/systemd/network/10-lan0.network (mode: %!u(os.FileMode=420)i)\"}\r\n{\"level\":\"info\",\"time\":\"2019-09-21T14:45:27.354+0200\",\"caller\":\"netconf/s" + - delay: 17 + content: "ystemd.go:80\",\"message\":\"Skipping validation since there is no known way to validate (.network|.link) files in advance.\"}\r\n{\"level\":\"info\",\"time\":\"2019-09-21T14:45:27.354+0200\",\"caller\":\"netconf/confi" + - delay: 19 + content: "gurator.go:139\",\"message\":\"rendering systemd.link.tpl to /etc/systemd/network/20-lan1.link (mode: %!u(os.FileMode=420)i)\"}\r\n{\"level\":\"info\",\"time\":\"2019-09-21T14:45:27.354+0200\",\"caller\":\"netconf/syst" + - delay: 16 + content: "emd.go:80\",\"message\":\"Skipping validation since there is no known way to validate (.network|.link) files in advance.\"}\r\n{\"level\":\"info\",\"time\":\"2019-09-21T14:45:27.354+0200\",\"caller\":\"netconf/configur" + - delay: 18 + content: "ator.go:139\",\"message\":\"rendering systemd.network.tpl to /etc/systemd/network/20-lan1.network (mode: %!u(os.FileMode=420)i)\"}\r\n{\"level\":\"info\",\"time\":\"2019-09-21T14:45:27.354+0200\",\"caller\":\"netconf/s" + - delay: 17 + content: "ystemd.go:80\",\"message\":\"Skipping validation since there is no known way to validate (.network|.link) files in advance.\"}\r\n{\"level\":\"info\",\"time\":\"2019-09-21T14:45:27.354+0200\",\"caller\":\"cmd/root.go:8" + - delay: 99 + content: "5\",\"message\":\"completed. Exiting..\"}\r\nSystem was booted with UEFI\r\nInstalling for x86_64-efi platform.\r\n" + - delay: 1547 + content: "Installation finished. No error reported.\r\n" + - delay: 206 + content: "Sourcing file `/etc/default/grub'\r\nSourcing file `/etc/default/grub.d/init-select.cfg'\r\nGenerating grub configuration file ...\r\nFound linux image: /boot" + - delay: 48 + content: "/vmlinuz-5.0.0-29-generic\r\nFound initrd image: /boot/initrd.img-5.0.0-29-generic\r\n" + - delay: 298 + content: "Adding boot menu entry for EFI firmware configuration\r\ndone\r\n" + - delay: 83 + content: "no userdata present\r\nwrite boot-info.yaml\r\n\e[32mINFO\e[0m[09-21|12:45:29] finish running /install.sh \e[32mcaller\e[0m=install.go:135\r\n\e[32mINFO\e[0m[09-21|12:45:29] unmounting " + - delay: 17 + content: " \e[32mmountpoint\e[0m=/rootfs/dev \e[32mcaller\e[0m=mount.go:113\r\n\e[32mINFO\e[0m[09-21|12:45:29] unmounting \e[32mmountpoint\e[0m=/rootfs/tmp \e[32mcaller\e[0m=mo" + - delay: 19 + content: "unt.go:113\r\n\e[32mINFO\e[0m[09-21|12:45:29] unmounting \e[32mmountpoint\e[0m=/rootfs/sys/firmware/efi/efivars \e[32mcaller\e[0m=mount.go:113\r\n\e[32mINFO\e[0m[09-21|12:45:29] unmo" + - delay: 16 + content: "unting \e[32mmountpoint\e[0m=/rootfs/sys \e[32mcaller\e[0m=mount.go:113\r\n\e[32mINFO\e[0m[09-21|12:45:29] unmounting \e[32mmountpoint\e[0m=/rootfs/pr" + - delay: 18 + content: "oc \e[32mcaller\e[0m=mount.go:113\r\n\e[32mINFO\e[0m[09-21|12:45:29] unmounting \e[32mmountpoint\e[0m=/rootfs/var/lib \e[32mcaller\e[0m=mount.go:113\r\n\e[32mINFO\e[0m[09-21|12:45:29] " + - delay: 16 + content: "unmounting \e[32mmountpoint\e[0m=/rootfs/boot/efi \e[32mcaller\e[0m=mount.go:113\r\n\e[32mINFO\e[0m[09-21|12:45:29] unmounting \e[32mmountpoint\e[0m=/" + - delay: 101 + content: "rootfs \e[32mcaller\e[0m=mount.go:113\r\n" + - delay: 202 + content: "POST /machine/report/00000000-0000-0000-0000-ac1f6b7aeb76 HTTP/1.1\r\r\nHost: 10.255.255.4:4242\r\r\nUser-Agent: Go-http-client/1.1\r\r\nContent-Length: 70\r\r\nAccept: application/json\r\r\nContent-Type: applicatio" + - delay: 46 + content: "n/json\r\r\nAccept-Encoding: gzip\r\r\n\r\r\n{\"console_password\":\"8VhHQ2asGpyVHHGQ\",\"message\":null,\"success\":true}\r\n\r\n" + - delay: 187 + content: "HTTP/1.1 200 OK\r\r\nTransfer-Encoding: chunked\r\r\nDate: Sat, 21 Sep 2019 12:45:30 GMT\r\r\n\r\r\n0\r\r\n\r\r\n\r\n\e[32mINFO\e[0m[09-21|12:45:30] report image installation was successful \e[32mresponse\e[0m=\"&{Allocation:" + - delay: 23 + content: " Changed: Created: Description: Events: Hardware: ID: Ledstate: Liveliness: Name: Partition: Rackid: Size: State: Tags:[]}\" \e[32mcaller\e[0m=" + - delay: 13 + content: "report.go:38\r\n\e[32mINFO\e[0m[09-21|12:45:30] installation \e[32mtook\e[0m=25.838962393s \e[32mcaller\e[0m=root.go:221\r\n\e[32mINFO\e[0m[09-21|12:45:30] event " + - delay: 12 + content: " \e[32mevent\e[0m=0xc000033370 \e[32mmessage\e[0m=\"booting into distro kernel\" \e[32mcaller\e[0m=event.go:62\r\nPOST /machine/00000000-0000-0000-0000-ac1f6b7aeb76/event HTTP/1.1\r\r\nHost: 10.255.255" + - delay: 17 + content: ".4:4242\r\r\nUser-Agent: Go-http-client/1.1\r\r\nContent-Length: 70\r\r\nAccept: application/json\r\r\nContent-Type: application/json\r\r\nAccept-Encoding: gzip\r\r\n\r\r\n{\"event\":\"Booting New Kernel\",\"message\":\"booting " + - delay: 99 + content: "into distro kernel\"}\r\n\r\nHTTP/1.1 200 OK\r\r\nTransfer-Encoding: chunked\r\r\nDate: Sat, 21 Sep 2019 12:45:30 GMT\r\r\n\r\r\n0\r\r\n\r\r\n\r\n" + - delay: 1467 + content: "\e[36mDBUG\e[0m[09-21|12:45:32] lldp \e[36mneigh\e[0m=\"Name:fra-equ01-leaf01 Desc:Cumulus Linux version 3.7.6 running on Accton AS7712-32X Chassis:Mac:b8:6a:97:74:00:3a" + - delay: 19 + content: " Port:Mac:b8:6a:97:74:00:4c\" \e[36mcaller\e[0m=lldpclient.go:72\r\n\e[36mDBUG\e[0m[09-21|12:45:32] lldp \e[36mneigh\e[0m=\"Name:fra-equ01-leaf02 Desc:Cumulus Linux version 3" + - delay: 96 + content: ".7.6 running on Accton AS7712-32X Chassis:Mac:b8:6a:97:73:f8:3a Port:Mac:b8:6a:97:73:f8:4c\" \e[36mcaller\e[0m=lldpclient.go:72\r\n" + - delay: 685 + content: "\e[32mINFO\e[0m[09-21|12:45:32] event \e[32mevent\e[0m=0xc000033630 \e[32mmessage\e[0m=\"still alive at: 2019-09-21 12:45:32.805114624 +0000 UTC m=+19980.030240052\" \e[32mca" + - delay: 6 + content: "ller\e[0m=event.go:62\r\nPOST /machine/00000000-0000-0000-0000-ac1f6b7aeb76/event HTTP/1.1\r\r\nHost: 10.255.255.4:4242\r\r\nUser-Agent: Go-http-client/1.1\r\r\nContent-Length: 105\r\r\nAccept: application/json\r\r\nCo" + - delay: 97 + content: "ntent-Type: application/json\r\r\nAccept-Encoding: gzip\r\r\n\r\r\n{\"event\":\"Alive\",\"message\":\"still alive at: 2019-09-21 12:45:32.805114624 +0000 UTC m=+19980.030240052\"}\r\n\r\n" + - delay: 717 + content: "[20112.792054] kexec_core: Starting new kernel\r\n" + - delay: 1637 + content: "[ 0.000000] microcode: microcode updated early to revision 0x200005e, date = 2019-04-02\r\n[ 0.000000] Linux version 5.0.0-29-generic (buildd@lcy01-amd64-030) (gcc version 8.3.0 (Ubuntu 8.3.0-6ubuntu1)) #31-Ubuntu SMP Thu Sep 12 13:05:32 UTC 2019 (Ubuntu 5.0.0-29.31-generic 5.0.21)\r\n[ 0.000000] Command line: console=ttyS1,115200n8 root=UUID=85974557-9beb-4400-a6a9-c1d65f301160 init=/bin/sys" + - delay: 18 + content: "temd net.ifnames=0 biosdevname=0 acpi_rsdp=0x5ed9f000\r\n[ 0.000000] KERNEL supported cpus:\r\n[ 0.000000] Intel GenuineIntel\r\n[ 0.000000] AMD AuthenticAMD\r\n[ 0.000000] Hygon HygonGenuin" + - delay: 18 + content: "e\r\n[ 0.000000] Centaur CentaurHauls\r\n[ 0.000000] x86/fpu: Supporting XSAVE feature 0x001: 'x87 floating point registers'\r\n[ 0.000000] x86/fpu: Supporting XSAVE feature 0x002: 'SSE registers" + - delay: 148 + content: "'\r\n[ 0.000000] x86/fpu: Supporting XSAVE feature 0x004: 'AVX registers'\r\n[ 0.000000] x86/fpu: Supporting XSAVE feature 0x008: 'MPX bounds registers'\r\n[ 0.000000] x86/fpu: Supporting XSAVE feature 0x010: 'MPX CSR'\r\n[ 0.000000] x86/fpu: Supporting XSAVE feature 0x020: 'AVX-512 opmask'\r\n[ 0.000000] x86/fpu: Supporting XSAVE feature 0x040: 'AVX-512 Hi256'\r\n[ 0.000000] x86/fpu: Supporting XSAVE feature 0x080: 'AVX-512 ZMM_Hi256'\r\n[ 0.000000] x86/fpu: Supporting XSAVE feature 0x200: 'Protection Keys User registers'\r\n[ 0.000000] x86/fpu: xstate_offset[2]: 576, xstate_sizes[2]: 256\r\n[ 0.000000] x86/fpu: xstate_offset[3]: 832, xstate_sizes[3]: 64\r\n[ 0.000000] x86/fpu: xstate_offset[4]: 896, xstate_sizes[4]: 64\r\n[ 0.000000] x86/fpu: xstate_offset[5]: 960, xstate_sizes[5]: 64\r\n[ 0.000000] x86/fpu: xstate_offset[6]: 1024, xstate_sizes[6]: 512\r\n[ 0.000000] x86/fpu: xstate_offset[7]: 1536, xstate_sizes[7]: 1024\r\n[ 0.000000] x86/fpu: xstate_offset[9]: 2560, xstate_sizes[9]: 8\r\n[ 0.000000] x86/fpu: Enabled xstate features 0x2ff, context size is 2568 bytes, using 'compacted' format.\r\n[ 0.000000] BIOS-provided physical RAM map:\r\n[ 0.000000] BIOS-e820: [mem 0x0000000000000000-0x000000000009ffff] usable\r\n[ 0.000000] BIOS-e820: [mem 0x00000000000a0000-0x00000000000fffff] reserved\r\n[ 0.000000] BIOS-e820: [mem 0x0000000000100000-0x000000005ac24017] usable\r\n[ 0.000000] BIOS-e820: [mem 0x000000005ac24018-0x000000005ac2a057] usable\r\n[ 0.000000] BIOS-e820: [mem 0x000000005ac2a058-0x000000005ac2b017] usable\r\n[ 0.000000] BIOS-e820: [mem 0x000000005ac2b018-0x000000005ac31057] usable\r\n[ 0.000000] BIOS-e820: [mem 0x000000005ac31058-0x000000005ac32017] usable\r\n[ 0.000000] BIOS-e820: [mem 0x000000005ac32018-0x00000000" + - delay: 19 + content: "5ac41057] usable\r\n[ 0.000000] BIOS-e820: [mem 0x000000005ac41058-0x000000005ac42017] usable\r\n[ 0.000000] BIOS-e820: [mem 0x000000005ac42018-0x000000005ac51057] usable\r\n[ 0.000000] BIOS-e820: " + - delay: 122 + content: "[mem 0x000000005ac51058-0x000000005ac52017] usable\r\n[ 0.000000] BIOS-e820: [mem 0x000000005ac52018-0x000000005ac61057] usable\r\n[ 0.000000] BIOS-e820: [mem 0x000000005ac61058-0x000000005ac62017] usable\r\n[ 0.000000] BIOS-e820: [mem 0x000000005ac62018-0x000000005ac71057] usable\r\n[ 0.000000] BIOS-e820: [mem 0x000000005ac71058-0x000000005ac72017] usable\r\n[ 0.000000] BIOS-e820: [mem 0x000000005ac72018-0x000000005aca6257] usable\r\n[ 0.000000] BIOS-e820: [mem 0x000000005aca6258-0x000000005aca7017] usable\r\n[ 0.000000] BIOS-e820: [mem 0x000000005aca7018-0x000000005acdb257] usable\r\n[ 0.000000] BIOS-e820: [mem 0x000000005acdb258-0x000000005acdc017] usable\r\n[ 0.000000] BIOS-e820: [mem 0x000000005acdc018-0x000000005ace4057] usable\r\n[ 0.000000] BIOS-e820: [mem 0x000000005ace4058-0x000000005ed9efff] usable\r\n[ 0.000000] BIOS-e820: [mem 0x000000005ed9f000-0x000000005f122fff] ACPI NVS\r\n[ 0.000000] BIOS-e820: [mem 0x000000005f123000-0x00000000699a9fff] usable\r\n[ 0.000000] BIOS-e820: [mem 0x00000000699aa000-0x000000006baa9fff] reserved\r\n[ 0.000000] BIOS-e820: [mem 0x000000006baaa000-0x000000006bed1fff] usable\r\n[ 0.000000] BIOS-e820: [mem 0x000000006bed2000-0x000000006ce85fff] ACPI NVS\r\n[ 0.000000] BIOS-e820: [mem 0x000000006ce86000-0x000000006f2d3fff] reserved\r\n[ 0.000000] BIOS-e820: [mem 0x000000006f2d4000-0x000000006f7fffff] usable\r\n[ 0.000000]" + - delay: 12 + content: " BIOS-e820: [mem 0x000000006f800000-0x000000008fffffff] reserved\r\n[ 0.000000] BIOS-e820: [mem 0x00000000fd000000-0x00000000fe7fffff] reserved\r\n[ 0.000000] BIOS-e820: [mem 0x00000000fed20000-0x00" + - delay: 31 + content: "000000fed44fff] reserved\r\n[ 0.000000] BIOS-e820: [mem 0x00000000ff000000-0x00000000ffffffff] reserved\r\n[ 0.000000] BIOS-e820: [mem 0x0000000100000000-0x000000183fffffff] usable\r\n[ 0.000000] N" + - delay: 5 + content: "X (Execute Disable) protection: active\r\n[ 0.000000] extended physical RAM map:\r\n[ 0.000000] reserve setup_data: [mem 0x0000000000000000-0x000000000009825f] usable\r\n[ 0.000000] reserve setup_d" + - delay: 16 + content: "ata: [mem 0x0000000000098260-0x00000000000982cf] usable\r\n[ 0.000000] reserve setup_data: [mem 0x00000000000982d0-0x000000000009ffff] usable\r\n[ 0.000000] reserve setup_data: [mem 0x00000000000a00" + - delay: 131 + content: "00-0x00000000000fffff] reserved\r\n[ 0.000000] reserve setup_data: [mem 0x0000000000100000-0x000000005ac24017] usable\r\n[ 0.000000] reserve setup_data: [mem 0x000000005ac24018-0x000000005ac2a057] usable\r\n[ 0.000000] reserve setup_data: [mem 0x000000005ac2a058-0x000000005ac2b017] usable\r\n[ 0.000000] reserve setup_data: [mem 0x000000005ac2b018-0x000000005ac31057] usable\r\n[ 0.000000] reserve setup_data: [mem 0x000000005ac31058-0x000000005ac32017] usable\r\n[ 0.000000] reserve setup_data: [mem 0x000000005ac32018-0x000000005ac41057] usable\r\n[ 0.000000] reserve setup_data: [mem 0x000000005ac41058-0x000000005ac42017] usable\r\n[ 0.000000] reserve setup_data: [mem 0x000000005ac42018-0x000000005ac51057] usable\r\n[ 0.000000] reserve setup_data: [mem 0x000000005ac51058-0x000000005ac52017] usable\r\n[ 0.000000] reserve setup_data: [mem 0x000000005ac52018-0x000000005ac61057] usable\r\n[ 0.000000] reserve setup_data: [mem 0x000000005ac61058-0x000000005ac62017] usable\r\n[ 0.000000] reserve setup_data: [mem 0x000000005ac62018-0x000000005ac71057] usable\r\n[ 0.000000] reserve setup_data: [mem 0x000000005ac71058-0x000000005ac72017] usable\r\n[ 0.000000] reserve setup_data: [mem 0x000000005ac72018-0x000000005aca6257] usable\r\n[ 0.000000] reserve setup_data: [mem 0x000000005aca6258-0x000000005aca7017] usable\r\n[ 0.000000] reserve setup_data: [mem 0x000000005aca7018-0x000000005acdb257] usable\r\n[ 0.000000] reserve setup_data: [mem 0x000000005acdb258-0x000000005acdc017] usable\r\n[ 0.000000] reserve setup_data: [mem 0x000000005acdc018-0x000000005ace4057] usable\r\n[" + - delay: 21 + content: " 0.000000] reserve setup_data: [mem 0x000000005ace4058-0x000000005ed9efff] usable\r\n[ 0.000000] reserve setup_data: [mem 0x000000005ed9f000-0x000000005f122fff] ACPI NVS\r\n[ 0.000000] reserve se" + - delay: 20 + content: "tup_data: [mem 0x000000005f123000-0x00000000699a9fff] usable\r\n[ 0.000000] reserve setup_data: [mem 0x00000000699aa000-0x000000006baa9fff] reserved\r\n[ 0.000000] reserve setup_data: [mem 0x0000000" + - delay: 13 + content: "06baaa000-0x000000006bed1fff] usable\r\n[ 0.000000] reserve setup_data: [mem 0x000000006bed2000-0x000000006ce85fff] ACPI NVS\r\n[ 0.000000] reserve setup_data: [mem 0x000000006ce86000-0x000000006f2d" + - delay: 18 + content: "3fff] reserved\r\n[ 0.000000] reserve setup_data: [mem 0x000000006f2d4000-0x000000006f7fffff] usable\r\n[ 0.000000] reserve setup_data: [mem 0x000000006f800000-0x000000008fffffff] reserved\r\n[ 0.0" + - delay: 127 + content: "00000] reserve setup_data: [mem 0x00000000fd000000-0x00000000fe7fffff] reserved\r\n[ 0.000000] reserve setup_data: [mem 0x00000000fed20000-0x00000000fed44fff] reserved\r\n[ 0.000000] reserve setup_data: [mem 0x00000000ff000000-0x00000000ffffffff] reserved\r\n[ 0.000000] reserve setup_data: [mem 0x0000000100000000-0x000000183fffffff] usable\r\n[ 0.000000] efi: EFI v2.70 by American Megatrends\r\n[ 0.000000] efi: ACPI 2.0=0x5ed9f000 ACPI=0x5ed9f000 SMBIOS=0x6eba4000 SMBIOS 3.0=0x6eba3000 MEMATTR=0x66987018 ESRT=0x66990418 \r\n[ 0.000000] secureboot: Secure boot could not be determined (mode 0)\r\n[ 0.000000] SMBIOS 3.2.1 present.\r\n[ 0.000000] DMI: Supermicro SYS-2029BT-HNTR/X11DPT-B, BIOS 3.0a 02/20/2019\r\n[ 0.000000] tsc: Detected 2100.000 MHz processor\r\n[ 0.000042] last_pfn = 0x1840000 max_arch_pfn = 0x400000000\r\n[ 0.002314] x86/PAT: Configuration [0-7]: WB WC UC- UC WB WP UC- WT \r\n[ 0.002904] total RAM covered: 97264M\r\n[ 0.003179] Found optimal setting for mtrr clean up\r\n[ 0.003180] gran_size: 64K \tchunk_size: 32M \tnum_reg: 8 \tlose cover RAM: 0G\r\n[ 0.005452] last_pfn = 0x6f800 max_arch_pfn = 0x400000000\r\n[ 0.015731] esrt: Reserving ESRT space from 0x0000000066990418 to 0x0000000066990450.\r\n[ 0.015744] check: Scanning 1 areas for low memory corruption\r\n[ 0.015748] Using GB pages for direct mapping\r\n[ 0.016909] RAMDISK: [me" + - delay: 8 + content: "m 0x56363000-0x589fffff]\r\n[ 0.016918] ACPI: Early table checksum verification disabled\r\n[ 0.016922] ACPI: RSDP 0x000000005ED9F000 000024 (v02 SUPERM)\r\n[ 0.016926] ACPI: XSDT 0x000000005ED9F0C" + - delay: 29 + content: "0 000104 (v01 SUPERM SUPERM 01072009 AMI 00010013)\r\n[ 0.016933] ACPI: FACP 0x000000005F043A80 000114 (v06 SUPERM SMCI--MB 01072009 INTL 20091013)\r\n[ 0.016939] ACPI: DSDT 0x000000005ED9F260 2A" + - delay: 7 + content: "481A (v02 SUPERM SMCI--MB 01072009 INTL 20091013)\r\n[ 0.016942] ACPI: FACS 0x000000006CE43080 000040\r\n[ 0.016945] ACPI: FPDT 0x000000005F043B98 000044 (v01 01072009 AMI 00010013)" + - delay: 16 + content: "\r\n[ 0.016948] ACPI: FIDT 0x000000005F043BE0 00009C (v01 SUPERM SMCI--MB 01072009 AMI 00010013)\r\n[ 0.016951] ACPI: SPMI 0x000000005F043C80 000041 (v05 SUPERM SMCI--MB 00000000 AMI. 00000000)\r\n[ " + - delay: 19 + content: " 0.016955] ACPI: UEFI 0x000000005F043CC8 00005C (v01 INTEL RstUefiV 00000000 00000000)\r\n[ 0.016958] ACPI: SSDT 0x000000005F043D28 00046C (v02 INTEL ADDRXLAT 00000001 INTL 20140828)\r\n[ 0" + - delay: 124 + content: ".016961] ACPI: MCFG 0x000000005F044198 00003C (v01 SUPERM SMCI--MB 01072009 MSFT 00000097)\r\n[ 0.016964] ACPI: HPET 0x000000005F0441D8 000038 (v01 SUPERM SMCI--MB 00000001 INTL 20091013)\r\n[ 0.016967] ACPI: APIC 0x000000005F044210 0016DE (v03 SUPERM SMCI--MB 00000000 INTL 20091013)\r\n[ 0.016970] ACPI: MIGT 0x000000005F0458F0 000040 (v01 SUPERM SMCI--MB 00000000 INTL 20091013)\r\n[ 0.016973] ACPI: MSCT 0x000000005F045930 000090 (v01 SUPERM SMCI--MB 00000001 INTL 20091013)\r\n[ 0.016976] ACPI: PCAT 0x000000005F0459C0 000088 (v02 SUPERM SMCI--MB 00000002 INTL 20091013)\r\n[ 0.016979] ACPI: PCCT 0x000000005F045A48 00006E (v01 SUPERM SMCI--MB 00000002 INTL 20091013)\r\n[ 0.016982] ACPI: RASF 0x000000005F045AB8 000030 (v01 SUPERM SMCI--MB 00000001 INTL 20091013)\r\n[ 0.016985] ACPI: SLIT 0x000000005F045AE8 00042C (v01 SUPERM SMCI--MB 00000001 INTL 20091013)\r\n[ 0.016988] ACPI: SRAT 0x000000005F045F18 002D30 (v03 SUPERM SMCI--MB 00000002 INTL 20091013)\r\n[ 0.016991] ACPI: SVOS 0x000000005F048C48 000032 (v01 SUPERM SMCI--MB 00000000 INTL 20091013)\r\n[ 0.016994] ACPI: WDDT 0x000000005F048C80 000040 (v01 SUPERM SMCI--MB 00000000 INTL 20091013)\r\n[ 0.016997] ACPI: OEM4 0x000000005F048CC0 0A27C4 (v02 INTEL CPU CST 00003000 INTL 20140828)\r\n[ 0.017001] ACPI: SSDT 0x000000005F0EB488 033990 (v02 INTEL SSDT PM 00004000 INTL 20140828)\r\n[ 0.017004] ACPI: SSDT 0x000000" + - delay: 12 + content: "005F11EE18 00065B (v02 SUPERM SMCI--MB 00000000 INTL 20091013)\r\n[ 0.017007] ACPI: SSDT 0x000000005F11F478 002B10 (v02 INTEL SpsNm 00000002 INTL 20140828)\r\n[ 0.017010] ACPI: DMAR 0x000000005F" + - delay: 19 + content: "121F88 000270 (v01 SUPERM SMCI--MB 00000001 INTL 20091013)\r\n[ 0.017013] ACPI: HEST 0x000000005F1221F8 0000A8 (v01 SUPERM SMCI--MB 00000001 INTL 00000001)\r\n[ 0.017016] ACPI: BERT 0x000000005F1222" + - delay: 16 + content: "A0 000030 (v01 SUPERM SMCI--MB 00000001 INTL 00000001)\r\n[ 0.017019] ACPI: ERST 0x000000005F1222D0 000230 (v01 SUPERM SMCI--MB 00000001 INTL 00000001)\r\n[ 0.017022] ACPI: EINJ 0x000000005F122500 0" + - delay: 16 + content: "00150 (v01 SUPERM SMCI--MB 00000001 INTL 00000001)\r\n[ 0.017025] ACPI: WSMT 0x000000005F122650 000028 (v01 Fo 01072009 AMI 00010013)\r\n[ 0.017088] SRAT: PXM 0 -> APIC 0x00 -> Node 0\r" + - delay: 17 + content: "\n[ 0.017089] SRAT: PXM 0 -> APIC 0x02 -> Node 0\r\n[ 0.017090] SRAT: PXM 0 -> APIC 0x04 -> Node 0\r\n[ 0.017091] SRAT: PXM 0 -> APIC 0x06 -> Node 0\r\n[ 0.017092] SRAT: PXM 0 -> APIC 0x08 -> Nod" + - delay: 120 + content: "e 0\r\n[ 0.017093] SRAT: PXM 0 -> APIC 0x0a -> Node 0\r\n[ 0.017094] SRAT: PXM 0 -> APIC 0x0c -> Node 0\r\n[ 0.017094] SRAT: PXM 0 -> APIC 0x0e -> Node 0\r\n[ 0.017096] SRAT: PXM 1 -> APIC 0x10 -> Node 1\r\n[ 0.017096] SRAT: PXM 1 -> APIC 0x12 -> Node 1\r\n[ 0.017097] SRAT: PXM 1 -> APIC 0x14 -> Node 1\r\n[ 0.017098] SRAT: PXM 1 -> APIC 0x16 -> Node 1\r\n[ 0.017099] SRAT: PXM 1 -> APIC 0x18 -> Node 1\r\n[ 0.017100] SRAT: PXM 1 -> APIC 0x1a -> Node 1\r\n[ 0.017101] SRAT: PXM 1 -> APIC 0x1c -> Node 1\r\n[ 0.017102] SRAT: PXM 1 -> APIC 0x1e -> Node 1\r\n[ 0.017103] SRAT: PXM 0 -> APIC 0x01 -> Node 0\r\n[ 0.017103] SRAT: PXM 0 -> APIC 0x03 -> Node 0\r\n[ 0.017104] SRAT: PXM 0 -> APIC 0x05 -> Node 0\r\n[ 0.017105] SRAT: PXM 0 -> APIC 0x07 -> Node 0\r\n[ 0.017106] SRAT: PXM 0 -> APIC 0x09 -> Node 0\r\n[ 0.017107] SRAT: PXM 0 -> APIC 0x0b -> Node 0\r\n[ 0.017108] SRAT: PXM 0 -> APIC 0x0d -> Node 0\r\n[ 0.017109] SRAT: PXM 0 -> APIC 0x0f -> Node 0\r\n[ 0.017109] SRAT: PXM 1 -> APIC 0x11 -> Node 1\r\n[ 0.017110] SRAT: PXM 1 -> APIC 0x13 -> Node 1\r\n[ 0.017111] SRAT: PXM 1 -> APIC 0x15 -> Node 1\r\n[ 0.017112] SRAT: PXM 1 -> APIC 0x17 -> Node 1\r\n[ 0.017113] SRAT: PXM 1 -> APIC 0x19 -> Node 1\r\n[ 0.017114] SRAT: PXM 1 -> APIC 0x1b -> Node 1\r\n[ 0.017115] SRAT: PXM 1 -> APIC 0x1d -> Node 1\r\n[ 0.017116] SRAT: PXM 1 -> APIC 0x1f -> Node 1\r\n[ 0.017132] ACP" + - delay: 16 + content: "I: SRAT: Node 0 PXM 0 [mem 0x00000000-0x7fffffff]\r\n[ 0.017134] ACPI: SRAT: Node 0 PXM 0 [mem 0x100000000-0xc3fffffff]\r\n[ 0.017135] ACPI: SRAT: Node 1 PXM 1 [mem 0xc40000000-0x183fffffff]\r\n[ 0" + - delay: 18 + content: ".017146] NUMA: Node 0 [mem 0x00000000-0x7fffffff] + [mem 0x100000000-0xc3fffffff] -> [mem 0x00000000-0xc3fffffff]\r\n[ 0.017157] NODE_DATA(0) allocated [mem 0xc3ffd5000-0xc3fffffff]\r\n[ 0.017185] N" + - delay: 17 + content: "ODE_DATA(1) allocated [mem 0x183ffd2000-0x183fffcfff]\r\n[ 0.017472] Zone ranges:\r\n[ 0.017473] DMA [mem 0x0000000000001000-0x0000000000ffffff]\r\n[ 0.017475] DMA32 [mem 0x000000000100" + - delay: 17 + content: "0000-0x00000000ffffffff]\r\n[ 0.017476] Normal [mem 0x0000000100000000-0x000000183fffffff]\r\n[ 0.017477] Device empty\r\n[ 0.017479] Movable zone start for each node\r\n[ 0.017483] Early " + - delay: 134 + content: "memory node ranges\r\n[ 0.017484] node 0: [mem 0x0000000000001000-0x000000000009ffff]\r\n[ 0.017485] node 0: [mem 0x0000000000100000-0x000000005ed9efff]\r\n[ 0.017486] node 0: [mem 0x000000005f123000-0x00000000699a9fff]\r\n[ 0.017487] node 0: [mem 0x000000006baaa000-0x000000006bed1fff]\r\n[ 0.017488] node 0: [mem 0x000000006f2d4000-0x000000006f7fffff]\r\n[ 0.017489] node 0: [mem 0x0000000100000000-0x0000000c3fffffff]\r\n[ 0.017490] node 1: [mem 0x0000000c40000000-0x000000183fffffff]\r\n[ 0.017925] Zeroed struct page in unavailable ranges: 24807 pages\r\n[ 0.017926] Initmem setup node 0 [mem 0x0000000000001000-0x0000000c3fffffff]\r\n[ 0.334156] Initmem setup node 1 [mem 0x0000000c40000000-0x000000183fffffff]\r\n[ 0.666962] ACPI: PM-Timer IO Port: 0x508\r\n[ 0.666985] ACPI: X2APIC_NMI (uid[0xffffffff] high level lint[0x1])\r\n[ 0.666988] ACPI: LAPIC_NMI (acpi_id[0xff] dfl edge lint[0x1])\r\n[ 0.667009] IOAPIC[0]: apic_id 8, version 32, address 0xfec00000, GSI 0-23\r\n[ 0.667013] IOAPIC[1]: apic_id 9, version 32, address 0xfec01000, GSI 24-31\r\n[ 0.667018] IOAPIC[2]: apic_id 10, version 32, address 0xfec08000, GSI 32-39\r\n[ 0.667022] IOAPIC[3]: apic_id 11, version 32, address 0xfec10000, GSI 40-47\r\n[ 0.667026] IOAPIC[4]: apic_id 12, version 32, address 0xfec18000, GSI 48-55\r\n[ 0.667031] IOAPIC[5]: apic_id 15, version 32, address" + - delay: 5 + content: " 0xfec20000, GSI 72-79\r\n[ 0.667036] IOAPIC[6]: apic_id 16, version 32, address 0xfec28000, GSI 80-87\r\n[ 0.667041] IOAPIC[7]: apic_id 17, version 32, address 0xfec30000, GSI 88-95\r\n[ 0.667046]" + - delay: 15 + content: " IOAPIC[8]: apic_id 18, version 32, address 0xfec38000, GSI 96-103\r\n[ 0.667051] ACPI: INT_SRC_OVR (bus 0 bus_irq 0 global_irq 2 dfl dfl)\r\n[ 0.667053] ACPI: INT_SRC_OVR (bus 0 bus_irq 9 global_ir" + - delay: 19 + content: "q 9 high level)\r\n[ 0.667062] Using ACPI (MADT) for SMP configuration information\r\n[ 0.667064] ACPI: HPET id: 0x8086a701 base: 0xfed00000\r\n[ 0.667068] smpboot: Allowing 32 CPUs, 0 hotplug CPUs" + - delay: 15 + content: "\r\n[ 0.667105] PM: Registered nosave memory: [mem 0x00000000-0x00000fff]\r\n[ 0.667108] PM: Registered nosave memory: [mem 0x00098000-0x00098fff]\r\n[ 0.667110] PM: Registered nosave memory: [mem " + - delay: 18 + content: "0x00098000-0x00098fff]\r\n[ 0.667112] PM: Registered nosave memory: [mem 0x000a0000-0x000fffff]\r\n[ 0.667114] PM: Registered nosave memory: [mem 0x5ac24000-0x5ac24fff]\r\n[ 0.667116] PM: Registere" + - delay: 128 + content: "d nosave memory: [mem 0x5ac2a000-0x5ac2afff]\r\n[ 0.667117] PM: Registered nosave memory: [mem 0x5ac2b000-0x5ac2bfff]\r\n[ 0.667119] PM: Registered nosave memory: [mem 0x5ac31000-0x5ac31fff]\r\n[ 0.667120] PM: Registered nosave memory: [mem 0x5ac32000-0x5ac32fff]\r\n[ 0.667122] PM: Registered nosave memory: [mem 0x5ac41000-0x5ac41fff]\r\n[ 0.667123] PM: Registered nosave memory: [mem 0x5ac42000-0x5ac42fff]\r\n[ 0.667125] PM: Registered nosave memory: [mem 0x5ac51000-0x5ac51fff]\r\n[ 0.667126] PM: Registered nosave memory: [mem 0x5ac52000-0x5ac52fff]\r\n[ 0.667128] PM: Registered nosave memory: [mem 0x5ac61000-0x5ac61fff]\r\n[ 0.667129] PM: Registered nosave memory: [mem 0x5ac62000-0x5ac62fff]\r\n[ 0.667131] PM: Registered nosave memory: [mem 0x5ac71000-0x5ac71fff]\r\n[ 0.667132] PM: Registered nosave memory: [mem 0x5ac72000-0x5ac72fff]\r\n[ 0.667134] PM: Registered nosave memory: [mem 0x5aca6000-0x5aca6fff]\r\n[ 0.667135] PM: Registered nosave memory: [mem 0x5aca7000-0x5aca7fff]\r\n[ 0.667137] PM: Registered nosave memory: [mem 0x5acdb000-0x5acdbfff]\r\n[ 0.667138] PM: Registered nosave memory: [mem 0x5acdc000-0x5acdcfff]\r\n[ 0.667140] PM: Registered nosave memory: [mem 0x5ace4000-0x5ace4fff]\r\n[ 0.667143] PM: Registered nosave memory: [mem 0x5ed9f000-0x5f122fff]\r\n[ 0.667145] PM: Registered nosave memory: [mem 0x699aa000-0x6baa9fff]\r\n[ 0.667148] PM: Reg" + - delay: 5 + content: "istered nosave memory: [mem 0x6bed2000-0x6ce85fff]\r\n[ 0.667149] PM: Registered nosave memory: [mem 0x6ce86000-0x6f2d3fff]\r\n[ 0.667151] PM: Registered nosave memory: [mem 0x6f800000-0x8fffffff]\r\n" + - delay: 30 + content: "[ 0.667152] PM: Registered nosave memory: [mem 0x90000000-0xfcffffff]\r\n[ 0.667153] PM: Registered nosave memory: [mem 0xfd000000-0xfe7fffff]\r\n[ 0.667154] PM: Registered nosave memory: [mem 0x" + - delay: 5 + content: "fe800000-0xfed1ffff]\r\n[ 0.667154] PM: Registered nosave memory: [mem 0xfed20000-0xfed44fff]\r\n[ 0.667155] PM: Registered nosave memory: [mem 0xfed45000-0xfeffffff]\r\n[ 0.667156] PM: Registered " + - delay: 18 + content: "nosave memory: [mem 0xff000000-0xffffffff]\r\n[ 0.667158] [mem 0x90000000-0xfcffffff] available for PCI devices\r\n[ 0.667160] Booting paravirtualized kernel on bare hardware\r\n[ 0.667163] clockso" + - delay: 17 + content: "urce: refined-jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 7645519600211568 ns\r\n[ 0.667175] random: get_random_bytes called from start_kernel+0x97/0x516 with crng_init=0\r\n[ 0.6" + - delay: 126 + content: "67184] setup_percpu: NR_CPUS:8192 nr_cpumask_bits:32 nr_cpu_ids:32 nr_node_ids:2\r\n[ 0.669224] percpu: Embedded 46 pages/cpu s151552 r8192 d28672 u262144\r\n[ 0.669283] Built 2 zonelists, mobility grouping on. Total pages: 24425600\r\n[ 0.669284] Policy zone: Normal\r\n[ 0.669286] Kernel command line: console=ttyS1,115200n8 root=UUID=85974557-9beb-4400-a6a9-c1d65f301160 init=/bin/systemd net.ifnames=0 biosdevname=0 acpi_rsdp=0x5ed9f000\r\n[ 0.945148] Memory: 97555808K/99253348K available (14339K kernel code, 2335K rwdata, 4304K rodata, 2576K init, 5204K bss, 1697540K reserved, 0K cma-reserved)\r\n[ 0.945696] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=32, Nodes=2\r\n[ 0.945706] Kernel/User page tables isolation: enabled\r\n[ 0.945733] ftrace: allocating 41580 entries in 163 pages\r\n[ 0.964921] rcu: Hierarchical RCU implementation.\r\n[ 0.964923] rcu: \tRCU restricting CPUs from NR_CPUS=8192 to nr_cpu_ids=32.\r\n[ 0.964925] \tTasks RCU enabled.\r\n[ 0.964926] rcu: RCU calculated value of scheduler-enlistment delay is 25 jiffies.\r\n[ 0.964927] rcu: Adjusting geometry for rcu_fanout_leaf=16, nr_cpu_ids=32\r\n[ 0.968256] NR_IRQS: 524544, nr_irqs: 2040, preallocated irqs: 16\r\n[ 0.968614] Console: colour dummy device 80x25\r\n[ 2.747576] printk: console [ttyS1] enabled\r\n[ 2.751829] mempolicy: Enabling automatic NUMA balancing. Configure with numa_balancing=" + - delay: 13 + content: " or the kernel.numa_balancing sysctl\r\n[ 2.763049] ACPI: Core revision 20181213\r\n[ 2.770098] clocksource: hpet: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 79635855245 ns\r\n[ 2.779183" + - delay: 20 + content: "] APIC: Switch to symmetric I/O mode setup\r\n[ 2.784162] DMAR: Host address width 46\r\n[ 2.788011] DMAR: DRHD base: 0x000000d37fc000 flags: 0x0\r\n[ 2.793334] DMAR: dmar0: reg_base_addr d37fc000 " + - delay: 15 + content: "ver 1:0 cap 8d2078c106f0466 ecap f020df\r\n[ 2.801338] DMAR: DRHD base: 0x000000e0ffc000 flags: 0x0\r\n[ 2.806664] DMAR: dmar1: reg_base_addr e0ffc000 ver 1:0 cap 8d2078c106f0466 ecap f020df\r\n[ 2" + - delay: 17 + content: ".814679] DMAR: DRHD base: 0x000000ee7fc000 flags: 0x0\r\n[ 2.820002] DMAR: dmar2: reg_base_addr ee7fc000 ver 1:0 cap 8d2078c106f0466 ecap f020df\r\n[ 2.828006] DMAR: DRHD base: 0x000000fbffc000 flag" + - delay: 18 + content: "s: 0x0\r\n[ 2.833331] DMAR: dmar3: reg_base_addr fbffc000 ver 1:0 cap 8d2078c106f0466 ecap f020df\r\n[ 2.841334] DMAR: DRHD base: 0x000000aaffc000 flags: 0x0\r\n[ 2.846660] DMAR: dmar4: reg_base_ad" + - delay: 119 + content: "dr aaffc000 ver 1:0 cap 8d2078c106f0466 ecap f020df\r\n[ 2.854667] DMAR: DRHD base: 0x000000b87fc000 flags: 0x0\r\n[ 2.859988] DMAR: dmar5: reg_base_addr b87fc000 ver 1:0 cap 8d2078c106f0466 ecap f020df\r\n[ 2.867995] DMAR: DRHD base: 0x000000c5ffc000 flags: 0x0\r\n[ 2.873321] DMAR: dmar6: reg_base_addr c5ffc000 ver 1:0 cap 8d2078c106f0466 ecap f020df\r\n[ 2.881331] DMAR: DRHD base: 0x0000009d7fc000 flags: 0x1\r\n[ 2.886662] DMAR: dmar7: reg_base_addr 9d7fc000 ver 1:0 cap 8d2078c106f0466 ecap f020df\r\n[ 2.894673] DMAR: RMRR base: 0x0000006ebe0000 end: 0x0000006ebf0fff\r\n[ 2.900947] DMAR: ATSR flags: 0x0\r\n[ 2.904273] DMAR: ATSR flags: 0x0\r\n[ 2.907601] DMAR: RHSA base: 0x0000009d7fc000 proximity domain: 0x0\r\n[ 2.913877] DMAR: RHSA base: 0x000000aaffc000 proximity domain: 0x0\r\n[ 2.920152] DMAR: RHSA base: 0x000000b87fc000 proximity domain: 0x0\r\n[ 2.926426] DMAR: RHSA base: 0x000000c5ffc000 proximity domain: 0x0\r\n[ 2.932703] DMAR: RHSA base: 0x000000d37fc000 proximity domain: 0x1\r\n[ 2.938975] DMAR: RHSA base: 0x000000e0ffc000 proximity domain: 0x1\r\n[ 2.945250] DMAR: RHSA base: 0x000000ee7fc000 proximity domain: 0x1\r\n[ 2.951525] DMAR: RHSA base: 0x000000fbffc000 proximity domain: 0x1\r\n[ 2.957799] DMAR-IR: IOAPIC id 12 under DRHD base 0xc5ffc000 IOMMU 6\r\n[ 2.964249] DMAR-IR: IOAPIC id 11 under DRHD base 0xb87fc000 IOMMU 5\r\n[ 2.970697] D" + - delay: 17 + content: "MAR-IR: IOAPIC id 10 under DRHD base 0xaaffc000 IOMMU 4\r\n[ 2.977144] DMAR-IR: IOAPIC id 18 under DRHD base 0xfbffc000 IOMMU 3\r\n[ 2.983592] DMAR-IR: IOAPIC id 17 under DRHD base 0xee7fc000 IOM" + - delay: 18 + content: "MU 2\r\n[ 2.990040] DMAR-IR: IOAPIC id 16 under DRHD base 0xe0ffc000 IOMMU 1\r\n[ 2.996487] DMAR-IR: IOAPIC id 15 under DRHD base 0xd37fc000 IOMMU 0\r\n[ 3.002938] DMAR-IR: IOAPIC id 8 under DRHD" + - delay: 17 + content: " base 0x9d7fc000 IOMMU 7\r\n[ 3.009299] DMAR-IR: IOAPIC id 9 under DRHD base 0x9d7fc000 IOMMU 7\r\n[ 3.015661] DMAR-IR: HPET id 0 under DRHD base 0x9d7fc000\r\n[ 3.021067] DMAR-IR: Queued invalid" + - delay: 20 + content: "ation will be enabled to support x2apic and Intr-remapping.\r\n[ 3.031641] DMAR-IR: Enabled IRQ remapping in x2apic mode\r\n[ 3.037037] x2apic enabled\r\n[ 3.039774] Switched APIC routing to cluste" + - delay: 130 + content: "r x2apic.\r\n[ 3.045837] ..TIMER: vector=0x30 apic1=0 pin1=2 apic2=-1 pin2=-1\r\n[ 3.071164] clocksource: tsc-early: mask: 0xffffffffffffffff max_cycles: 0x1e4530a99b6, max_idle_ns: 440795257976 ns\r\n[ 3.081681] Calibrating delay loop (skipped), value calculated using timer frequency.. 4200.00 BogoMIPS (lpj=8400000)\r\n[ 3.085672] pid_max: default: 32768 minimum: 301\r\n[ 3.090727] LSM: Security Framework initializing\r\n[ 3.093694] Yama: becoming mindful.\r\n[ 3.097726] AppArmor: AppArmor initialized\r\n[ 3.115618] Dentry cache hash table entries: 8388608 (order: 14, 67108864 bytes)\r\n[ 3.124422] Inode-cache hash table entries: 4194304 (order: 13, 33554432 bytes)\r\n[ 3.125889] Mount-cache hash table entries: 131072 (order: 8, 1048576 bytes)\r\n[ 3.129843] Mountpoint-cache hash table entries: 131072 (order: 8, 1048576 bytes)\r\n[ 3.134141] mce: CPU0: Thermal monitoring enabled (TM1)\r\n[ 3.137705] process: using mwait in idle threads\r\n[ 3.141674] Last level iTLB entr" + - delay: 10 + content: "ies: 4KB 64, 2MB 8, 4MB 8\r\n[ 3.145672] Last level dTLB entries: 4KB 64, 2MB 0, 4MB 0, 1GB 4\r\n[ 3.149672] Spectre V1 : Mitigation: usercopy/swapgs barriers and __user pointer sanitization\r\n[ 3" + - delay: 18 + content: ".153673] Spectre V2 : Mitigation: Full generic retpoline\r\n[ 3.157672] Spectre V2 : Spectre v2 / SpectreRSB mitigation: Filling RSB on context switch\r\n[ 3.161672] Spectre V2 : Enabling Restricted" + - delay: 16 + content: " Speculation for firmware calls\r\n[ 3.165678] Spectre V2 : mitigation: Enabling conditional Indirect Branch Prediction Barrier\r\n[ 3.169672] Spectre V2 : User space: Mitigation: STIBP via seccomp " + - delay: 19 + content: "and prctl\r\n[ 3.173672] Speculative Store Bypass: Mitigation: Speculative Store Bypass disabled via prctl and seccomp\r\n[ 3.177699] MDS: Mitigation: Clear CPU buffers\r\n[ 3.181963] Freeing SMP a" + - delay: 19 + content: "lternatives memory: 36K\r\n[ 3.190289] smpboot: CPU0: Intel(R) Xeon(R) Silver 4110 CPU @ 2.10GHz (family: 0x6, model: 0x55, stepping: 0x4)\r\n[ 3.193858] Performance Events: PEBS fmt3+, Skylake even" + - delay: 120 + content: "ts, 32-deep LBR, full-width counters, Intel PMU driver.\r\n[ 3.197676] ... version: 4\r\n[ 3.201672] ... bit width: 48\r\n[ 3.205672] ... generic registers: 4\r\n[ 3.209672] ... value mask: 0000ffffffffffff\r\n[ 3.213672] ... max period: 00007fffffffffff\r\n[ 3.217672] ... fixed-purpose events: 3\r\n[ 3.221672] ... event mask: 000000070000000f\r\n[ 3.225741] rcu: Hierarchical SRCU implementation.\r\n[ 3.230899] random: crng done (trusting CPU's manufacturer)\r\n[ 3.236873] NMI watchdog: Enabled. Permanently consum" + - delay: 37 + content: "es one hw-PMU counter.\r\n[ 3.238129] smp: Bringing up secondary CPUs ...\r\n[ 3.241802] x86: Booting SMP configuration:\r\n[ 3.245674] .... node #0, CPUs: #1 #2 #3 #4 #5 #6 #7\r\n" + - delay: 166 + content: "[ 3.281674] .... node #1, CPUs: #8 #9 #10 #11 #12 #13 #14 #15\r\n[ 3.413673] .... node #0, CPUs: #16\r\n[ 3.414958] MDS CPU bug present and SMT on, data leak possible. See https://www.kernel.org/doc/html/latest/admin-guide/hw-vuln/mds.html for more details.\r\n[ 3.421813] #17 #18 #19 #20 #21 #22 #23\r\n[ 3.433673] .... node #1, CPUs: #24 #25 #26 #27 #28 #29 #30 #31\r\n[ 3.442909] smp: Brought up 2 nodes, 32 CPUs\r\n[ 3.4496" + - delay: 81 + content: "73] smpboot: Max logical packages: 2\r\n[ 3.453673] smpboot: Total of 32 processors activated (134430.48 BogoMIPS)\r\n" + - delay: 123 + content: "[ 3.464967] devtmpfs: initialized\r\n[ 3.465745] x86/mm: Memory block size: 1024MB\r\n[ 3.473720] PM: Registering ACPI NVS region [mem 0x5ed9f000-0x5f122fff] (3686400 bytes)\r\n[ 3.481732] PM: Registering ACPI NVS region [mem 0x6bed2000-0x6ce85fff] (16465920 bytes)\r\n[ 3.490049] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 7645041785100000 ns\r\n[ 3.497716] futex hash table entries: 8192 (order: 7, 524288 bytes)\r\n[ 3.505961] pinctrl core: initialized pinctrl subsystem\r\n[ 3.509804] RTC time: 12:45:15, date: 2019-09-21\r\n[ 3.513915] NET: Registered protocol family 16\r\n[ 3.517807] audit: initializing netlink subsys (disabled)\r\n[ 3.525692] audit: type=2000 audit(1569069912.644:1): state=initialized audit_enabled=0 res=1\r\n[ 3.525792] EISA bus registered\r\n[ 3.532830] cpuidle: using governor ladder\r\n[ 3.533707] cpuidle: using governor menu\r\n[ 3.537677] Detected 1 PCC Subspaces\r\n[ 3.541264] Registering PCC driver as Mailbox controller\r\n[ 3.549707] ACPI FADT declares the system doesn't support PCIe ASPM, so disable it\r\n[ 3.553673] ACPI: bus type PCI registered\r\n[ 3.561673] acpiphp: ACPI Hot Plug PCI Controller Driver version: 0.5\r\n[ 3.565765] PCI: MMCONFIG for domain 0000 [bus 00-ff] at [mem 0x80000000-0x8fffffff] (base 0x80000000)\r\n[ 3.573675] PCI: MMCONFIG at [mem 0x80000000-0x8fffffff] reserved in E82" + - delay: 20 + content: "0\r\n[ 3.581687] PCI: Using configuration type 1 for base access\r\n[ 3.591820] HugeTLB registered 1.00 GiB page size, pre-allocated 0 pages\r\n[ 3.597676] HugeTLB registered 2.00 MiB page size, pr" + - delay: 18 + content: "e-allocated 0 pages\r\n[ 3.605854] ACPI: Added _OSI(Module Device)\r\n[ 3.609675] ACPI: Added _OSI(Processor Device)\r\n[ 3.613677] ACPI: Added _OSI(3.0 _SCP Extensions)\r\n[ 3.617672] ACPI: Added" + - delay: 18 + content: " _OSI(Processor Aggregator Device)\r\n[ 3.621673] ACPI: Added _OSI(Linux-Dell-Video)\r\n[ 3.625672] ACPI: Added _OSI(Linux-Lenovo-NV-HDMI-Audio)\r\n[ 3.633672] ACPI: Added _OSI(Linux-HPI-Hybrid-Gra" + - delay: 141 + content: "phics)\r\n" + - delay: 56 + content: "[ 3.791166] ACPI: 5 ACPI AML tables successfully acquired and loaded\r\n[ 3.811676] ACPI: [Firmware Bug]: BIOS _OSI(Linux) query ignored\r\n" + - delay: 148 + content: "[ 3.828497] ACPI: Dynamic OEM Table Load:\r\n" + - delay: 205 + content: "[ 4.078300] ACPI: Interpreter enabled\r\n[ 4.081698] ACPI: (supports S0 S4 S5)\r\n[ 4.085362] ACPI: Using IOAPIC for interrupt routing\r\n[ 4.089777] HEST: Table parsing has been initialized.\r\n[" + - delay: 11 + content: " 4.097678] PCI: Using host bridge windows from ACPI; if necessary, use \"pci=nocrs\" and report a bug\r\n[ 4.107325] ACPI: Enabled 6 GPEs in block 00 to 7F\r\n[ 4.187414] ACPI: PCI Root Bridge [PC0" + - delay: 16 + content: "0] (domain 0000 [bus 00-16])\r\n[ 4.193678] acpi PNP0A08:00: _OSC: OS supports [ExtendedConfig ASPM ClockPM Segments MSI]\r\n[ 4.201892] acpi PNP0A08:00: _OSC: platform does not support [SHPCHotplug" + - delay: 20 + content: " AER LTR]\r\n[ 4.209877] acpi PNP0A08:00: _OSC: OS now controls [PCIeHotplug PME PCIeCapability]\r\n[ 4.217673] acpi PNP0A08:00: FADT indicates ASPM is unsupported, using BIOS configuration\r\n[ 4." + - delay: 17 + content: "226457] PCI host bridge to bus 0000:00\r\n[ 4.229674] pci_bus 0000:00: root bus resource [io 0x0000-0x03af window]\r\n[ 4.233673] pci_bus 0000:00: root bus resource [io 0x03e0-0x0cf7 window]\r\n[ " + - delay: 16 + content: " 4.241673] pci_bus 0000:00: root bus resource [io 0x03b0-0x03bb window]\r\n[ 4.249673] pci_bus 0000:00: root bus resource [io 0x03c0-0x03df window]\r\n[ 4.257673] pci_bus 0000:00: root bus resourc" + - delay: 125 + content: "e [io 0x1000-0x3fff window]\r\n[ 4.261673] pci_bus 0000:00: root bus resource [mem 0x000a0000-0x000bffff window]\r\n[ 4.269673] pci_bus 0000:00: root bus resource [mem 0x000c4000-0x000c7fff window]\r\n[ 4.277673] pci_bus 0000:00: root bus resource [mem 0xfe010000-0xfe010fff window]\r\n[ 4.285673] pci_bus 0000:00: root bus resource [mem 0x90000000-0x9d7fffff window]\r\n[ 4.293673] pci_bus 0000:00: root bus resource [mem 0x380000000000-0x383fffffffff window]\r\n[ 4.301674] pci_bus 0000:00: root bus resource [bus 00-16]\r\n[ 4.312673] pci 0000:00:1c.0: PCI bridge to [bus 01]\r\n[ 4.317966] pci 0000:00:1c.5: PCI bridge to [bus 02-03]\r\n[ 4.325717] pci_bus 0000:03: extended config space not accessible\r\n[ 4.329806] pci 0000:03:00.0: BAR 0: assigned to efifb\r\n[ 4.333812] pci 0000:02:00.0: PCI bridge to [bus 03]\r\n[ 4.342843] ACPI: PCI Root Bridge [PC01] (domain 0000 [bus 17-39])\r\n[ 4.349676] acpi PNP0A08:01: _OSC: OS supports [ExtendedConfig ASPM ClockPM Segments MSI]\r\n[ 4.358358] acpi PNP0A08:01: _OSC: platform does not support [SHPCHotplug AER LTR]\r\n[ 4.366113] acpi PNP0A08:01: _OSC: OS now controls [PCIeHotplug PME PCIeCapability]\r\n[ 4.373673] acpi PNP0A0" + - delay: 5 + content: "8:01: FADT indicates ASPM is unsupported, using BIOS configuration\r\n[ 4.381959] PCI host bridge to bus 0000:17\r\n[ 4.385674] pci_bus 0000:17: root bus resource [io 0x4000-0x5fff window]\r\n[ 4." + - delay: 16 + content: "389673] pci_bus 0000:17: root bus resource [mem 0x9d800000-0xaaffffff window]\r\n[ 4.397673] pci_bus 0000:17: root bus resource [mem 0x384000000000-0x387fffffffff window]\r\n[ 4.405673] pci_bus 0000" + - delay: 21 + content: ":17: root bus resource [bus 17-39]\r\n[ 4.416819] pci 0000:18:00.0: VF(n) BAR0 space: [mem 0x00000000-0x003fffff 64bit pref] (contains BAR0 for 64 VFs)\r\n[ 4.425685] pci 0000:18:00.0: VF(n) BAR3 sp" + - delay: 17 + content: "ace: [mem 0x00000000-0x000fffff 64bit pref] (contains BAR3 for 64 VFs)\r\n[ 4.437972] pci 0000:18:00.1: VF(n) BAR0 space: [mem 0x00000000-0x003fffff 64bit pref] (contains BAR0 for 64 VFs)\r\n[ 4.445" + - delay: 18 + content: "685] pci 0000:18:00.1: VF(n) BAR3 space: [mem 0x00000000-0x000fffff 64bit pref] (contains BAR3 for 64 VFs)\r\n[ 4.457854] pci 0000:17:00.0: PCI bridge to [bus 18]\r\n[ 4.461841] ACPI: PCI Root Bridg" + - delay: 123 + content: "e [PC02] (domain 0000 [bus 3a-5c])\r\n[ 4.469676] acpi PNP0A08:02: _OSC: OS supports [ExtendedConfig ASPM ClockPM Segments MSI]\r\n[ 4.478316] acpi PNP0A08:02: _OSC: platform does not support [SHPCHotplug AER LTR]\r\n[ 4.486065] acpi PNP0A08:02: _OSC: OS now controls [PCIeHotplug PME PCIeCapability]\r\n[ 4.493673] acpi PNP0A08:02: FADT indicates ASPM is unsupported, using BIOS configuration\r\n[ 4.501916] PCI host bridge to bus 0000:3a\r\n[ 4.505674] pci_bus 0000:3a: root bus resource [io 0x6000-0x7fff window]\r\n[ 4.513673] pci_bus 0000:3a: root bus resource [mem 0xab000000-0xb87fffff window]\r\n[ 4.521673] pci_bus 0000:3a: root bus resource [mem 0x388000000000-0x38bfffffffff window]\r\n[ 4.529673] pci_bus 0000:3a: root bus resource [bus 3a-5c]\r\n[ 4.536481] pci 0000:3b:00.0: VF(n) BAR0 space: [mem 0x00000000-0x0001ffff 64bit pref] (contains BAR0 for 8 VFs)\r\n[ 4.545687] pci 0000:3b:00.0: VF(n) BAR3 space: [mem 0x00000000-0x0001ffff 64bit pref] (contains BAR3 for 8 VFs)\r\n[ 4.557913] pci 0000:3b:00.1: VF(n) BAR0 space: [mem 0x00000000-0x0001ffff 64bit pref] (contains BAR0 for 8 VFs)\r\n[ 4.565688] pci 0000:3b:00.1: VF(n) BAR3 space: [mem 0x00000000-0x0001ffff 64bit pref] (contains BAR3 for 8 VFs)\r\n[ 4.577900] pci 0000:3b:00.2: VF(n) BAR0 space: [mem 0x00000000-0x0001ffff 64bit pref] (contains BAR0 for 8 VFs)\r\n[ 4.585686] pci 0000:3b:00.2: VF(n) BAR3 spac" + - delay: 17 + content: "e: [mem 0x00000000-0x0001ffff 64bit pref] (contains BAR3 for 8 VFs)\r\n[ 4.597898] pci 0000:3b:00.3: VF(n) BAR0 space: [mem 0x00000000-0x0001ffff 64bit pref] (contains BAR0 for 8 VFs)\r\n[ 4.609687]" + - delay: 19 + content: " pci 0000:3b:00.3: VF(n) BAR3 space: [mem 0x00000000-0x0001ffff 64bit pref] (contains BAR3 for 8 VFs)\r\n[ 4.617770] pci 0000:3a:00.0: PCI bridge to [bus 3b]\r\n[ 4.621814] ACPI: PCI Root Bridge [PC" + - delay: 14 + content: "03] (domain 0000 [bus 5d-7f])\r\n[ 4.629675] acpi PNP0A08:03: _OSC: OS supports [ExtendedConfig ASPM ClockPM Segments MSI]\r\n[ 4.638331] acpi PNP0A08:03: _OSC: platform does not support [SHPCHotplu" + - delay: 20 + content: "g AER LTR]\r\n[ 4.646064] acpi PNP0A08:03: _OSC: OS now controls [PCIeHotplug PME PCIeCapability]\r\n[ 4.653673] acpi PNP0A08:03: FADT indicates ASPM is unsupported, using BIOS configuration\r\n[ 4" + - delay: 137 + content: ".661941] PCI host bridge to bus 0000:5d\r\n[ 4.665674] pci_bus 0000:5d: root bus resource [io 0x8000-0x9fff window]\r\n[ 4.673673] pci_bus 0000:5d: root bus resource [mem 0xb8800000-0xc5ffffff window]\r\n[ 4.681673] pci_bus 0000:5d: root bus resource [mem 0x38c000000000-0x38ffffffffff window]\r\n[ 4.689673] pci_bus 0000:5d: root bus resource [bus 5d-7f]\r\n[ 4.694990] ACPI: PCI Root Bridge [PC06] (domain 0000 [bus 80-84])\r\n[ 4.701675] acpi PNP0A08:06: _OSC: OS supports [ExtendedConfig ASPM ClockPM Segments MSI]\r\n[ 4.710063] acpi PNP0A08:06: _OSC: platform does not support [SHPCHotplug AER LTR]\r\n[ 4.717965] acpi PNP0A08:06: _OSC: OS now controls [PCIeHotplug PME PCIeCapability]\r\n[ 4.725673] acpi PNP0A08:06: FADT indicates ASPM is unsupported, using BIOS configuration\r\n[ 4.733891] PCI host bridge to bus 0000:80\r\n[ 4.737674] pci_bus 0000:80: root bus resource [io 0xa000-0xbfff window]\r\n[ 4.745673] pci_bus 0000:80: root bus resource [mem 0xc6000000-0xd37fffff window]\r\n[ 4.753673] pci_bus 0000:80: root bus resource [mem 0x390000000000-0x393fffffffff window]\r\n[ 4.761673] pci_bus 0000:80: root bus resource [bus 80-84]\r\n[ 4.767302] ACPI: PCI Root Bridge [PC07] (domain 0000 [bus 85-ad])\r\n[ 4.773675] acpi PNP0A08:07: _OSC: OS supports [ExtendedConfig ASPM ClockPM Segments MSI]\r\n[ 4.782323] acpi PNP0A08:07: _OSC: platform does not support [SHPCHotplug AER LTR]\r\n[ 4.790066] acpi PNP0A08:07: _OSC: OS now controls [PCIeHotplug PME PCIeCapability]\r\n[ 4.797673] acpi PNP0A08:07: FADT indicates ASPM is unsupported, using BIOS configuration\r\n[ " + - delay: 16 + content: " 4.806008] PCI host bridge to bus 0000:85\r\n[ 4.809674] pci_bus 0000:85: root bus resource [io 0xc000-0xdfff window]\r\n[ 4.817673] pci_bus 0000:85: root bus resource [mem 0xd3800000-0xe0ffffff " + - delay: 32 + content: "window]\r\n[ 4.825674] pci_bus 0000:85: root bus resource [mem 0x394000000000-0x397fffffffff window]\r\n[ 4.833673] pci_bus 0000:85: root bus resource [bus 85-ad]\r\n[ 4.840649] ACPI: PCI Root Brid" + - delay: 7 + content: "ge [PC08] (domain 0000 [bus ae-d6])\r\n[ 4.849676] acpi PNP0A08:08: _OSC: OS supports [ExtendedConfig ASPM ClockPM Segments MSI]\r\n[ 4.858314] acpi PNP0A08:08: _OSC: platform does not support [SHPC" + - delay: 21 + content: "Hotplug AER LTR]\r\n[ 4.866070] acpi PNP0A08:08: _OSC: OS now controls [PCIeHotplug PME PCIeCapability]\r\n[ 4.873673] acpi PNP0A08:08: FADT indicates ASPM is unsupported, using BIOS configuration\r\n" + - delay: 13 + content: "[ 4.881962] PCI host bridge to bus 0000:ae\r\n[ 4.885673] pci_bus 0000:ae: root bus resource [io 0xe000-0xefff window]\r\n[ 4.893673] pci_bus 0000:ae: root bus resource [mem 0xe1000000-0xee7ffff" + - delay: 21 + content: "f window]\r\n[ 4.897673] pci_bus 0000:ae: root bus resource [mem 0x398000000000-0x39bfffffffff window]\r\n[ 4.909673] pci_bus 0000:ae: root bus resource [bus ae-d6]\r\n[ 4.916368] ACPI: PCI Root Br" + - delay: 16 + content: "idge [PC09] (domain 0000 [bus d7-ff])\r\n[ 4.921675] acpi PNP0A08:09: _OSC: OS supports [ExtendedConfig ASPM ClockPM Segments MSI]\r\n[ 4.930326] acpi PNP0A08:09: _OSC: platform does not support [SH" + - delay: 19 + content: "PCHotplug AER LTR]\r\n[ 4.938072] acpi PNP0A08:09: _OSC: OS now controls [PCIeHotplug PME PCIeCapability]\r\n[ 4.945673] acpi PNP0A08:09: FADT indicates ASPM is unsupported, using BIOS configuration" + - delay: 18 + content: "\r\n[ 4.953933] PCI host bridge to bus 0000:d7\r\n[ 4.957673] pci_bus 0000:d7: root bus resource [io 0xf000-0xffff window]\r\n[ 4.965673] pci_bus 0000:d7: root bus resource [mem 0xee800000-0xfbfff" + - delay: 18 + content: "fff window]\r\n[ 4.973673] pci_bus 0000:d7: root bus resource [mem 0x39c000000000-0x39ffffffffff window]\r\n[ 4.981673] pci_bus 0000:d7: root bus resource [bus d7-ff]\r\n[ 4.987710] pci 0000:d7:00." + - delay: 18 + content: "0: PCI bridge to [bus d8]\r\n[ 4.993902] pci 0000:d7:01.0: PCI bridge to [bus d9]\r\n[ 4.997721] pci 0000:d7:02.0: PCI bridge to [bus da]\r\n[ 5.005721] pci 0000:d7:03.0: PCI bridge to [bus db]\r\n[ " + - delay: 17 + content: " 5.010352] ACPI: PCI Interrupt Link [LNKA] (IRQs 3 4 5 6 7 10 *11 12 14 15), disabled.\r\n[ 5.017747] ACPI: PCI Interrupt Link [LNKB] (IRQs 3 4 5 6 7 *10 11 12 14 15), disabled.\r\n[ 5.025745] ACP" + - delay: 19 + content: "I: PCI Interrupt Link [LNKC] (IRQs 3 4 5 6 10 *11 12 14 15), disabled.\r\n[ 5.033746] ACPI: PCI Interrupt Link [LNKD] (IRQs 3 4 5 6 10 *11 12 14 15), disabled.\r\n[ 5.041746] ACPI: PCI Interrupt Lin" + - delay: 18 + content: "k [LNKE] (IRQs 3 4 5 6 7 10 *11 12 14 15), disabled.\r\n[ 5.049745] ACPI: PCI Interrupt Link [LNKF] (IRQs 3 4 5 6 7 10 *11 12 14 15), disabled.\r\n[ 5.057745] ACPI: PCI Interrupt Link [LNKG] (IRQs 3" + - delay: 17 + content: " 4 5 6 7 10 *11 12 14 15), disabled.\r\n[ 5.065746] ACPI: PCI Interrupt Link [LNKH] (IRQs 3 4 5 6 7 10 *11 12 14 15), disabled.\r\n[ 5.074268] SCSI subsystem initialized\r\n[ 5.077727] pci 0000:03:" + - delay: 17 + content: "00.0: vgaarb: setting as boot VGA device\r\n[ 5.081671] pci 0000:03:00.0: vgaarb: VGA device added: decodes=io+mem,owns=io+mem,locks=none\r\n[ 5.093733] pci 0000:03:00.0: vgaarb: bridge control poss" + - delay: 17 + content: "ible\r\n[ 5.097672] vgaarb: loaded\r\n[ 5.100401] ACPI: bus type USB registered\r\n[ 5.105687] usbcore: registered new interface driver usbfs\r\n[ 5.109680] usbcore: registered new interface drive" + - delay: 16 + content: "r hub\r\n[ 5.117757] usbcore: registered new device driver usb\r\n[ 5.121704] pps_core: LinuxPPS API ver. 1 registered\r\n[ 5.125672] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Gio" + - delay: 48 + content: "metti \r\n[ 5.137674] PTP clock support registered\r\n[ 5.141733] EDAC MC: Ver: 3.0.0\r\n[ 5.145166] Registered efivars operations\r\n[ 5.178081] PCI: Using ACPI for IRQ routing" + - delay: 20 + content: "\r\n[ 5.185978] NetLabel: Initializing\r\n[ 5.189379] NetLabel: domain hash size = 128\r\n[ 5.193672] NetLabel: protocols = UNLABELED CIPSOv4 CALIPSO\r\n[ 5.197690] NetLabel: unlabeled traffic " + - delay: 20 + content: "allowed by default\r\n[ 5.206349] hpet0: at MMIO 0xfed00000, IRQs 2, 8, 0, 0, 0, 0, 0, 0\r\n[ 5.209674] hpet0: 8 comparators, 64-bit 24.000000 MHz counter\r\n[ 5.219801] clocksource: Switched to cl" + - delay: 33 + content: "ocksource tsc-early\r\n[ 5.237787] VFS: Disk quotas dquot_6.6.0\r\n[ 5.241742] VFS: Dquot-cache hash table entries: 512 (order 0, 4096 bytes)\r\n[ 5.248798] AppArmor: AppArmor Filesystem Enabled\r\n[" + - delay: 18 + content: " 5.253526] pnp: PnP ACPI init\r\n[ 5.257534] system 00:01: [io 0x0500-0x05fe] has been reserved\r\n[ 5.263460] system 00:01: [io 0x0400-0x047f] has been reserved\r\n[ 5.269376] system 00:01: [" + - delay: 18 + content: "io 0x0600-0x061f] has been reserved\r\n[ 5.275296] system 00:01: [io 0x0880-0x0883] has been reserved\r\n[ 5.281215] system 00:01: [io 0x0800-0x081f] could not be reserved\r\n[ 5.287482] system " + - delay: 17 + content: "00:01: [mem 0xfed1c000-0xfed3ffff] could not be reserved\r\n[ 5.294438] system 00:01: [mem 0xfed45000-0xfed8bfff] has been reserved\r\n[ 5.301054] system 00:01: [mem 0xff000000-0xffffffff] has been " + - delay: 17 + content: "reserved\r\n[ 5.307665] system 00:01: [mem 0xfee00000-0xfeefffff] has been reserved\r\n[ 5.314277] system 00:01: [mem 0xfed12000-0xfed1200f] has been reserved\r\n[ 5.320889] system 00:01: [mem 0xfe" + - delay: 18 + content: "d12010-0xfed1201f] has been reserved\r\n[ 5.327504] system 00:01: [mem 0xfed1b000-0xfed1bfff] has been reserved\r\n[ 5.334664] system 00:02: [io 0x0a00-0x0a0f] has been reserved\r\n[ 5.340583] sys" + - delay: 20 + content: "tem 00:02: [io 0x0a10-0x0a1f] has been reserved\r\n[ 5.346500] system 00:02: [io 0x0a20-0x0a2f] has been reserved\r\n[ 5.352421] system 00:02: [io 0x0a30-0x0a3f] has been reserved\r\n[ 5.358340]" + - delay: 17 + content: " system 00:02: [io 0x0a40-0x0a4f] has been reserved\r\n[ 5.365336] system 00:05: [mem 0xfd000000-0xfdabffff] has been reserved\r\n[ 5.371948] system 00:05: [mem 0xfdad0000-0xfdadffff] has been rese" + - delay: 17 + content: "rved\r\n[ 5.378557] system 00:05: [mem 0xfdb00000-0xfdffffff] has been reserved\r\n[ 5.385173] system 00:05: [mem 0xfe000000-0xfe00ffff] has been reserved\r\n[ 5.391784] system 00:05: [mem 0xfe0110" + - delay: 19 + content: "00-0xfe01ffff] has been reserved\r\n[ 5.398397] system 00:05: [mem 0xfe036000-0xfe03bfff] has been reserved\r\n[ 5.405011] system 00:05: [mem 0xfe03d000-0xfe3fffff] has been reserved\r\n[ 5.411623]" + - delay: 22 + content: " system 00:05: [mem 0xfe410000-0xfe7fffff] has been reserved\r\n[ 5.418622] system 00:06: [io 0x0f00-0x0ffe] has been reserved\r\n[ 5.425923] pnp: PnP ACPI: found 7 devices\r\n[ 5.435903] clocksou" + - delay: 18 + content: "rce: acpi_pm: mask: 0xffffff max_cycles: 0xffffff, max_idle_ns: 2085701024 ns\r\n[ 5.444809] pci 0000:00:1c.0: PCI bridge to [bus 01]\r\n[ 5.449775] pci 0000:00:1c.0: bridge window [io 0x1000-0x1" + - delay: 17 + content: "fff]\r\n[ 5.455868] pci 0000:00:1c.0: bridge window [mem 0x90000000-0x901fffff]\r\n[ 5.462653] pci 0000:00:1c.0: bridge window [mem 0x380000000000-0x3800001fffff 64bit pref]\r\n[ 5.471089] pci " + - delay: 18 + content: "0000:02:00.0: PCI bridge to [bus 03]\r\n[ 5.476052] pci 0000:02:00.0: bridge window [io 0x3000-0x3fff]\r\n[ 5.482148] pci 0000:02:00.0: bridge window [mem 0x9c000000-0x9d0fffff]\r\n[ 5.488937]" + - delay: 16 + content: " pci 0000:00:1c.5: PCI bridge to [bus 02-03]\r\n[ 5.494166] pci 0000:00:1c.5: bridge window [io 0x3000-0x3fff]\r\n[ 5.500258] pci 0000:00:1c.5: bridge window [mem 0x9c000000-0x9d0fffff]\r\n[ 5" + - delay: 17 + content: ".507213] pci 0000:18:00.0: BAR 7: no space for [mem size 0x00400000 64bit pref]\r\n[ 5.514775] pci 0000:18:00.0: BAR 7: failed to assign [mem size 0x00400000 64bit pref]\r\n[ 5.522690] pci 0000:18:0" + - delay: 17 + content: "0.1: BAR 7: no space for [mem size 0x00400000 64bit pref]\r\n[ 5.530251] pci 0000:18:00.1: BAR 7: failed to assign [mem size 0x00400000 64bit pref]\r\n[ 5.538165] pci 0000:18:00.0: BAR 10: no space " + - delay: 21 + content: "for [mem size 0x00100000 64bit pref]\r\n[ 5.545818] pci 0000:18:00.0: BAR 10: failed to assign [mem size 0x00100000 64bit pref]\r\n[ 5.553821] pci 0000:18:00.1: BAR 10: no space for [mem size 0x0010" + - delay: 14 + content: "0000 64bit pref]\r\n[ 5.561472] pci 0000:18:00.1: BAR 10: failed to assign [mem size 0x00100000 64bit pref]\r\n[ 5.569471] pci 0000:17:00.0: PCI bridge to [bus 18]\r\n[ 5.574439] pci 0000:17:00.0: " + - delay: 17 + content: " bridge window [mem 0xaae00000-0xaaefffff]\r\n[ 5.581222] pci 0000:17:00.0: bridge window [mem 0xa8000000-0xaa0fffff 64bit pref]\r\n[ 5.588969] pci 0000:17:00.0: PCI bridge to [bus 18]\r\n[ 5.59" + - delay: 20 + content: "3948] pci 0000:17:00.0: BAR 15: assigned [mem 0x384000000000-0x384002ffffff 64bit pref]\r\n[ 5.602469] pci 0000:18:00.0: BAR 0: assigned [mem 0x384000000000-0x384000ffffff 64bit pref]\r\n[ 5.610902]" + - delay: 17 + content: " pci 0000:18:00.1: BAR 0: assigned [mem 0x384001000000-0x384001ffffff 64bit pref]\r\n[ 5.619334] pci 0000:18:00.0: BAR 7: assigned [mem 0x384002000000-0x3840023fffff 64bit pref]\r\n[ 5.627765] pci 0" + - delay: 16 + content: "000:18:00.1: BAR 7: assigned [mem 0x384002400000-0x3840027fffff 64bit pref]\r\n[ 5.636198] pci 0000:18:00.0: BAR 3: assigned [mem 0x384002800000-0x384002807fff 64bit pref]\r\n[ 5.644633] pci 0000:18" + - delay: 17 + content: ":00.1: BAR 3: assigned [mem 0x384002808000-0x38400280ffff 64bit pref]\r\n[ 5.653065] pci 0000:18:00.0: BAR 10: assigned [mem 0x384002810000-0x38400290ffff 64bit pref]\r\n[ 5.661583] pci 0000:18:00.1" + - delay: 17 + content: ": BAR 10: assigned [mem 0x384002910000-0x384002a0ffff 64bit pref]\r\n[ 5.670103] pci 0000:17:00.0: PCI bridge to [bus 18]\r\n[ 5.675068] pci 0000:17:00.0: bridge window [mem 0xaae00000-0xaaefffff]" + - delay: 17 + content: "\r\n[ 5.681852] pci 0000:17:00.0: bridge window [mem 0x384000000000-0x384002ffffff 64bit pref]\r\n[ 5.690330] pci 0000:3a:00.0: BAR 15: assigned [mem 0x388000000000-0x3880000fffff 64bit pref]\r\n[ " + - delay: 17 + content: " 5.698857] pci 0000:3b:00.0: BAR 7: assigned [mem 0x388000000000-0x38800001ffff 64bit pref]\r\n[ 5.707292] pci 0000:3b:00.0: BAR 10: assigned [mem 0x388000020000-0x38800003ffff 64bit pref]\r\n[ 5.7" + - delay: 18 + content: "15812] pci 0000:3b:00.1: BAR 7: assigned [mem 0x388000040000-0x38800005ffff 64bit pref]\r\n[ 5.724243] pci 0000:3b:00.1: BAR 10: assigned [mem 0x388000060000-0x38800007ffff 64bit pref]\r\n[ 5.732763" + - delay: 17 + content: "] pci 0000:3b:00.2: BAR 7: assigned [mem 0x388000080000-0x38800009ffff 64bit pref]\r\n[ 5.741194] pci 0000:3b:00.2: BAR 10: assigned [mem 0x3880000a0000-0x3880000bffff 64bit pref]\r\n[ 5.749715] pci" + - delay: 17 + content: " 0000:3b:00.3: BAR 7: assigned [mem 0x3880000c0000-0x3880000dffff 64bit pref]\r\n[ 5.758148] pci 0000:3b:00.3: BAR 10: assigned [mem 0x3880000e0000-0x3880000fffff 64bit pref]\r\n[ 5.766665] pci 0000" + - delay: 17 + content: ":3a:00.0: PCI bridge to [bus 3b]\r\n[ 5.771632] pci 0000:3a:00.0: bridge window [io 0x7000-0x7fff]\r\n[ 5.777725] pci 0000:3a:00.0: bridge window [mem 0xb8000000-0xb86fffff]\r\n[ 5.784510] pci" + - delay: 18 + content: " 0000:3a:00.0: bridge window [mem 0x388000000000-0x3880000fffff 64bit pref]\r\n[ 5.793092] pci 0000:d7:00.0: BAR 13: no space for [io size 0x1000]\r\n[ 5.799444] pci 0000:d7:00.0: BAR 13: failed " + - delay: 18 + content: "to assign [io size 0x1000]\r\n[ 5.806144] pci 0000:d7:01.0: BAR 13: no space for [io size 0x1000]\r\n[ 5.812495] pci 0000:d7:01.0: BAR 13: failed to assign [io size 0x1000]\r\n[ 5.819193] pci 00" + - delay: 17 + content: "00:d7:02.0: BAR 13: no space for [io size 0x1000]\r\n[ 5.825546] pci 0000:d7:02.0: BAR 13: failed to assign [io size 0x1000]\r\n[ 5.832248] pci 0000:d7:02.0: BAR 13: no space for [io size 0x1000]" + - delay: 17 + content: "\r\n[ 5.838599] pci 0000:d7:02.0: BAR 13: failed to assign [io size 0x1000]\r\n[ 5.845297] pci 0000:d7:01.0: BAR 13: no space for [io size 0x1000]\r\n[ 5.851650] pci 0000:d7:01.0: BAR 13: failed " + - delay: 18 + content: "to assign [io size 0x1000]\r\n[ 5.858349] pci 0000:d7:00.0: BAR 13: no space for [io size 0x1000]\r\n[ 5.864704] pci 0000:d7:00.0: BAR 13: failed to assign [io size 0x1000]\r\n[ 5.871402] pci 00" + - delay: 17 + content: "00:d7:00.0: PCI bridge to [bus d8]\r\n[ 5.876370] pci 0000:d7:00.0: bridge window [mem 0xfbe00000-0xfbefffff]\r\n[ 5.883156] pci 0000:d7:00.0: bridge window [mem 0x39c000000000-0x39c0001fffff 64" + - delay: 18 + content: "bit pref]\r\n[ 5.891591] pci 0000:d7:01.0: PCI bridge to [bus d9]\r\n[ 5.896556] pci 0000:d7:01.0: bridge window [mem 0xfbd00000-0xfbdfffff]\r\n[ 5.903342] pci 0000:d7:01.0: bridge window [mem " + - delay: 17 + content: "0x39c000200000-0x39c0003fffff 64bit pref]\r\n[ 5.911774] pci 0000:d7:02.0: PCI bridge to [bus da]\r\n[ 5.916739] pci 0000:d7:02.0: bridge window [mem 0xee800000-0xee9fffff]\r\n[ 5.923525] pci 000" + - delay: 18 + content: "0:d7:02.0: bridge window [mem 0x39c000400000-0x39c0005fffff 64bit pref]\r\n[ 5.931961] pci 0000:d7:03.0: PCI bridge to [bus db]\r\n[ 5.936922] pci 0000:d7:03.0: bridge window [io 0xf000-0xffff]" + - delay: 17 + content: "\r\n[ 5.943018] pci 0000:d7:03.0: bridge window [mem 0xeea00000-0xeebfffff]\r\n[ 5.949803] pci 0000:d7:03.0: bridge window [mem 0x39c000600000-0x39c0007fffff 64bit pref]\r\n[ 5.958332] NET: Reg" + - delay: 18 + content: "istered protocol family 2\r\n[ 5.962963] tcp_listen_portaddr_hash hash table entries: 65536 (order: 8, 1048576 bytes)\r\n[ 5.971329] TCP established hash table entries: 524288 (order: 10, 4194304 by" + - delay: 19 + content: "tes)\r\n[ 5.979438] TCP bind hash table entries: 65536 (order: 8, 1048576 bytes)\r\n[ 5.986272] TCP: Hash tables configured (established 524288 bind 65536)\r\n[ 5.993046] UDP hash table entries: 65" + - delay: 18 + content: "536 (order: 9, 2097152 bytes)\r\n[ 5.999669] UDP-Lite hash table entries: 65536 (order: 9, 2097152 bytes)\r\n[ 6.006845] NET: Registered protocol family 1\r\n[ 6.011213] NET: Registered protocol fa" + - delay: 97 + content: "mily 44\r\n[ 6.016016] pci 0000:03:00.0: Video device with shadowed ROM at [mem 0x000c0000-0x000dffff]\r\n[ 6.024589] Unpacking initramfs...\r\n" + - delay: 703 + content: "[ 6.687375] Freeing initrd memory: 39540K\r\n[ 6.705699] PCI-DMA: Using software bounce buffering for IO (SWIOTLB)\r\n[ 6.712145] software IO TLB: mapped [mem 0x62987000-0x66987000] (64MB)\r\n[ 6.720785] check: Scanning for low memory corruption every 60 seconds\r\n[ 6.730013] Initialise system trusted keyrings\r\n[ 6.734466] Key type blacklist registered\r\n[ 6.738533] workingset: timestamp_bits=36 max_order=25 bucket_order=0\r\n[ 6.746393] zbud: loaded\r\n[ 6.749550] squashfs: version 4.0 (2009/01/31) Phillip Lougher\r\n[ 6.755600] fuse init (API version 7.28)\r\n[ 6.797131] Key type asymmetric registered\r\n[ 6.801229] Asymmetric key parser 'x509' registered\r\n[ 6.80" + - delay: 6 + content: "6112] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 243)\r\n[ 6.813580] io scheduler mq-deadline registered\r\n[ 6.818990] pcieport 0000:00:1c.0: Signaling PME with IRQ 24\r\n[ 6." + - delay: 17 + content: "824681] pciehp 0000:00:1c.0:pcie004: Slot #0 AttnBtn- PwrCtrl- MRL- AttnInd- PwrInd- HotPlug+ Surprise+ Interlock- NoCompl+ LLActRep+\r\n[ 6.837267] pcieport 0000:00:1c.5: Signaling PME with IRQ 25\r\n" + - delay: 17 + content: "[ 6.843219] pcieport 0000:17:00.0: Signaling PME with IRQ 27\r\n[ 6.849100] pcieport 0000:3a:00.0: Signaling PME with IRQ 29\r\n[ 6.855150] pcieport 0000:d7:00.0: Signaling PME with IRQ 31\r\n[ " + - delay: 16 + content: "6.860845] pciehp 0000:d7:00.0:pcie004: Slot #14 AttnBtn+ PwrCtrl+ MRL- AttnInd+ PwrInd+ HotPlug+ Surprise- Interlock- NoCompl- LLActRep+ (with Cmd Compl erratum)\r\n[ 6.875717] pcieport 0000:d7:01.0:" + - delay: 18 + content: " Signaling PME with IRQ 32\r\n[ 6.881407] pciehp 0000:d7:01.0:pcie004: Slot #15 AttnBtn+ PwrCtrl+ MRL- AttnInd+ PwrInd+ HotPlug+ Surprise- Interlock- NoCompl- LLActRep+ (with Cmd Compl erratum)\r\n[ " + - delay: 17 + content: " 6.896257] pcieport 0000:d7:02.0: Signaling PME with IRQ 33\r\n[ 6.901938] pciehp 0000:d7:02.0:pcie004: Slot #16 AttnBtn+ PwrCtrl+ MRL- AttnInd+ PwrInd+ HotPlug+ Surprise- Interlock- NoCompl- LLActRe" + - delay: 19 + content: "p+ (with Cmd Compl erratum)\r\n[ 6.916766] pcieport 0000:d7:03.0: Signaling PME with IRQ 34\r\n[ 6.922445] pciehp 0000:d7:03.0:pcie004: Slot #17 AttnBtn+ PwrCtrl+ MRL- AttnInd+ PwrInd+ HotPlug+ Surp" + - delay: 19 + content: "rise- Interlock- NoCompl- LLActRep+ (with Cmd Compl erratum)\r\n[ 6.937185] shpchp: Standard Hot Plug PCI Controller Driver version: 0.4\r\n[ 6.943999] efifb: probing for efifb\r\n[ 6.947601] efifb" + - delay: 16 + content: ": framebuffer at 0x9c000000, using 3072k, total 3072k\r\n[ 6.954125] efifb: mode is 1024x768x32, linelength=4096, pages=1\r\n[ 6.960130] efifb: scrolling: redraw\r\n[ 6.963711] efifb: Truecolor: si" + - delay: 36 + content: "ze=8:8:8:8, shift=24:16:8:0\r\n[ 6.977695] Console: switching to colour frame buffer device 128x48\r\n[ 6.992268] fb0: EFI VGA frame buffer device\r\n[ 6.998232] input: Power Button as /devices/LNX" + - delay: 18 + content: "SYSTM:00/LNXPWRBN:00/input/input0\r\n[ 7.005641] ACPI: Power Button [PWRF]\r\n[ 7.011136] ERST: Error Record Serialization Table (ERST) support is initialized.\r\n[ 7.018616] pstore: Registered ers" + - delay: 41 + content: "t as persistent store backend\r\n[ 7.025193] GHES: APEI firmware first mode is enabled by APEI bit and WHEA _OSC.\r\n[ 7.032783] Serial: 8250/16550 driver, 32 ports, IRQ sharing enabled\r\n[ 7.0600" + - delay: 41 + content: "84] 00:03: ttyS0 at I/O 0x3f8 (irq = 4, base_baud = 115200) is a 16550A\r\n�[ 7.088405] 00:04: ttyS1 at I/O 0x2f8 (irq = 3, base_baud = 115200) is a 16550A\r\n[ 7.097421] Linux agpgart interface v0." + - delay: 24 + content: "103\r\n[ 7.109834] loop: module loaded\r\n[ 7.113339] libphy: Fixed MDIO Bus: probed\r\n[ 7.117438] tun: Universal TUN/TAP device driver, 1.6\r\n[ 7.122522] PPP generic driver version 2.4.2\r\n[ " + - delay: 17 + content: "7.126868] ehci_hcd: USB 2.0 'Enhanced' Host Controller (EHCI) Driver\r\n[ 7.133394] ehci-pci: EHCI PCI platform driver\r\n[ 7.137871] ehci-platform: EHCI generic platform driver\r\n[ 7.143106] ohci" + - delay: 18 + content: "_hcd: USB 1.1 'Open' Host Controller (OHCI) Driver\r\n[ 7.149288] ohci-pci: OHCI PCI platform driver\r\n[ 7.153762] ohci-platform: OHCI generic platform driver\r\n[ 7.158988] uhci_hcd: USB Universa" + - delay: 19 + content: "l Host Controller Interface driver\r\n[ 7.165634] xhci_hcd 0000:00:14.0: xHCI Host Controller\r\n[ 7.170879] xhci_hcd 0000:00:14.0: new USB bus registered, assigned bus number 1\r\n[ 7.179379] xhci" + - delay: 17 + content: "_hcd 0000:00:14.0: hcc params 0x200077c1 hci version 0x100 quirks 0x0000000000009810\r\n[ 7.188727] usb usb1: New USB device found, idVendor=1d6b, idProduct=0002, bcdDevice= 5.00\r\n[ 7.196993] usb " + - delay: 18 + content: "usb1: New USB device strings: Mfr=3, Product=2, SerialNumber=1\r\n[ 7.204216] usb usb1: Product: xHCI Host Controller\r\n[ 7.209092] usb usb1: Manufacturer: Linux 5.0.0-29-generic xhci-hcd\r\n[ 7.2" + - delay: 20 + content: "15360] usb usb1: SerialNumber: 0000:00:14.0\r\n[ 7.220119] hub 1-0:1.0: USB hub found\r\n[ 7.223890] hub 1-0:1.0: 16 ports detected\r\n[ 7.229921] xhci_hcd 0000:00:14.0: xHCI Host Controller\r\n[ " + - delay: 17 + content: "7.235158] xhci_hcd 0000:00:14.0: new USB bus registered, assigned bus number 2\r\n[ 7.242552] xhci_hcd 0000:00:14.0: Host supports USB 3.0 SuperSpeed\r\n[ 7.248935] usb usb2: New USB device found, " + - delay: 18 + content: "idVendor=1d6b, idProduct=0003, bcdDevice= 5.00\r\n[ 7.257196] usb usb2: New USB device strings: Mfr=3, Product=2, SerialNumber=1\r\n[ 7.264413] usb usb2: Product: xHCI Host Controller\r\n[ 7.269295" + - delay: 18 + content: "] usb usb2: Manufacturer: Linux 5.0.0-29-generic xhci-hcd\r\n[ 7.275560] usb usb2: SerialNumber: 0000:00:14.0\r\n[ 7.280318] hub 2-0:1.0: USB hub found\r\n[ 7.284087] hub 2-0:1.0: 10 ports detected" + - delay: 18 + content: "\r\n[ 7.288631] usb: port power management may be unreliable\r\n[ 7.294766] i8042: PNP: No PS/2 controller found.\r\n[ 7.299573] mousedev: PS/2 mouse device common for all mice\r\n[ 7.305280] rtc_" + - delay: 18 + content: "cmos 00:00: RTC can wake from S4\r\n[ 7.310174] rtc_cmos 00:00: registered as rtc0\r\n[ 7.314639] rtc_cmos 00:00: alarms up to one month, y3k, 114 bytes nvram, hpet irqs\r\n[ 7.322299] i2c /dev ent" + - delay: 18 + content: "ries driver\r\n[ 7.325894] device-mapper: uevent: version 1.0.3\r\n[ 7.330612] device-mapper: ioctl: 4.39.0-ioctl (2018-04-03) initialised: dm-devel@redhat.com\r\n[ 7.339066] platform eisa.0: Probi" + - delay: 17 + content: "ng EISA bus 0\r\n[ 7.343595] platform eisa.0: EISA: Cannot allocate resource for mainboard\r\n[ 7.350380] platform eisa.0: Cannot allocate resource for EISA slot 1\r\n[ 7.356818] platform eisa.0: C" + - delay: 16 + content: "annot allocate resource for EISA slot 2\r\n[ 7.363259] platform eisa.0: Cannot allocate resource for EISA slot 3\r\n[ 7.369700] platform eisa.0: Cannot allocate resource for EISA slot 4\r\n[ 7.3761" + - delay: 18 + content: "40] platform eisa.0: Cannot allocate resource for EISA slot 5\r\n[ 7.382578] platform eisa.0: Cannot allocate resource for EISA slot 6\r\n[ 7.389017] platform eisa.0: Cannot allocate resource for EI" + - delay: 17 + content: "SA slot 7\r\n[ 7.395455] platform eisa.0: Cannot allocate resource for EISA slot 8\r\n[ 7.401898] platform eisa.0: EISA: Detected 0 cards\r\n[ 7.406782] intel_pstate: Intel P-state driver initializ" + - delay: 58 + content: "ing\r\n[ 7.414138] ledtrig-cpu: registered to indicate activity on CPUs\r\n[ 7.420156] EFI Variables Facility v0.08 2004-May-17\r\n[ 7.456893] NET: Registered protocol family 10\r\n[ 7.466942] Seg" + - delay: 20 + content: "ment Routing with IPv6\r\n[ 7.470623] NET: Registered protocol family 17\r\n[ 7.475172] Key type dns_resolver registered\r\n[ 7.482943] mce: Using 20 MCE banks\r\n[ 7.486451] RAS: Correctable Erro" + - delay: 19 + content: "rs collector initialized.\r\n[ 7.491974] microcode: sig=0x50654, pf=0x1, revision=0x200005e\r\n[ 7.498680] microcode: Microcode Update Driver: v2.2.\r\n[ 7.499422] resctrl: MB allocation detected\r\n" + - delay: 21 + content: "[ 7.508678] sched_clock: Marking stable (5595538715, 1913129182)->(7734937668, -226269771)\r\n[ 7.517302] registered taskstats version 1\r\n[ 7.521413] Loading compiled-in X.509 certificates\r\n[ " + - delay: 17 + content: " 7.527904] Loaded X.509 cert 'Build time autogenerated kernel key: 6e89d8a3d3920a6f950c788ca6fb1453f5bbea64'\r\n[ 7.539199] Couldn't get size: 0x800000000000000e\r\n[ 7.543900] MODSIGN: Couldn't ge" + - delay: 18 + content: "t UEFI db list\r\n[ 7.549101] Couldn't get size: 0x800000000000000e\r\n[ 7.553807] MODSIGN: Couldn't get UEFI MokListRT\r\n[ 7.559199] Couldn't get size: 0x800000000000000e\r\n[ 7.563906] MODSIGN:" + - delay: 18 + content: " Couldn't get UEFI dbx list\r\n[ 7.565720] usb 1-7: new high-speed USB device number 2 using xhci_hcd\r\n[ 7.568476] zswap: loaded using pool lzo/zbud\r\n[ 7.579649] pstore: Using crash dump compre" + - delay: 25 + content: "ssion: deflate\r\n[ 7.590269] Key type big_key registered\r\n[ 7.594111] Key type trusted registered\r\n[ 7.600476] Key type encrypted registered\r\n[ 7.604492] AppArmor: AppArmor sha1 policy hash" + - delay: 19 + content: "ing enabled\r\n[ 7.612683] ima: No TPM chip found, activating TPM-bypass!\r\n[ 7.618170] ima: Allocated hash algorithm: sha1\r\n[ 7.622703] No architecture policies found\r\n[ 7.626808] evm: Initi" + - delay: 17 + content: "alising EVM extended attributes:\r\n[ 7.631946] evm: security.selinux\r\n[ 7.635267] evm: security.SMACK64\r\n[ 7.638583] evm: security.SMACK64EXEC\r\n[ 7.642252] evm: security.SMACK64TRANSMUTE\r\n[" + - delay: 19 + content: " 7.646351] evm: security.SMACK64MMAP\r\n[ 7.650017] evm: security.apparmor\r\n[ 7.653418] evm: security.ima\r\n[ 7.656387] evm: security.capability\r\n[ 7.659966] evm: HMAC attrs: 0x1\r\n[ 7.6" + - delay: 20 + content: "64757] Magic number: 3:106:785\r\n[ 7.668508] pci 0000:ae:0a.7: hash matches\r\n[ 7.672728] acpi LNXCPU:6f: hash matches\r\n[ 7.676806] rtc_cmos 00:00: setting system clock to 2019-09-21T12:45:19" + - delay: 36 + content: " UTC (1569069919)\r\n[ 7.687931] Freeing unused decrypted memory: 2040K\r\n[ 7.693449] Freeing unused kernel image memory: 2576K\r\n[ 7.713756] Write protecting the kernel read-only data: 22528k\r\n[" + - delay: 17 + content: " 7.720337] Freeing unused kernel image memory: 2016K\r\n[ 7.722294] usb 1-7: New USB device found, idVendor=0557, idProduct=7000, bcdDevice= 0.00\r\n[ 7.733568] usb 1-7: New USB device strings: M" + - delay: 17 + content: "fr=0, Product=0, SerialNumber=0\r\n[ 7.741220] Freeing unused kernel image memory: 1840K\r\n[ 7.741241] hub 1-7:1.0: USB hub found\r\n[ 7.746318] tsc: Refined TSC clocksource calibration: 2099.999 " + - delay: 18 + content: "MHz\r\n[ 7.750206] hub 1-7:1.0: 4 ports detected\r\n[ 7.756219] clocksource: tsc: mask: 0xffffffffffffffff max_cycles: 0x1e452fc488e, max_idle_ns: 440795307124 ns\r\n[ 7.769273] x86/mm: Checked W+X" + - delay: 24 + content: " mappings: passed, no W+X pages found.\r\n[ 7.776647] x86/mm: Checking user space page tables\r\n[ 7.781547] clocksource: Switched to clocksource tsc\r\n[ 7.792960] x86/mm: Checked W+X mappings: pa" + - delay: 94 + content: "ssed, no W+X pages found.\r\n[ 7.799399] Run /init as init process\r\nLoading, please wait...\r\nStarting version 240\r\n" + - delay: 152 + content: "[ 7.963258] lpc_ich 0000:00:1f.0: I/O Disable is set\r\n[ 7.987413] dca service started, version 1.12.1\r\n[ 7.987421] i801_smbus 0000:00:1f.4: SMBus using PCI interrupt\r\n[ 7.987684] i40e: Intel(R) Ethernet Connection XL710 Network Driver - version 2.7.6-k\r\n[ 7.987685] i40e: Copyright (c) 2013 - 2014 Intel Corporation.\r\n[ 8.011881] ahci 0000:00:11.5: AHCI 0001.0301 32 slots 6 ports 6" + - delay: 7 + content: " Gbps 0x3f impl SATA mode\r\n[ 8.020061] ahci 0000:00:11.5: flags: 64bit ncq sntf led clo only pio slum part ems deso sadm sds apst \r\n[ 8.045483] i40e 0000:18:00.0: fw 6.0.48442 api 1.7 nvm 6.01 0" + - delay: 20 + content: "x8000349f 1.1747.0\r\n[ 8.053834] nvme nvme0: pci function 0000:d8:00.0\r\n[ 8.058713] nvme nvme1: pci function 0000:d9:00.0\r\n[ 8.058851] igb: Intel(R) Gigabit Ethernet Network Driver - version 5" + - delay: 177 + content: ".4.0-k\r\n[ 8.065720] usb 1-7.1: new low-speed USB device number 3 using xhci_hcd\r\n[ 8.070384] igb: Copyright (c) 2007-2014 Intel Corporation.\r\n[ 8.210389] usb 1-7.1: New USB device found, idVendor=0557, idProduct=2419, bcdDevice= 1.00\r\n[ 8.218743] usb 1-7.1: New USB device strings: Mfr=0, Product=0, SerialNumber=0\r\n[ 8.233570] hidra" + - delay: 10 + content: "w: raw HID events driver (C) Jiri Kosina\r\n[ 8.242214] usbcore: registered new interface driver usbhid\r\n[ 8.247792] usbhid: USB HID core driver\r\n[ 8.253449] iHID 0557:2419 as /devices/pci0000:" + - delay: 44 + content: "00/0000:00:14.0/usb1/1-7/1-7.1/1-7.1:1.0/0003:0557:2419.0001/input/input1\r\n[ 8.289716] i40e 0000:18:00.0: MAC address: ac:1f:6b:7a:eb:76\r\n[ 8.296698] i40e 0000:18:00.0: FW LLDP disabled for this" + - delay: 28 + content: " PF.\r\n[ 8.302360] i40e 0000:18:00.0: DCB init failed -53, disabled\r\n[ 8.317967] i40e 0000:18:00.0 eth0: NIC Link is Up, 25 Gbps Full Duplex, Requested FEC: None, FEC: None, Autoneg: False, Flow " + - delay: 17 + content: "Control: None\r\n[ 8.321877] hid-generic 0003:0557:2419.0001: input,hidraw0: USB HID v1.00 Keyboard [HID 0557:2419] on usb-0000:00:14.0-7.1/input0\r\n[ 8.341355] i40e 0000:18:00.0: PCI-Express: Spee" + - delay: 17 + content: "d 8.0GT/s Width x8\r\n[ 8.342267] input: HID 0557:2419 as /devices/pci0000:00/0000:00:14.0/usb1/1-7/1-7.1/1-7.1:1.1/0003:0557:2419.0002/input/input2\r\n[ 8.359842] hid-generic 0003:0557:2419.0002: i" + - delay: 22 + content: "nput,hidraw1: USB HID v1.00 Mouse [HID 0557:2419] on usb-0000:00:14.0-7.1/input1\r\n[ 8.362175] scsi host0: ahci\r\n[ 8.379352] i40e 0000:18:00.0: Features: PF-id[0] VFs: 64 VSIs: 66 QP: 32 RSS FD_A" + - delay: 22 + content: "TR FD_SB NTUPLE VxLAN Geneve PTP VEPA\r\n[ 8.390450] scsi host1: ahci\r\n[ 8.394190] scsi host2: ahci\r\n[ 8.398526] scsi host3: ahci\r\n[ 8.401629] scsi host4: ahci\r\n[ 8.404730] scsi host5: ah" + - delay: 20 + content: "ci\r\n[ 8.410455] i40e 0000:18:00.1: fw 6.0.48442 api 1.7 nvm 6.01 0x8000349f 1.1747.0\r\n[ 8.418602] ata1: SATA max UDMA/133 abar m524288@0x9d180000 port 0x9d180100 irq 36\r\n[ 8.426180] ata2: SAT" + - delay: 17 + content: "A max UDMA/133 abar m524288@0x9d180000 port 0x9d180180 irq 36\r\n[ 8.433746] ata3: SATA max UDMA/133 abar m524288@0x9d180000 port 0x9d180200 irq 36\r\n[ 8.441310] ata4: SATA max UDMA/133 abar m52428" + - delay: 18 + content: "8@0x9d180000 port 0x9d180280 irq 36\r\n[ 8.448876] ata5: SATA max UDMA/133 abar m524288@0x9d180000 port 0x9d180300 irq 36\r\n[ 8.456442] ata6: SATA max UDMA/133 abar m524288@0x9d180000 port 0x9d1803" + - delay: 18 + content: "80 irq 36\r\n[ 8.464022] igb 0000:3b:00.0: added PHC on eth1\r\n[ 8.468562] igb 0000:3b:00.0: Intel(R) Gigabit Ethernet Network Connection\r\n[ 8.475431] igb 0000:3b:00.0: eth1: (PCIe:5.0Gb/s:Width" + - delay: 99 + content: " x4) ac:1f:6b:94:ca:70\r\n[ 8.482637] igb 0000:3b:00.0: eth1: PBA No: 020C00-000\r\n[ 8.487774] igb 0000:3b:00.0: Using MSI-X interrupts. 8 rx queue(s), 8 tx queue(s)\r\n" + - delay: 179 + content: "[ 8.729693] i40e 0000:18:00.1: MAC address: ac:1f:6b:7a:eb:77\r\n[ 8.736670] i40e 0000:18:00.1: FW LLDP disabled for this PF.\r\n[ 8.742326] i40e 0000:18:00.1: DCB init failed -53, disabled\r\n[ " + - delay: 22 + content: " 8.757815] i40e 0000:18:00.1 eth2: NIC Link is Up, 25 Gbps Full Duplex, Requested FEC: None, FEC: None, Autoneg: False, Flow Control: None\r\n[ 8.776592] ata4: SATA link down (SStatus 0 SControl 300)" + - delay: 20 + content: "\r\n[ 8.781125] i40e 0000:18:00.1: PCI-Express: Speed 8.0GT/s Width x8\r\n[ 8.782037] ata6: SATA link down (SStatus 0 SControl 300)\r\n[ 8.793587] ata3: SATA link down (SStatus 0 SControl 300)\r\n[ " + - delay: 15 + content: " 8.799007] ata1: SATA link down (SStatus 0 SControl 300)\r\n[ 8.804420] ata2: SATA link down (SStatus 0 SControl 300)\r\n[ 8.806385] i40e 0000:18:00.1: Features: PF-id[1] VFs: 64 VSIs: 66 QP: 32 RS" + - delay: 19 + content: "S FD_ATR FD_SB NTUPLE VxLAN Geneve PTP VEPA\r\n[ 8.809860] ata5: SATA link down (SStatus 0 SControl 300)\r\n[ 8.821013] ahci 0000:00:17.0: AHCI 0001.0301 32 slots 8 ports 6 Gbps 0xff impl SATA mode\r" + - delay: 35 + content: "\n[ 8.834174] ahci 0000:00:17.0: flags: 64bit ncq sntf led clo only pio slum part ems deso sadm sds apst \r\n[ 8.862456] igb 0000:3b:00.1: added PHC on eth3\r\n[ 8.867006] igb 0000:3b:00.1: Intel(" + - delay: 17 + content: "R) Gigabit Ethernet Network Connection\r\n[ 8.873895] igb 0000:3b:00.1: eth3: (PCIe:5.0Gb/s:Width x4) ac:1f:6b:94:ca:71\r\n[ 8.881113] igb 0000:3b:00.1: eth3: PBA No: 020C00-000\r\n[ 8.886265] igb " + - delay: 77 + content: "0000:3b:00.1: Using MSI-X interrupts. 8 rx queue(s), 8 tx queue(s)\r\n[ 8.952781] igb 0000:3b:00.2: added PHC on eth4\r\n[ 8.957321] igb 0000:3b:00.2: Intel(R) Gigabit Ethernet Network Connection\r\n[" + - delay: 16 + content: " 8.964197] igb 0000:3b:00.2: eth4: (PCIe:5.0Gb/s:Width x4) ac:1f:6b:94:ca:72\r\n[ 8.971403] igb 0000:3b:00.2: eth4: PBA No: 020C00-000\r\n[ 8.976544] igb 0000:3b:00.2: Using MSI-X interrupts. 8 r" + - delay: 21 + content: "x queue(s), 8 tx queue(s)\r\n[ 8.985601] scsi host6: ahci\r\n[ 8.988903] scsi host7: ahci\r\n[ 8.992051] scsi host8: ahci\r\n[ 8.995218] scsi host9: ahci\r\n[ 8.998337] scsi host10: ahci\r\n[ 9." + - delay: 29 + content: "001539] scsi host11: ahci\r\n[ 9.004705] scsi host12: ahci\r\n[ 9.007904] scsi host13: ahci\r\n[ 9.020424] ata7: SATA max UDMA/133 abar m524288@0x9d100000 port 0x9d100100 irq 154\r\n[ 9.028081] at" + - delay: 16 + content: "a8: SATA max UDMA/133 abar m524288@0x9d100000 port 0x9d100180 irq 154\r\n[ 9.035733] ata9: SATA max UDMA/133 abar m524288@0x9d100000 port 0x9d100200 irq 154\r\n[ 9.043384] ata10: SATA max UDMA/133 a" + - delay: 18 + content: "bar m524288@0x9d100000 port 0x9d100280 irq 154\r\n[ 9.051123] ata11: SATA max UDMA/133 abar m524288@0x9d100000 port 0x9d100300 irq 154\r\n[ 9.058864] ata12: SATA max UDMA/133 abar m524288@0x9d100000" + - delay: 18 + content: " port 0x9d100380 irq 154\r\n[ 9.066603] ata13: SATA max UDMA/133 abar m524288@0x9d100000 port 0x9d100400 irq 154\r\n[ 9.074340] ata14: SATA max UDMA/133 abar m524288@0x9d100000 port 0x9d100480 irq 1" + - delay: 38 + content: "54\r\n[ 9.103904] igb 0000:3b:00.3: added PHC on eth5\r\n[ 9.108441] igb 0000:3b:00.3: Intel(R) Gigabit Ethernet Network Connection\r\n[ 9.115318] igb 0000:3b:00.3: eth5: (PCIe:5.0Gb/s:Width x4) ac" + - delay: 37 + content: ":1f:6b:94:ca:73\r\n[ 9.122524] igb 0000:3b:00.3: eth5: PBA No: 020C00-000\r\n[ 9.127658] igb 0000:3b:00.3: Using MSI-X interrupts. 8 rx queue(s), 8 tx queue(s)\r\nBegin: Loading essential drivers ... " + - delay: 93 + content: "done.\r\nBegin: Running /scripts/init-premount ... done.\r\nBegin: Mounting root file system ... Begin: Running /scripts/local-top ... done.\r\nBegin: Running /scripts/local-premount ... done.\r\n" + - delay: 227 + content: "[ 9.397187] ata14: SATA link down (SStatus 0 SControl 300)\r\n[ 9.402694] ata9: SATA link down (SStatus 0 SControl 300)\r\n[ 9.408118] ata13: SATA link down (SStatus 0 SControl 300)\r\n[ 9.413620] ata12: SATA link down (SStatus 0 SControl 300)\r\n[ 9.419123] ata10: SATA link down (SStatus 0 SControl 300)\r\n[ 9.424625] ata8: SATA link down (SStatus 0 SControl 300)\r\n[ 9.430046] ata7: SAT" + - delay: 52 + content: "A link down (SStatus 0 SControl 300)\r\n[ 9.435458] ata11: SATA link down (SStatus 0 SControl 300)\r\n" + - delay: 1177 + content: "[ 10.634228] nvme nvme1: Shutdown timeout set to 10 seconds\r\n[ 10.634256] nvme nvme0: Shutdown timeout set to 10 seconds\r\n[ 10.643251] nvme nvme1: 32/0/0 default/read/poll queues\r\n[ 10.648694] nvme nvme0: 32/0/0 default/read/poll queues\r\n[ 10.664027] nvme1n1: p1 p2 p3\r\nWarning: fsck not present, so sk[ 10.696832] EXT4-fs (nvme1n1p2): mounted filesystem with ordered data mode. Opts: (n" + - delay: 94 + content: "ull)\r\nipping root file system\r\ndone.\r\nBegin: Running /scripts/local-bottom ... done.\r\nBegin: Running /scripts/init-bottom ... done.\r\n" + - delay: 100 + content: "[ 10.813511] systemd[1]: Inserted module 'autofs4'\r\n" + - delay: 20 + content: >- + [ 10.901523] systemd[1]: systemd 240 running in system mode. (+PAM + +AUDIT +SELINUX +IMA +APPARMOR +SMACK +SYSVINIT +UTMP +LIBCRYPTSETUP + +GCRYPT +GNUTLS +ACL +XZ +LZ4 +SECCOMP +BLKID +ELFUTILS +KMOD + - delay: 90 + content: "-IDN2 +IDN -PCRE2 default-hierarchy=hybrid)\r\n[ 10.941909] systemd[1]: Detected architecture x86-64.\r\n\r\nWelcome to \e[1mUbuntu 19.04\e[0m!\r\n\r\n[ 10.966019] systemd[1]: Set hostname to .\r\n" + - delay: 78 + content: "[ 11.062230] systemd[1]: Started Dispatch Password Requests to Console Directory Watch.\r\n[\e[0;32m OK \e[0m] Started \e[0;1;39mDispatch Password …ts to Console Directory Watch\e[0m.\r\n[ 11.085966] " + - delay: 23 + content: "systemd[1]: Started Forward Password Requests to Wall Directory Watch.\r\n[\e[0;32m OK \e[0m] Started \e[0;1;39mForward Password R…uests to Wall Directory Watch\e[0m.\r\n[ 11.109787] systemd[1]: Reached" + - delay: 31 + content: " target Paths.\r\n[\e[0;32m OK \e[0m] Reached target \e[0;1;39mPaths\e[0m.\r\n[ 11.130073] systemd[1]: Listening on fsck to fsckd communication Socket.\r\n[\e[0;32m OK \e[0m] Listening on \e[0;1;39mfsck to f" + - delay: 36 + content: "sckd communication Socket\e[0m.\r\n[ 11.153929] systemd[1]: Listening on Network Service Netlink Socket.\r\n[\e[0;32m OK \e[0m] Listening on \e[0;1;39mNetwork Service Netlink Socket\e[0m.\r\n[ 11.179696] s" + - delay: 26 + content: "ystemd[1]: Created slice system-systemd\\x2dfsck.slice.\r\n[\e[0;32m OK \e[0m] Created slice \e[0;1;39msystem-systemd\\x2dfsck.slice\e[0m.\r\n[ 11.201897] systemd[1]: Reached target System Time Synchronized" + - delay: 35 + content: ".\r\n[\e[0;32m OK \e[0m] Reached target \e[0;1;39mSystem Time Synchronized\e[0m.\r\n[\e[0;32m OK \e[0m] Reached target \e[0;1;39mRemote File Systems\e[0m.\r\n[\e[0;32m OK \e[0m] Listening on \e[0;1;39mJournal So" + - delay: 53 + content: "cket\e[0m.\r\n Mounting \e[0;1;39mHuge Pages File System\e[0m...\r\n Starting \e[0;1;39mCreate list of re…odes for the current kernel\e[0m...\r\n Starting \e[0;1;39mFile System Check on " + - delay: 48 + content: "Root Device\e[0m...\r\n Mounting \e[0;1;39mPOSIX Message Queue File System\e[0m...\r\n Mounting \e[0;1;39mKernel Debug File System\e[0m...\r\n Starting \e[0;1;39mLoad Kernel Modules\e[0m..." + - delay: 21 + content: "\r\n[ 11.346010] IPMI message handler: version 39.2\r\n[ 11.352131] ipmi device interface\r\n Startin[ 11.357036] IPMI Watchdog: driver initialized\r\ng \e[0;1;39mifupdown2 networking initializat" + - delay: 53 + content: "ion\e[0m...\r\n[\e[0;32m OK \e[0m] Listening on \e[0;1;39mudev Kernel Socket\e[0m.\r\n[\e[0;32m OK \e[0m] Reached target \e[0;1;39mLocal Encrypted Volumes\e[0m.\r\n[\e[0;32m OK \e[0m] Listening on \e[0;1;39mJourn" + - delay: 46 + content: "al Socket (/dev/log)\e[0m.\r\n[\e[0;32m OK \e[0m] Listening on \e[0;1;39minitctl Compatibility Named Pipe\e[0m.\r\n[\e[0;32m OK \e[0m] Created slice \e[0;1;39msystem-getty.slice\e[0m.\r\n[\e[0;32m OK \e[0m] List" + - delay: 38 + content: "ening on \e[0;1;39mJournal Audit Socket\e[0m.\r\n Starting \e[0;1;39mJournal Service\e[0m...\r\n[ 11.493118] Ethernet Channel Bonding Driver: v3.7.1 (April 27, 2011)\r\n[\e[0;32m OK \e[0m] Created sli" + - delay: 44 + content: "ce \e[0;1;39msystem-serial\\x2dgetty.slice\e[0m.\r\n[\e[0;32m OK \e[0m] Set up automount \e[0;1;39mArbitrary…s File System Automount Point\e[0m.\r\n[\e[0;32m OK \e[0m] Reached target \e[0;1;39mSwap\e[0m.\r\n[\e[0" + - delay: 47 + content: ";32m OK \e[0m] Listening on \e[0;1;39mudev Control Socket\e[0m.\r\n Starting \e[0;1;39mudev Coldplug all Devices\e[0m...\r\n[\e[0;32m OK \e[0m] Created slice \e[0;1;39mUser and Session Slice\e[0m.\r\n[\e[" + - delay: 46 + content: "0;32m OK \e[0m] Reached target \e[0;1;39mSlices\e[0m.\r\n[\e[0;32m OK \e[0m] Mounted \e[0;1;39mHuge Pages File System\e[0m.\r\n[\e[0;32m OK \e[0m] Started \e[0;1;39mCreate list of req… nodes for the current" + - delay: 43 + content: " kernel\e[0m.\r\n[\e[0;32m OK \e[0m] Started \e[0;1;39mFile System Check on Root Device\e[0m.\r\n[\e[0;32m OK \e[0m] Mounted \e[0;1;39mPOSIX Message Queue File System\e[0m.\r\n[\e[0;32m OK \e[0m] Mounted \e[0;1;3" + - delay: 47 + content: "9mKernel Debug File System\e[0m.\r\n[\e[0;32m OK \e[0m] Started \e[0;1;39mLoad Kernel Modules\e[0m.\r\n[\e[0;32m OK \e[0m] Started \e[0;1;39mifupdown2 networking initialization\e[0m.\r\n[\e[0;32m OK \e[0m] Start" + - delay: 38 + content: "ed \e[0;1;39mFile System Check Daemon to report status\e[0m.\r\n Mounting \e[0;1;39mFUSE Control File System\e[0m...\r\n[ 11.760601] systemd-journald[789]: Configuration file /etc/systemd/journald.c" + - delay: 29 + content: "onf.d/00-journal-size.conf is marked world-writable. Please remove world writability permission bits. Proceeding anyway.\r\n Starting \e[0;1;39mApply Kernel Variables\e[0m...\r\n Mounting \e[" + - delay: 50 + content: "0;1;39mKernel Configuration File System\e[0m...\r\n Starting \e[0;1;39mRemount Root and Kernel File Systems\e[0m...\r\n[\e[0;32m OK \e[0m] Mounted \e[0;1;39mFUSE Control File System\e[0m.\r\n[\e[0;32m OK" + - delay: 46 + content: " \e[0m] Started \e[0;1;39mApply Kernel Variables\e[0m.\r\n[\e[0;32m OK \e[0m] Mounted \e[0;1;39mKernel Configuration File System\e[0m.\r\n[\e[0;32m OK \e[0m] Started \e[0;1;39mudev Coldplug all Devices\e[0m.\r\n[" + - delay: 49 + content: "\e[0;32m OK \e[0m] Started \e[0;1;39mRemount Root and Kernel File Systems\e[0m.\r\n[\e[0;32m OK \e[0m] Started \e[0;1;39mJournal Service\e[0m.\r\n Starting \e[0;1;39mCreate System Users\e[0m...\r\n " + - delay: 54 + content: " Starting \e[0;1;39mFlush Journal to Persistent Storage\e[0m...\r\n[\e[0;32m OK \e[0m] Started \e[0;1;39mCreate System Users\e[0m.\r\n Starting \e[0;1;39mCreate Static Device Nodes in /dev\e[0m...\r\n[\e[" + - delay: 47 + content: "0;32m OK \e[0m] Started \e[0;1;39mCreate Static Device Nodes in /dev\e[0m.\r\n[\e[0;32m OK \e[0m] Reached target \e[0;1;39mLocal File Systems (Pre)\e[0m.\r\n Mounting \e[0;1;39m/tmp\e[0m...\r\n S" + - delay: 44 + content: "tarting \e[0;1;39mudev Kernel Device Manager\e[0m...\r\n[\e[0;32m OK \e[0m] Started \e[0;1;39mFlush Journal to Persistent Storage\e[0m.\r\n[\e[0;32m OK \e[0m] Started \e[0;1;39mudev Kernel Device Manager\e[0m.\r" + - delay: 96 + content: "\n[\e[0;32m OK \e[0m] Mounted \e[0;1;39m/tmp\e[0m.\r\n Starting \e[0;1;39mNetwork Service\e[0m...\r\n" + - delay: 263 + content: "[\e[0;32m OK \e[0m] Found device \e[0;1;39m/dev/ttyS1\e[0m.\r\n" + - delay: 353 + content: "[\e[0;32m OK \e[0m] Started \e[0;1;39mNetwork Service\e[0m.\r\n[\e[0;32m OK \e[0m] Found device \e[0;1;39mSAMSUNG MZWLL800HEHP-00003 varlib\e[0m.\r\n[\e[0;32m OK \e[0m] Found device \e[0;1;39mSAMSUNG MZWLL800HEHP-00003 EFI\e[0m.\r\n Mounting \e[0;1;39m/boot/efi\e[0m...\r\n Starting \e[0;1;39mFile System Check…1077-4c64-b006-7efe6e1ea662\e[0m...\r\n Starting \e[0;1;39mWait \e[0m...\r\n[\e[0;32m OK \e[0m] Mounted \e[0;1;39m/boot/efi\e[0m.\r\n[\e[0;32m OK \e[0m] Started \e[0;1;39mFile System Check …d-1077-4c64-b006-7efe6e1ea662\e[0m.\r\n Mounting \e[0;1;39m/var/lib\e[0m...\r\n[\e[0;32m OK \e[0m] Mounted \e[0;1;39m/var/lib\e[0m.\r\n[\e[0;32m OK \e[0m] Listening on \e[0;1;39mLoad/Save RF …itch Status /dev/rfkill Watch\e[0m.\r\n Starting \e[0;1;39mLoad/[0m...\r\n[\e[0;32m OK \e[0m] Reached target" + - delay: 47 + content: " \e[0;1;39mLocal File Systems\e[0m.\r\n Starting \e[0;1;39mGRUB failed boot detection\e[0m...\r\n Starting \e[0;1;39mCreate Volatile Files and Directories\e[0m...\r\n[\e[0;32m OK \e[0m] Started \e[" + - delay: 23 + content: "0;1;39mLoad/Save Random Seed\e[0m.\r\n[ 12.861760] mei mei::55213584-9a29-4916-badf-0fb7ed682aeb:01: Could not read FW version\r\n[ 12.861769] mei mei::55213584-9a29-4916-badf-0fb7ed682aeb:01: FW versi" + - delay: 45 + content: "on command failed -5\r\n[\e[0;32m OK \e[0m] Started \e[0;1;39mCreate Volatile Files and Directories\e[0m.\r\n[\e[0;32m OK \e[0m] Started \e[0;1;39mGRUB failed boot detection\e[0m.\r\n Starting \e[0;1;39m" + - delay: 51 + content: "Update UTMP about System Boot/Shutdown\e[0m...\r\n Starting \e[0;1;39mNetwork Name Resolution\e[0m...\r\n[\e[0;32m OK \e[0m] Started \e[0;1;39mUpdate UTMP about System Boot/Shutdown\e[0m.\r\n[\e[0;32m OK" + - delay: 48 + content: " \e[0m] Reached target \e[0;1;39mSystem Initialization\e[0m.\r\n[\e[0;32m OK \e[0m] Started \e[0;1;39mDaily apt download activities\e[0m.\r\n Starting \e[0;1;39mDocker Socket for the API\e[0m.\r\n[\e[0;32m" + - delay: 39 + content: " OK \e[0m] Started \e[0;1;39mDaily rotation of log files\e[0m.\r\n[\e[0;32m OK \e[0m] Listening on \e[0;1;39mD-Bus System Message Bus Socket\e[0m.\r\n[\e[0;32m OK \e[0m] Started \e[0;1;39mDaily Cleanup of Tem" + - delay: 46 + content: "porary Directories\e[0m.\r\n[\e[0;32m OK \e[0m] Started \e[0;1;39mMessage of the Day\e[0m.\r\n[\e[0;32m OK \e[0m] Started \e[0;1;39mDiscard unused blocks once a week\e[0m.\r\n[\e[0;32m OK \e[0m] Started \e[0;1;39" + - delay: 48 + content: "mDaily apt upgrade and clean activities\e[0m.\r\n[\e[0;32m OK \e[0m] Reached target \e[0;1;39mTimers\e[0m.\r\n[\e[0;32m OK \e[0m] Listening on \e[0;1;39mDocker Socket for the API\e[0m.\r\n[\e[0;32m OK \e[0m] Rea" + - delay: 47 + content: "ched target \e[0;1;39mSockets\e[0m.\r\n[\e[0;32m OK \e[0m] Reached target \e[0;1;39mBasic System\e[0m.\r\n Starting \e[0;1;39mFRRouting\e[0m...\r\n[\e[0;32m OK \e[0m] Started \e[0;1;39mD-Bus System Message" + - delay: 49 + content: " Bus\e[0m.\r\n Starting \e[0;1;39mLogin Service\e[0m...\r\n Starting \e[0;1;39mLSB: Record successful boot for GRUB\e[0m...\r\n[\e[0;32m OK \e[0m] Started \e[0;1;39mSet the CPU Frequency Scaling g" + - delay: 57 + content: "overnor\e[0m.\r\n[\e[0;32m OK \e[0m] Started \e[0;1;39mNetwork Name Resolution\e[0m.\r\n[\e[0;32m OK \e[0m] Reached target \e[0;1;39mHost and Network Name Lookups\e[0m.\r\n[\e[0;32m OK \e[0m] Started \e[0;1;39mLS" + - delay: 96 + content: "B: Record successful boot for GRUB\e[0m.\r\n" + - delay: 99 + content: "[\e[0;32m OK \e[0m] Started \e[0;1;39mLogin Service\e[0m.\r\n" + - delay: 379 + content: "[\e[0;32m OK \e[0m] Started \e[0;1;39mFRRouting\e[0m.\r\n[\e[0;32m OK \e[0m] Reached target \e[0;1;39mNetwork\e[0m.\r\n Starting \e[0;1;39mOpenBSD Secure Shell server\e[0m...\r\n Starting \e[0;1;39mcontainerd container runtime\e[0m...\r\n Starti" + - delay: 22 + content: "ng \e[0;1;39mNetwork Time Service\e[0m...\r\n Starting \e[0;1;39mPermit User Sessions\e[0m...\r\n[\e[0;32m OK \e[0m] Started \e[0;1;39mLLDP daemon\e[0m.\r\n[\e[0;32m OK \e[0m] Started \e[0;1;39mcontainerd " + - delay: 50 + content: "container runtime\e[0m.\r\n[\e[0;32m OK \e[0m] Started \e[0;1;39mOpenBSD Secure Shell server\e[0m.\r\n[\e[0;32m OK \e[0m] Started \e[0;1;39mNetwork Time Service\e[0m.\r\n[\e[0;32m OK \e[0m] Started \e[0;1;39mPerm" + - delay: 52 + content: "it User Sessions\e[0m.\r\n[\e[0;32m OK \e[0m] Started \e[0;1;39mSerial Getty on ttyS1\e[0m.\r\n[\e[0;32m OK \e[0m] Started \e[0;1;39mGetty on tty1\e[0m.\r\n[\e[0;32m OK \e[0m] Reached target \e[0;1;39mLogin Promp" + - delay: 94 + content: "ts\e[0m.\r\n[ 14.062263] power_meter ACPI000D:00: Ignoring unsafe software power cap!\r\n" + - delay: 5218 + content: "\r\r\nUbuntu 19.04 test-01 ttyS1\r\n\r\ntest-01 login: " + - delay: 4000 + content: m + - delay: 138 + content: e + - delay: 72 + content: t + - delay: 200 + content: a + - delay: 217 + content: l + - delay: 783 + content: "\r\r\nPassword: " + - delay: 1010 + content: "\r\nWarning: your password will expire in 1 day\r\nWelcome to Ubuntu 19.04 (GNU/Linux 5.0.0-29-generic x86_64)\r\n\r\n " + - delay: 17 + content: "* Documentation: https://help.ubuntu.com\r\n * Management: https://landscape.canonical.com\r\n * Support: https://ubuntu.com/advantage\r\n\r\nThis system has been minimized by removing packages an" + - delay: 18 + content: "d content that are\r\nnot required on a system that users do not log into.\r\n\r\nTo restore this content, you can run the 'unminimize' command.\r\n\r\nThe programs included with the Ubuntu system are free soft" + - delay: 17 + content: "ware;\r\nthe exact distribution terms for each program are described in the\r\nindividual files in /usr/share/doc/*/copyright.\r\n\r\nUbuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by\r\nappl" + - delay: 97 + content: "icable law.\r\n\r\nTo run a command as administrator (user \"root\"), use \"sudo \".\r\nSee \"man sudo_root\" for details.\r\n\r\nmetal@test-01:~$ " + - delay: 3101 + content: c + - delay: 99 + content: a + - delay: 101 + content: t + - delay: 99 + content: ' ' + - delay: 268 + content: / + - delay: 132 + content: et + - delay: 100 + content: c/ + - delay: 400 + content: o + - delay: 100 + content: s + - delay: 100 + content: '-release ' + - delay: 447 + content: "\r\nNAME=\"Ubuntu\"\r\nVERSION=\"19.04 (Disco Dingo)\"\r\nID=ubuntu\r\nID_LIKE=debian\r\nPRETTY_NAME=\"Ubuntu 19.04\"\r\nVERSION_ID=\"19.04\"\r\nHOME_URL=\"https://www.ubuntu.com/\"\r\nSUPPORT_URL=\"https://help.ubuntu.com/\"\r\nB" + - delay: 28 + content: "UG_REPORT_URL=\"https://bugs.launchpad.net/ubuntu/\"\r\nPRIVACY_POLICY_URL=\"https://www.ubuntu.com/legal/terms-and-policies/privacy-policy\"\r\nVERSION_CODENAME=disco\r\nUBUNTU_CODENAME=disco\r\nmetal@test-01:~$" + - delay: 5000 + content: ' ' diff --git a/v0.18.15/assets/themes/documenter-dark.css b/v0.18.15/assets/themes/documenter-dark.css new file mode 100644 index 0000000000..53889fb99d --- /dev/null +++ b/v0.18.15/assets/themes/documenter-dark.css @@ -0,0 +1,7 @@ +html.theme--documenter-dark .pagination-previous,html.theme--documenter-dark .pagination-next,html.theme--documenter-dark .pagination-link,html.theme--documenter-dark .pagination-ellipsis,html.theme--documenter-dark .file-cta,html.theme--documenter-dark .file-name,html.theme--documenter-dark .select select,html.theme--documenter-dark .textarea,html.theme--documenter-dark .input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input,html.theme--documenter-dark .button{-moz-appearance:none;-webkit-appearance:none;align-items:center;border:1px solid transparent;border-radius:.4em;box-shadow:none;display:inline-flex;font-size:1rem;height:2.5em;justify-content:flex-start;line-height:1.5;padding-bottom:calc(0.5em - 1px);padding-left:calc(0.75em - 1px);padding-right:calc(0.75em - 1px);padding-top:calc(0.5em - 1px);position:relative;vertical-align:top}html.theme--documenter-dark .pagination-previous:focus,html.theme--documenter-dark .pagination-next:focus,html.theme--documenter-dark .pagination-link:focus,html.theme--documenter-dark .pagination-ellipsis:focus,html.theme--documenter-dark .file-cta:focus,html.theme--documenter-dark .file-name:focus,html.theme--documenter-dark .select select:focus,html.theme--documenter-dark .textarea:focus,html.theme--documenter-dark .input:focus,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input:focus,html.theme--documenter-dark .button:focus,html.theme--documenter-dark .is-focused.pagination-previous,html.theme--documenter-dark .is-focused.pagination-next,html.theme--documenter-dark .is-focused.pagination-link,html.theme--documenter-dark .is-focused.pagination-ellipsis,html.theme--documenter-dark .is-focused.file-cta,html.theme--documenter-dark .is-focused.file-name,html.theme--documenter-dark .select select.is-focused,html.theme--documenter-dark .is-focused.textarea,html.theme--documenter-dark .is-focused.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--documenter-dark .is-focused.button,html.theme--documenter-dark .pagination-previous:active,html.theme--documenter-dark .pagination-next:active,html.theme--documenter-dark .pagination-link:active,html.theme--documenter-dark .pagination-ellipsis:active,html.theme--documenter-dark .file-cta:active,html.theme--documenter-dark .file-name:active,html.theme--documenter-dark .select select:active,html.theme--documenter-dark .textarea:active,html.theme--documenter-dark .input:active,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input:active,html.theme--documenter-dark .button:active,html.theme--documenter-dark .is-active.pagination-previous,html.theme--documenter-dark .is-active.pagination-next,html.theme--documenter-dark .is-active.pagination-link,html.theme--documenter-dark .is-active.pagination-ellipsis,html.theme--documenter-dark .is-active.file-cta,html.theme--documenter-dark .is-active.file-name,html.theme--documenter-dark .select select.is-active,html.theme--documenter-dark .is-active.textarea,html.theme--documenter-dark .is-active.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-active,html.theme--documenter-dark .is-active.button{outline:none}html.theme--documenter-dark .pagination-previous[disabled],html.theme--documenter-dark .pagination-next[disabled],html.theme--documenter-dark .pagination-link[disabled],html.theme--documenter-dark .pagination-ellipsis[disabled],html.theme--documenter-dark .file-cta[disabled],html.theme--documenter-dark .file-name[disabled],html.theme--documenter-dark .select select[disabled],html.theme--documenter-dark .textarea[disabled],html.theme--documenter-dark .input[disabled],html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input[disabled],html.theme--documenter-dark .button[disabled],fieldset[disabled] html.theme--documenter-dark .pagination-previous,html.theme--documenter-dark fieldset[disabled] .pagination-previous,fieldset[disabled] html.theme--documenter-dark .pagination-next,html.theme--documenter-dark fieldset[disabled] .pagination-next,fieldset[disabled] html.theme--documenter-dark .pagination-link,html.theme--documenter-dark fieldset[disabled] .pagination-link,fieldset[disabled] html.theme--documenter-dark .pagination-ellipsis,html.theme--documenter-dark fieldset[disabled] .pagination-ellipsis,fieldset[disabled] html.theme--documenter-dark .file-cta,html.theme--documenter-dark fieldset[disabled] .file-cta,fieldset[disabled] html.theme--documenter-dark .file-name,html.theme--documenter-dark fieldset[disabled] .file-name,fieldset[disabled] html.theme--documenter-dark .select select,fieldset[disabled] html.theme--documenter-dark .textarea,fieldset[disabled] html.theme--documenter-dark .input,fieldset[disabled] html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input,html.theme--documenter-dark fieldset[disabled] .select select,html.theme--documenter-dark .select fieldset[disabled] select,html.theme--documenter-dark fieldset[disabled] .textarea,html.theme--documenter-dark fieldset[disabled] .input,html.theme--documenter-dark fieldset[disabled] #documenter .docs-sidebar form.docs-search>input,html.theme--documenter-dark #documenter .docs-sidebar fieldset[disabled] form.docs-search>input,fieldset[disabled] html.theme--documenter-dark .button,html.theme--documenter-dark fieldset[disabled] .button{cursor:not-allowed}html.theme--documenter-dark .tabs,html.theme--documenter-dark .pagination-previous,html.theme--documenter-dark .pagination-next,html.theme--documenter-dark .pagination-link,html.theme--documenter-dark .pagination-ellipsis,html.theme--documenter-dark .breadcrumb,html.theme--documenter-dark .file,html.theme--documenter-dark .button,.is-unselectable{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}html.theme--documenter-dark .navbar-link:not(.is-arrowless)::after,html.theme--documenter-dark .select:not(.is-multiple):not(.is-loading)::after{border:3px solid rgba(0,0,0,0);border-radius:2px;border-right:0;border-top:0;content:" ";display:block;height:0.625em;margin-top:-0.4375em;pointer-events:none;position:absolute;top:50%;transform:rotate(-45deg);transform-origin:center;width:0.625em}html.theme--documenter-dark .admonition:not(:last-child),html.theme--documenter-dark .tabs:not(:last-child),html.theme--documenter-dark .pagination:not(:last-child),html.theme--documenter-dark .message:not(:last-child),html.theme--documenter-dark .level:not(:last-child),html.theme--documenter-dark .breadcrumb:not(:last-child),html.theme--documenter-dark .block:not(:last-child),html.theme--documenter-dark .title:not(:last-child),html.theme--documenter-dark .subtitle:not(:last-child),html.theme--documenter-dark .table-container:not(:last-child),html.theme--documenter-dark .table:not(:last-child),html.theme--documenter-dark .progress:not(:last-child),html.theme--documenter-dark .notification:not(:last-child),html.theme--documenter-dark .content:not(:last-child),html.theme--documenter-dark .box:not(:last-child){margin-bottom:1.5rem}html.theme--documenter-dark .modal-close,html.theme--documenter-dark .delete{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-moz-appearance:none;-webkit-appearance:none;background-color:rgba(10,10,10,0.2);border:none;border-radius:9999px;cursor:pointer;pointer-events:auto;display:inline-block;flex-grow:0;flex-shrink:0;font-size:0;height:20px;max-height:20px;max-width:20px;min-height:20px;min-width:20px;outline:none;position:relative;vertical-align:top;width:20px}html.theme--documenter-dark .modal-close::before,html.theme--documenter-dark .delete::before,html.theme--documenter-dark .modal-close::after,html.theme--documenter-dark .delete::after{background-color:#fff;content:"";display:block;left:50%;position:absolute;top:50%;transform:translateX(-50%) translateY(-50%) rotate(45deg);transform-origin:center center}html.theme--documenter-dark .modal-close::before,html.theme--documenter-dark .delete::before{height:2px;width:50%}html.theme--documenter-dark .modal-close::after,html.theme--documenter-dark .delete::after{height:50%;width:2px}html.theme--documenter-dark .modal-close:hover,html.theme--documenter-dark .delete:hover,html.theme--documenter-dark .modal-close:focus,html.theme--documenter-dark .delete:focus{background-color:rgba(10,10,10,0.3)}html.theme--documenter-dark .modal-close:active,html.theme--documenter-dark .delete:active{background-color:rgba(10,10,10,0.4)}html.theme--documenter-dark .is-small.modal-close,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.modal-close,html.theme--documenter-dark .is-small.delete,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.delete{height:16px;max-height:16px;max-width:16px;min-height:16px;min-width:16px;width:16px}html.theme--documenter-dark .is-medium.modal-close,html.theme--documenter-dark .is-medium.delete{height:24px;max-height:24px;max-width:24px;min-height:24px;min-width:24px;width:24px}html.theme--documenter-dark .is-large.modal-close,html.theme--documenter-dark .is-large.delete{height:32px;max-height:32px;max-width:32px;min-height:32px;min-width:32px;width:32px}html.theme--documenter-dark .control.is-loading::after,html.theme--documenter-dark .select.is-loading::after,html.theme--documenter-dark .loader,html.theme--documenter-dark .button.is-loading::after{animation:spinAround 500ms infinite linear;border:2px solid #dbdee0;border-radius:9999px;border-right-color:transparent;border-top-color:transparent;content:"";display:block;height:1em;position:relative;width:1em}html.theme--documenter-dark .hero-video,html.theme--documenter-dark .modal-background,html.theme--documenter-dark .modal,html.theme--documenter-dark .image.is-square img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-square img,html.theme--documenter-dark .image.is-square .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-square .has-ratio,html.theme--documenter-dark .image.is-1by1 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-1by1 img,html.theme--documenter-dark .image.is-1by1 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-1by1 .has-ratio,html.theme--documenter-dark .image.is-5by4 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-5by4 img,html.theme--documenter-dark .image.is-5by4 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-5by4 .has-ratio,html.theme--documenter-dark .image.is-4by3 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-4by3 img,html.theme--documenter-dark .image.is-4by3 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-4by3 .has-ratio,html.theme--documenter-dark .image.is-3by2 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-3by2 img,html.theme--documenter-dark .image.is-3by2 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-3by2 .has-ratio,html.theme--documenter-dark .image.is-5by3 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-5by3 img,html.theme--documenter-dark .image.is-5by3 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-5by3 .has-ratio,html.theme--documenter-dark .image.is-16by9 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-16by9 img,html.theme--documenter-dark .image.is-16by9 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-16by9 .has-ratio,html.theme--documenter-dark .image.is-2by1 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-2by1 img,html.theme--documenter-dark .image.is-2by1 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-2by1 .has-ratio,html.theme--documenter-dark .image.is-3by1 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-3by1 img,html.theme--documenter-dark .image.is-3by1 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-3by1 .has-ratio,html.theme--documenter-dark .image.is-4by5 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-4by5 img,html.theme--documenter-dark .image.is-4by5 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-4by5 .has-ratio,html.theme--documenter-dark .image.is-3by4 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-3by4 img,html.theme--documenter-dark .image.is-3by4 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-3by4 .has-ratio,html.theme--documenter-dark .image.is-2by3 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-2by3 img,html.theme--documenter-dark .image.is-2by3 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-2by3 .has-ratio,html.theme--documenter-dark .image.is-3by5 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-3by5 img,html.theme--documenter-dark .image.is-3by5 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-3by5 .has-ratio,html.theme--documenter-dark .image.is-9by16 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-9by16 img,html.theme--documenter-dark .image.is-9by16 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-9by16 .has-ratio,html.theme--documenter-dark .image.is-1by2 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-1by2 img,html.theme--documenter-dark .image.is-1by2 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-1by2 .has-ratio,html.theme--documenter-dark .image.is-1by3 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-1by3 img,html.theme--documenter-dark .image.is-1by3 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-1by3 .has-ratio,.is-overlay{bottom:0;left:0;position:absolute;right:0;top:0}html.theme--documenter-dark .navbar-burger{-moz-appearance:none;-webkit-appearance:none;appearance:none;background:none;border:none;color:currentColor;font-family:inherit;font-size:1em;margin:0;padding:0}/*! minireset.css v0.0.6 | MIT License | github.com/jgthms/minireset.css */html,body,p,ol,ul,li,dl,dt,dd,blockquote,figure,fieldset,legend,textarea,pre,iframe,hr,h1,h2,h3,h4,h5,h6{margin:0;padding:0}h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:normal}ul{list-style:none}button,input,select,textarea{margin:0}html{box-sizing:border-box}*,*::before,*::after{box-sizing:inherit}img,video{height:auto;max-width:100%}iframe{border:0}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}td:not([align]),th:not([align]){text-align:inherit}.has-text-white{color:#fff !important}a.has-text-white:hover,a.has-text-white:focus{color:#e6e6e6 !important}.has-background-white{background-color:#fff !important}.has-text-black{color:#0a0a0a !important}a.has-text-black:hover,a.has-text-black:focus{color:#000 !important}.has-background-black{background-color:#0a0a0a !important}.has-text-light{color:#ecf0f1 !important}a.has-text-light:hover,a.has-text-light:focus{color:#cfd9db !important}.has-background-light{background-color:#ecf0f1 !important}.has-text-dark{color:#282f2f !important}a.has-text-dark:hover,a.has-text-dark:focus{color:#111414 !important}.has-background-dark{background-color:#282f2f !important}.has-text-primary{color:#375a7f !important}a.has-text-primary:hover,a.has-text-primary:focus{color:#28415b !important}.has-background-primary{background-color:#375a7f !important}.has-text-primary-light{color:#f1f5f9 !important}a.has-text-primary-light:hover,a.has-text-primary-light:focus{color:#cddbe9 !important}.has-background-primary-light{background-color:#f1f5f9 !important}.has-text-primary-dark{color:#4d7eb2 !important}a.has-text-primary-dark:hover,a.has-text-primary-dark:focus{color:#7198c1 !important}.has-background-primary-dark{background-color:#4d7eb2 !important}.has-text-link{color:#1abc9c !important}a.has-text-link:hover,a.has-text-link:focus{color:#148f77 !important}.has-background-link{background-color:#1abc9c !important}.has-text-link-light{color:#edfdf9 !important}a.has-text-link-light:hover,a.has-text-link-light:focus{color:#c0f6ec !important}.has-background-link-light{background-color:#edfdf9 !important}.has-text-link-dark{color:#15987e !important}a.has-text-link-dark:hover,a.has-text-link-dark:focus{color:#1bc5a4 !important}.has-background-link-dark{background-color:#15987e !important}.has-text-info{color:#024c7d !important}a.has-text-info:hover,a.has-text-info:focus{color:#012d4b !important}.has-background-info{background-color:#024c7d !important}.has-text-info-light{color:#ebf7ff !important}a.has-text-info-light:hover,a.has-text-info-light:focus{color:#b9e2fe !important}.has-background-info-light{background-color:#ebf7ff !important}.has-text-info-dark{color:#0e9dfb !important}a.has-text-info-dark:hover,a.has-text-info-dark:focus{color:#40b1fc !important}.has-background-info-dark{background-color:#0e9dfb !important}.has-text-success{color:#008438 !important}a.has-text-success:hover,a.has-text-success:focus{color:#005122 !important}.has-background-success{background-color:#008438 !important}.has-text-success-light{color:#ebfff3 !important}a.has-text-success-light:hover,a.has-text-success-light:focus{color:#b8ffd6 !important}.has-background-success-light{background-color:#ebfff3 !important}.has-text-success-dark{color:#00eb64 !important}a.has-text-success-dark:hover,a.has-text-success-dark:focus{color:#1fff7e !important}.has-background-success-dark{background-color:#00eb64 !important}.has-text-warning{color:#ad8100 !important}a.has-text-warning:hover,a.has-text-warning:focus{color:#7a5b00 !important}.has-background-warning{background-color:#ad8100 !important}.has-text-warning-light{color:#fffaeb !important}a.has-text-warning-light:hover,a.has-text-warning-light:focus{color:#ffedb8 !important}.has-background-warning-light{background-color:#fffaeb !important}.has-text-warning-dark{color:#d19c00 !important}a.has-text-warning-dark:hover,a.has-text-warning-dark:focus{color:#ffbf05 !important}.has-background-warning-dark{background-color:#d19c00 !important}.has-text-danger{color:#9e1b0d !important}a.has-text-danger:hover,a.has-text-danger:focus{color:#6f1309 !important}.has-background-danger{background-color:#9e1b0d !important}.has-text-danger-light{color:#fdeeec !important}a.has-text-danger-light:hover,a.has-text-danger-light:focus{color:#fac3bd !important}.has-background-danger-light{background-color:#fdeeec !important}.has-text-danger-dark{color:#ec311d !important}a.has-text-danger-dark:hover,a.has-text-danger-dark:focus{color:#f05c4c !important}.has-background-danger-dark{background-color:#ec311d !important}.has-text-black-bis{color:#121212 !important}.has-background-black-bis{background-color:#121212 !important}.has-text-black-ter{color:#242424 !important}.has-background-black-ter{background-color:#242424 !important}.has-text-grey-darker{color:#282f2f !important}.has-background-grey-darker{background-color:#282f2f !important}.has-text-grey-dark{color:#343c3d !important}.has-background-grey-dark{background-color:#343c3d !important}.has-text-grey{color:#5e6d6f !important}.has-background-grey{background-color:#5e6d6f !important}.has-text-grey-light{color:#8c9b9d !important}.has-background-grey-light{background-color:#8c9b9d !important}.has-text-grey-lighter{color:#dbdee0 !important}.has-background-grey-lighter{background-color:#dbdee0 !important}.has-text-white-ter{color:#ecf0f1 !important}.has-background-white-ter{background-color:#ecf0f1 !important}.has-text-white-bis{color:#fafafa !important}.has-background-white-bis{background-color:#fafafa !important}.is-flex-direction-row{flex-direction:row !important}.is-flex-direction-row-reverse{flex-direction:row-reverse !important}.is-flex-direction-column{flex-direction:column !important}.is-flex-direction-column-reverse{flex-direction:column-reverse !important}.is-flex-wrap-nowrap{flex-wrap:nowrap !important}.is-flex-wrap-wrap{flex-wrap:wrap !important}.is-flex-wrap-wrap-reverse{flex-wrap:wrap-reverse !important}.is-justify-content-flex-start{justify-content:flex-start !important}.is-justify-content-flex-end{justify-content:flex-end !important}.is-justify-content-center{justify-content:center !important}.is-justify-content-space-between{justify-content:space-between !important}.is-justify-content-space-around{justify-content:space-around !important}.is-justify-content-space-evenly{justify-content:space-evenly !important}.is-justify-content-start{justify-content:start !important}.is-justify-content-end{justify-content:end !important}.is-justify-content-left{justify-content:left !important}.is-justify-content-right{justify-content:right !important}.is-align-content-flex-start{align-content:flex-start !important}.is-align-content-flex-end{align-content:flex-end !important}.is-align-content-center{align-content:center !important}.is-align-content-space-between{align-content:space-between !important}.is-align-content-space-around{align-content:space-around !important}.is-align-content-space-evenly{align-content:space-evenly !important}.is-align-content-stretch{align-content:stretch !important}.is-align-content-start{align-content:start !important}.is-align-content-end{align-content:end !important}.is-align-content-baseline{align-content:baseline !important}.is-align-items-stretch{align-items:stretch !important}.is-align-items-flex-start{align-items:flex-start !important}.is-align-items-flex-end{align-items:flex-end !important}.is-align-items-center{align-items:center !important}.is-align-items-baseline{align-items:baseline !important}.is-align-items-start{align-items:start !important}.is-align-items-end{align-items:end !important}.is-align-items-self-start{align-items:self-start !important}.is-align-items-self-end{align-items:self-end !important}.is-align-self-auto{align-self:auto !important}.is-align-self-flex-start{align-self:flex-start !important}.is-align-self-flex-end{align-self:flex-end !important}.is-align-self-center{align-self:center !important}.is-align-self-baseline{align-self:baseline !important}.is-align-self-stretch{align-self:stretch !important}.is-flex-grow-0{flex-grow:0 !important}.is-flex-grow-1{flex-grow:1 !important}.is-flex-grow-2{flex-grow:2 !important}.is-flex-grow-3{flex-grow:3 !important}.is-flex-grow-4{flex-grow:4 !important}.is-flex-grow-5{flex-grow:5 !important}.is-flex-shrink-0{flex-shrink:0 !important}.is-flex-shrink-1{flex-shrink:1 !important}.is-flex-shrink-2{flex-shrink:2 !important}.is-flex-shrink-3{flex-shrink:3 !important}.is-flex-shrink-4{flex-shrink:4 !important}.is-flex-shrink-5{flex-shrink:5 !important}.is-clearfix::after{clear:both;content:" ";display:table}.is-pulled-left{float:left !important}.is-pulled-right{float:right !important}.is-radiusless{border-radius:0 !important}.is-shadowless{box-shadow:none !important}.is-clickable{cursor:pointer !important;pointer-events:all !important}.is-clipped{overflow:hidden !important}.is-relative{position:relative !important}.is-marginless{margin:0 !important}.is-paddingless{padding:0 !important}.m-0{margin:0 !important}.mt-0{margin-top:0 !important}.mr-0{margin-right:0 !important}.mb-0{margin-bottom:0 !important}.ml-0{margin-left:0 !important}.mx-0{margin-left:0 !important;margin-right:0 !important}.my-0{margin-top:0 !important;margin-bottom:0 !important}.m-1{margin:.25rem !important}.mt-1{margin-top:.25rem !important}.mr-1{margin-right:.25rem !important}.mb-1{margin-bottom:.25rem !important}.ml-1{margin-left:.25rem !important}.mx-1{margin-left:.25rem !important;margin-right:.25rem !important}.my-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.m-2{margin:.5rem !important}.mt-2{margin-top:.5rem !important}.mr-2{margin-right:.5rem !important}.mb-2{margin-bottom:.5rem !important}.ml-2{margin-left:.5rem !important}.mx-2{margin-left:.5rem !important;margin-right:.5rem !important}.my-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.m-3{margin:.75rem !important}.mt-3{margin-top:.75rem !important}.mr-3{margin-right:.75rem !important}.mb-3{margin-bottom:.75rem !important}.ml-3{margin-left:.75rem !important}.mx-3{margin-left:.75rem !important;margin-right:.75rem !important}.my-3{margin-top:.75rem !important;margin-bottom:.75rem !important}.m-4{margin:1rem !important}.mt-4{margin-top:1rem !important}.mr-4{margin-right:1rem !important}.mb-4{margin-bottom:1rem !important}.ml-4{margin-left:1rem !important}.mx-4{margin-left:1rem !important;margin-right:1rem !important}.my-4{margin-top:1rem !important;margin-bottom:1rem !important}.m-5{margin:1.5rem !important}.mt-5{margin-top:1.5rem !important}.mr-5{margin-right:1.5rem !important}.mb-5{margin-bottom:1.5rem !important}.ml-5{margin-left:1.5rem !important}.mx-5{margin-left:1.5rem !important;margin-right:1.5rem !important}.my-5{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.m-6{margin:3rem !important}.mt-6{margin-top:3rem !important}.mr-6{margin-right:3rem !important}.mb-6{margin-bottom:3rem !important}.ml-6{margin-left:3rem !important}.mx-6{margin-left:3rem !important;margin-right:3rem !important}.my-6{margin-top:3rem !important;margin-bottom:3rem !important}.m-auto{margin:auto !important}.mt-auto{margin-top:auto !important}.mr-auto{margin-right:auto !important}.mb-auto{margin-bottom:auto !important}.ml-auto{margin-left:auto !important}.mx-auto{margin-left:auto !important;margin-right:auto !important}.my-auto{margin-top:auto !important;margin-bottom:auto !important}.p-0{padding:0 !important}.pt-0{padding-top:0 !important}.pr-0{padding-right:0 !important}.pb-0{padding-bottom:0 !important}.pl-0{padding-left:0 !important}.px-0{padding-left:0 !important;padding-right:0 !important}.py-0{padding-top:0 !important;padding-bottom:0 !important}.p-1{padding:.25rem !important}.pt-1{padding-top:.25rem !important}.pr-1{padding-right:.25rem !important}.pb-1{padding-bottom:.25rem !important}.pl-1{padding-left:.25rem !important}.px-1{padding-left:.25rem !important;padding-right:.25rem !important}.py-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.p-2{padding:.5rem !important}.pt-2{padding-top:.5rem !important}.pr-2{padding-right:.5rem !important}.pb-2{padding-bottom:.5rem !important}.pl-2{padding-left:.5rem !important}.px-2{padding-left:.5rem !important;padding-right:.5rem !important}.py-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.p-3{padding:.75rem !important}.pt-3{padding-top:.75rem !important}.pr-3{padding-right:.75rem !important}.pb-3{padding-bottom:.75rem !important}.pl-3{padding-left:.75rem !important}.px-3{padding-left:.75rem !important;padding-right:.75rem !important}.py-3{padding-top:.75rem !important;padding-bottom:.75rem !important}.p-4{padding:1rem !important}.pt-4{padding-top:1rem !important}.pr-4{padding-right:1rem !important}.pb-4{padding-bottom:1rem !important}.pl-4{padding-left:1rem !important}.px-4{padding-left:1rem !important;padding-right:1rem !important}.py-4{padding-top:1rem !important;padding-bottom:1rem !important}.p-5{padding:1.5rem !important}.pt-5{padding-top:1.5rem !important}.pr-5{padding-right:1.5rem !important}.pb-5{padding-bottom:1.5rem !important}.pl-5{padding-left:1.5rem !important}.px-5{padding-left:1.5rem !important;padding-right:1.5rem !important}.py-5{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.p-6{padding:3rem !important}.pt-6{padding-top:3rem !important}.pr-6{padding-right:3rem !important}.pb-6{padding-bottom:3rem !important}.pl-6{padding-left:3rem !important}.px-6{padding-left:3rem !important;padding-right:3rem !important}.py-6{padding-top:3rem !important;padding-bottom:3rem !important}.p-auto{padding:auto !important}.pt-auto{padding-top:auto !important}.pr-auto{padding-right:auto !important}.pb-auto{padding-bottom:auto !important}.pl-auto{padding-left:auto !important}.px-auto{padding-left:auto !important;padding-right:auto !important}.py-auto{padding-top:auto !important;padding-bottom:auto !important}.is-size-1{font-size:3rem !important}.is-size-2{font-size:2.5rem !important}.is-size-3{font-size:2rem !important}.is-size-4{font-size:1.5rem !important}.is-size-5{font-size:1.25rem !important}.is-size-6{font-size:1rem !important}.is-size-7,html.theme--documenter-dark .docstring>section>a.docs-sourcelink{font-size:.75rem !important}@media screen and (max-width: 768px){.is-size-1-mobile{font-size:3rem !important}.is-size-2-mobile{font-size:2.5rem !important}.is-size-3-mobile{font-size:2rem !important}.is-size-4-mobile{font-size:1.5rem !important}.is-size-5-mobile{font-size:1.25rem !important}.is-size-6-mobile{font-size:1rem !important}.is-size-7-mobile{font-size:.75rem !important}}@media screen and (min-width: 769px),print{.is-size-1-tablet{font-size:3rem !important}.is-size-2-tablet{font-size:2.5rem !important}.is-size-3-tablet{font-size:2rem !important}.is-size-4-tablet{font-size:1.5rem !important}.is-size-5-tablet{font-size:1.25rem !important}.is-size-6-tablet{font-size:1rem !important}.is-size-7-tablet{font-size:.75rem !important}}@media screen and (max-width: 1055px){.is-size-1-touch{font-size:3rem !important}.is-size-2-touch{font-size:2.5rem !important}.is-size-3-touch{font-size:2rem !important}.is-size-4-touch{font-size:1.5rem !important}.is-size-5-touch{font-size:1.25rem !important}.is-size-6-touch{font-size:1rem !important}.is-size-7-touch{font-size:.75rem !important}}@media screen and (min-width: 1056px){.is-size-1-desktop{font-size:3rem !important}.is-size-2-desktop{font-size:2.5rem !important}.is-size-3-desktop{font-size:2rem !important}.is-size-4-desktop{font-size:1.5rem !important}.is-size-5-desktop{font-size:1.25rem !important}.is-size-6-desktop{font-size:1rem !important}.is-size-7-desktop{font-size:.75rem !important}}@media screen and (min-width: 1216px){.is-size-1-widescreen{font-size:3rem !important}.is-size-2-widescreen{font-size:2.5rem !important}.is-size-3-widescreen{font-size:2rem !important}.is-size-4-widescreen{font-size:1.5rem !important}.is-size-5-widescreen{font-size:1.25rem !important}.is-size-6-widescreen{font-size:1rem !important}.is-size-7-widescreen{font-size:.75rem !important}}@media screen and (min-width: 1408px){.is-size-1-fullhd{font-size:3rem !important}.is-size-2-fullhd{font-size:2.5rem !important}.is-size-3-fullhd{font-size:2rem !important}.is-size-4-fullhd{font-size:1.5rem !important}.is-size-5-fullhd{font-size:1.25rem !important}.is-size-6-fullhd{font-size:1rem !important}.is-size-7-fullhd{font-size:.75rem !important}}.has-text-centered{text-align:center !important}.has-text-justified{text-align:justify !important}.has-text-left{text-align:left !important}.has-text-right{text-align:right !important}@media screen and (max-width: 768px){.has-text-centered-mobile{text-align:center !important}}@media screen and (min-width: 769px),print{.has-text-centered-tablet{text-align:center !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.has-text-centered-tablet-only{text-align:center !important}}@media screen and (max-width: 1055px){.has-text-centered-touch{text-align:center !important}}@media screen and (min-width: 1056px){.has-text-centered-desktop{text-align:center !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.has-text-centered-desktop-only{text-align:center !important}}@media screen and (min-width: 1216px){.has-text-centered-widescreen{text-align:center !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.has-text-centered-widescreen-only{text-align:center !important}}@media screen and (min-width: 1408px){.has-text-centered-fullhd{text-align:center !important}}@media screen and (max-width: 768px){.has-text-justified-mobile{text-align:justify !important}}@media screen and (min-width: 769px),print{.has-text-justified-tablet{text-align:justify !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.has-text-justified-tablet-only{text-align:justify !important}}@media screen and (max-width: 1055px){.has-text-justified-touch{text-align:justify !important}}@media screen and (min-width: 1056px){.has-text-justified-desktop{text-align:justify !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.has-text-justified-desktop-only{text-align:justify !important}}@media screen and (min-width: 1216px){.has-text-justified-widescreen{text-align:justify !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.has-text-justified-widescreen-only{text-align:justify !important}}@media screen and (min-width: 1408px){.has-text-justified-fullhd{text-align:justify !important}}@media screen and (max-width: 768px){.has-text-left-mobile{text-align:left !important}}@media screen and (min-width: 769px),print{.has-text-left-tablet{text-align:left !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.has-text-left-tablet-only{text-align:left !important}}@media screen and (max-width: 1055px){.has-text-left-touch{text-align:left !important}}@media screen and (min-width: 1056px){.has-text-left-desktop{text-align:left !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.has-text-left-desktop-only{text-align:left !important}}@media screen and (min-width: 1216px){.has-text-left-widescreen{text-align:left !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.has-text-left-widescreen-only{text-align:left !important}}@media screen and (min-width: 1408px){.has-text-left-fullhd{text-align:left !important}}@media screen and (max-width: 768px){.has-text-right-mobile{text-align:right !important}}@media screen and (min-width: 769px),print{.has-text-right-tablet{text-align:right !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.has-text-right-tablet-only{text-align:right !important}}@media screen and (max-width: 1055px){.has-text-right-touch{text-align:right !important}}@media screen and (min-width: 1056px){.has-text-right-desktop{text-align:right !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.has-text-right-desktop-only{text-align:right !important}}@media screen and (min-width: 1216px){.has-text-right-widescreen{text-align:right !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.has-text-right-widescreen-only{text-align:right !important}}@media screen and (min-width: 1408px){.has-text-right-fullhd{text-align:right !important}}.is-capitalized{text-transform:capitalize !important}.is-lowercase{text-transform:lowercase !important}.is-uppercase{text-transform:uppercase !important}.is-italic{font-style:italic !important}.is-underlined{text-decoration:underline !important}.has-text-weight-light{font-weight:300 !important}.has-text-weight-normal{font-weight:400 !important}.has-text-weight-medium{font-weight:500 !important}.has-text-weight-semibold{font-weight:600 !important}.has-text-weight-bold{font-weight:700 !important}.is-family-primary{font-family:"Lato Medium",-apple-system,BlinkMacSystemFont,"Segoe UI","Helvetica Neue","Helvetica","Arial",sans-serif !important}.is-family-secondary{font-family:"Lato Medium",-apple-system,BlinkMacSystemFont,"Segoe UI","Helvetica Neue","Helvetica","Arial",sans-serif !important}.is-family-sans-serif{font-family:"Lato Medium",-apple-system,BlinkMacSystemFont,"Segoe UI","Helvetica Neue","Helvetica","Arial",sans-serif !important}.is-family-monospace{font-family:"JuliaMono","SFMono-Regular","Menlo","Consolas","Liberation Mono","DejaVu Sans Mono",monospace !important}.is-family-code{font-family:"JuliaMono","SFMono-Regular","Menlo","Consolas","Liberation Mono","DejaVu Sans Mono",monospace !important}.is-block{display:block !important}@media screen and (max-width: 768px){.is-block-mobile{display:block !important}}@media screen and (min-width: 769px),print{.is-block-tablet{display:block !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.is-block-tablet-only{display:block !important}}@media screen and (max-width: 1055px){.is-block-touch{display:block !important}}@media screen and (min-width: 1056px){.is-block-desktop{display:block !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.is-block-desktop-only{display:block !important}}@media screen and (min-width: 1216px){.is-block-widescreen{display:block !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.is-block-widescreen-only{display:block !important}}@media screen and (min-width: 1408px){.is-block-fullhd{display:block !important}}.is-flex{display:flex !important}@media screen and (max-width: 768px){.is-flex-mobile{display:flex !important}}@media screen and (min-width: 769px),print{.is-flex-tablet{display:flex !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.is-flex-tablet-only{display:flex !important}}@media screen and (max-width: 1055px){.is-flex-touch{display:flex !important}}@media screen and (min-width: 1056px){.is-flex-desktop{display:flex !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.is-flex-desktop-only{display:flex !important}}@media screen and (min-width: 1216px){.is-flex-widescreen{display:flex !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.is-flex-widescreen-only{display:flex !important}}@media screen and (min-width: 1408px){.is-flex-fullhd{display:flex !important}}.is-inline{display:inline !important}@media screen and (max-width: 768px){.is-inline-mobile{display:inline !important}}@media screen and (min-width: 769px),print{.is-inline-tablet{display:inline !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.is-inline-tablet-only{display:inline !important}}@media screen and (max-width: 1055px){.is-inline-touch{display:inline !important}}@media screen and (min-width: 1056px){.is-inline-desktop{display:inline !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.is-inline-desktop-only{display:inline !important}}@media screen and (min-width: 1216px){.is-inline-widescreen{display:inline !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.is-inline-widescreen-only{display:inline !important}}@media screen and (min-width: 1408px){.is-inline-fullhd{display:inline !important}}.is-inline-block{display:inline-block !important}@media screen and (max-width: 768px){.is-inline-block-mobile{display:inline-block !important}}@media screen and (min-width: 769px),print{.is-inline-block-tablet{display:inline-block !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.is-inline-block-tablet-only{display:inline-block !important}}@media screen and (max-width: 1055px){.is-inline-block-touch{display:inline-block !important}}@media screen and (min-width: 1056px){.is-inline-block-desktop{display:inline-block !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.is-inline-block-desktop-only{display:inline-block !important}}@media screen and (min-width: 1216px){.is-inline-block-widescreen{display:inline-block !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.is-inline-block-widescreen-only{display:inline-block !important}}@media screen and (min-width: 1408px){.is-inline-block-fullhd{display:inline-block !important}}.is-inline-flex{display:inline-flex !important}@media screen and (max-width: 768px){.is-inline-flex-mobile{display:inline-flex !important}}@media screen and (min-width: 769px),print{.is-inline-flex-tablet{display:inline-flex !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.is-inline-flex-tablet-only{display:inline-flex !important}}@media screen and (max-width: 1055px){.is-inline-flex-touch{display:inline-flex !important}}@media screen and (min-width: 1056px){.is-inline-flex-desktop{display:inline-flex !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.is-inline-flex-desktop-only{display:inline-flex !important}}@media screen and (min-width: 1216px){.is-inline-flex-widescreen{display:inline-flex !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.is-inline-flex-widescreen-only{display:inline-flex !important}}@media screen and (min-width: 1408px){.is-inline-flex-fullhd{display:inline-flex !important}}.is-hidden{display:none !important}.is-sr-only{border:none !important;clip:rect(0, 0, 0, 0) !important;height:0.01em !important;overflow:hidden !important;padding:0 !important;position:absolute !important;white-space:nowrap !important;width:0.01em !important}@media screen and (max-width: 768px){.is-hidden-mobile{display:none !important}}@media screen and (min-width: 769px),print{.is-hidden-tablet{display:none !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.is-hidden-tablet-only{display:none !important}}@media screen and (max-width: 1055px){.is-hidden-touch{display:none !important}}@media screen and (min-width: 1056px){.is-hidden-desktop{display:none !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.is-hidden-desktop-only{display:none !important}}@media screen and (min-width: 1216px){.is-hidden-widescreen{display:none !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.is-hidden-widescreen-only{display:none !important}}@media screen and (min-width: 1408px){.is-hidden-fullhd{display:none !important}}.is-invisible{visibility:hidden !important}@media screen and (max-width: 768px){.is-invisible-mobile{visibility:hidden !important}}@media screen and (min-width: 769px),print{.is-invisible-tablet{visibility:hidden !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.is-invisible-tablet-only{visibility:hidden !important}}@media screen and (max-width: 1055px){.is-invisible-touch{visibility:hidden !important}}@media screen and (min-width: 1056px){.is-invisible-desktop{visibility:hidden !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.is-invisible-desktop-only{visibility:hidden !important}}@media screen and (min-width: 1216px){.is-invisible-widescreen{visibility:hidden !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.is-invisible-widescreen-only{visibility:hidden !important}}@media screen and (min-width: 1408px){.is-invisible-fullhd{visibility:hidden !important}}html.theme--documenter-dark{/*! + Theme: a11y-dark + Author: @ericwbailey + Maintainer: @ericwbailey + + Based on the Tomorrow Night Eighties theme: https://github.com/isagalaev/highlight.js/blob/master/src/styles/tomorrow-night-eighties.css +*/}html.theme--documenter-dark html{background-color:#1f2424;font-size:16px;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;min-width:300px;overflow-x:auto;overflow-y:scroll;text-rendering:optimizeLegibility;text-size-adjust:100%}html.theme--documenter-dark article,html.theme--documenter-dark aside,html.theme--documenter-dark figure,html.theme--documenter-dark footer,html.theme--documenter-dark header,html.theme--documenter-dark hgroup,html.theme--documenter-dark section{display:block}html.theme--documenter-dark body,html.theme--documenter-dark button,html.theme--documenter-dark input,html.theme--documenter-dark optgroup,html.theme--documenter-dark select,html.theme--documenter-dark textarea{font-family:"Lato Medium",-apple-system,BlinkMacSystemFont,"Segoe UI","Helvetica Neue","Helvetica","Arial",sans-serif}html.theme--documenter-dark code,html.theme--documenter-dark pre{-moz-osx-font-smoothing:auto;-webkit-font-smoothing:auto;font-family:"JuliaMono","SFMono-Regular","Menlo","Consolas","Liberation Mono","DejaVu Sans Mono",monospace}html.theme--documenter-dark body{color:#fff;font-size:1em;font-weight:400;line-height:1.5}html.theme--documenter-dark a{color:#1abc9c;cursor:pointer;text-decoration:none}html.theme--documenter-dark a strong{color:currentColor}html.theme--documenter-dark a:hover{color:#1dd2af}html.theme--documenter-dark code{background-color:rgba(255,255,255,0.05);color:#ececec;font-size:.875em;font-weight:normal;padding:.1em}html.theme--documenter-dark hr{background-color:#282f2f;border:none;display:block;height:2px;margin:1.5rem 0}html.theme--documenter-dark img{height:auto;max-width:100%}html.theme--documenter-dark input[type="checkbox"],html.theme--documenter-dark input[type="radio"]{vertical-align:baseline}html.theme--documenter-dark small{font-size:.875em}html.theme--documenter-dark span{font-style:inherit;font-weight:inherit}html.theme--documenter-dark strong{color:#f2f2f2;font-weight:700}html.theme--documenter-dark fieldset{border:none}html.theme--documenter-dark pre{-webkit-overflow-scrolling:touch;background-color:#282f2f;color:#fff;font-size:.875em;overflow-x:auto;padding:1.25rem 1.5rem;white-space:pre;word-wrap:normal}html.theme--documenter-dark pre code{background-color:transparent;color:currentColor;font-size:1em;padding:0}html.theme--documenter-dark table td,html.theme--documenter-dark table th{vertical-align:top}html.theme--documenter-dark table td:not([align]),html.theme--documenter-dark table th:not([align]){text-align:inherit}html.theme--documenter-dark table th{color:#f2f2f2}html.theme--documenter-dark .box{background-color:#343c3d;border-radius:8px;box-shadow:none;color:#fff;display:block;padding:1.25rem}html.theme--documenter-dark a.box:hover,html.theme--documenter-dark a.box:focus{box-shadow:0 0.5em 1em -0.125em rgba(10,10,10,0.1),0 0 0 1px #1abc9c}html.theme--documenter-dark a.box:active{box-shadow:inset 0 1px 2px rgba(10,10,10,0.2),0 0 0 1px #1abc9c}html.theme--documenter-dark .button{background-color:#282f2f;border-color:#4c5759;border-width:1px;color:#375a7f;cursor:pointer;justify-content:center;padding-bottom:calc(0.5em - 1px);padding-left:1em;padding-right:1em;padding-top:calc(0.5em - 1px);text-align:center;white-space:nowrap}html.theme--documenter-dark .button strong{color:inherit}html.theme--documenter-dark .button .icon,html.theme--documenter-dark .button .icon.is-small,html.theme--documenter-dark .button #documenter .docs-sidebar form.docs-search>input.icon,html.theme--documenter-dark #documenter .docs-sidebar .button form.docs-search>input.icon,html.theme--documenter-dark .button .icon.is-medium,html.theme--documenter-dark .button .icon.is-large{height:1.5em;width:1.5em}html.theme--documenter-dark .button .icon:first-child:not(:last-child){margin-left:calc(-0.5em - 1px);margin-right:.25em}html.theme--documenter-dark .button .icon:last-child:not(:first-child){margin-left:.25em;margin-right:calc(-0.5em - 1px)}html.theme--documenter-dark .button .icon:first-child:last-child{margin-left:calc(-0.5em - 1px);margin-right:calc(-0.5em - 1px)}html.theme--documenter-dark .button:hover,html.theme--documenter-dark .button.is-hovered{border-color:#8c9b9d;color:#f2f2f2}html.theme--documenter-dark .button:focus,html.theme--documenter-dark .button.is-focused{border-color:#8c9b9d;color:#17a689}html.theme--documenter-dark .button:focus:not(:active),html.theme--documenter-dark .button.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(26,188,156,0.25)}html.theme--documenter-dark .button:active,html.theme--documenter-dark .button.is-active{border-color:#343c3d;color:#f2f2f2}html.theme--documenter-dark .button.is-text{background-color:transparent;border-color:transparent;color:#fff;text-decoration:underline}html.theme--documenter-dark .button.is-text:hover,html.theme--documenter-dark .button.is-text.is-hovered,html.theme--documenter-dark .button.is-text:focus,html.theme--documenter-dark .button.is-text.is-focused{background-color:#282f2f;color:#f2f2f2}html.theme--documenter-dark .button.is-text:active,html.theme--documenter-dark .button.is-text.is-active{background-color:#1d2122;color:#f2f2f2}html.theme--documenter-dark .button.is-text[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-text{background-color:transparent;border-color:transparent;box-shadow:none}html.theme--documenter-dark .button.is-ghost{background:none;border-color:rgba(0,0,0,0);color:#1abc9c;text-decoration:none}html.theme--documenter-dark .button.is-ghost:hover,html.theme--documenter-dark .button.is-ghost.is-hovered{color:#1abc9c;text-decoration:underline}html.theme--documenter-dark .button.is-white{background-color:#fff;border-color:transparent;color:#0a0a0a}html.theme--documenter-dark .button.is-white:hover,html.theme--documenter-dark .button.is-white.is-hovered{background-color:#f9f9f9;border-color:transparent;color:#0a0a0a}html.theme--documenter-dark .button.is-white:focus,html.theme--documenter-dark .button.is-white.is-focused{border-color:transparent;color:#0a0a0a}html.theme--documenter-dark .button.is-white:focus:not(:active),html.theme--documenter-dark .button.is-white.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(255,255,255,0.25)}html.theme--documenter-dark .button.is-white:active,html.theme--documenter-dark .button.is-white.is-active{background-color:#f2f2f2;border-color:transparent;color:#0a0a0a}html.theme--documenter-dark .button.is-white[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-white{background-color:#fff;border-color:#fff;box-shadow:none}html.theme--documenter-dark .button.is-white.is-inverted{background-color:#0a0a0a;color:#fff}html.theme--documenter-dark .button.is-white.is-inverted:hover,html.theme--documenter-dark .button.is-white.is-inverted.is-hovered{background-color:#000}html.theme--documenter-dark .button.is-white.is-inverted[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-white.is-inverted{background-color:#0a0a0a;border-color:transparent;box-shadow:none;color:#fff}html.theme--documenter-dark .button.is-white.is-loading::after{border-color:transparent transparent #0a0a0a #0a0a0a !important}html.theme--documenter-dark .button.is-white.is-outlined{background-color:transparent;border-color:#fff;color:#fff}html.theme--documenter-dark .button.is-white.is-outlined:hover,html.theme--documenter-dark .button.is-white.is-outlined.is-hovered,html.theme--documenter-dark .button.is-white.is-outlined:focus,html.theme--documenter-dark .button.is-white.is-outlined.is-focused{background-color:#fff;border-color:#fff;color:#0a0a0a}html.theme--documenter-dark .button.is-white.is-outlined.is-loading::after{border-color:transparent transparent #fff #fff !important}html.theme--documenter-dark .button.is-white.is-outlined.is-loading:hover::after,html.theme--documenter-dark .button.is-white.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .button.is-white.is-outlined.is-loading:focus::after,html.theme--documenter-dark .button.is-white.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #0a0a0a #0a0a0a !important}html.theme--documenter-dark .button.is-white.is-outlined[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-white.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--documenter-dark .button.is-white.is-inverted.is-outlined{background-color:transparent;border-color:#0a0a0a;color:#0a0a0a}html.theme--documenter-dark .button.is-white.is-inverted.is-outlined:hover,html.theme--documenter-dark .button.is-white.is-inverted.is-outlined.is-hovered,html.theme--documenter-dark .button.is-white.is-inverted.is-outlined:focus,html.theme--documenter-dark .button.is-white.is-inverted.is-outlined.is-focused{background-color:#0a0a0a;color:#fff}html.theme--documenter-dark .button.is-white.is-inverted.is-outlined.is-loading:hover::after,html.theme--documenter-dark .button.is-white.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .button.is-white.is-inverted.is-outlined.is-loading:focus::after,html.theme--documenter-dark .button.is-white.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}html.theme--documenter-dark .button.is-white.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-white.is-inverted.is-outlined{background-color:transparent;border-color:#0a0a0a;box-shadow:none;color:#0a0a0a}html.theme--documenter-dark .button.is-black{background-color:#0a0a0a;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-black:hover,html.theme--documenter-dark .button.is-black.is-hovered{background-color:#040404;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-black:focus,html.theme--documenter-dark .button.is-black.is-focused{border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-black:focus:not(:active),html.theme--documenter-dark .button.is-black.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(10,10,10,0.25)}html.theme--documenter-dark .button.is-black:active,html.theme--documenter-dark .button.is-black.is-active{background-color:#000;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-black[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-black{background-color:#0a0a0a;border-color:#0a0a0a;box-shadow:none}html.theme--documenter-dark .button.is-black.is-inverted{background-color:#fff;color:#0a0a0a}html.theme--documenter-dark .button.is-black.is-inverted:hover,html.theme--documenter-dark .button.is-black.is-inverted.is-hovered{background-color:#f2f2f2}html.theme--documenter-dark .button.is-black.is-inverted[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-black.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#0a0a0a}html.theme--documenter-dark .button.is-black.is-loading::after{border-color:transparent transparent #fff #fff !important}html.theme--documenter-dark .button.is-black.is-outlined{background-color:transparent;border-color:#0a0a0a;color:#0a0a0a}html.theme--documenter-dark .button.is-black.is-outlined:hover,html.theme--documenter-dark .button.is-black.is-outlined.is-hovered,html.theme--documenter-dark .button.is-black.is-outlined:focus,html.theme--documenter-dark .button.is-black.is-outlined.is-focused{background-color:#0a0a0a;border-color:#0a0a0a;color:#fff}html.theme--documenter-dark .button.is-black.is-outlined.is-loading::after{border-color:transparent transparent #0a0a0a #0a0a0a !important}html.theme--documenter-dark .button.is-black.is-outlined.is-loading:hover::after,html.theme--documenter-dark .button.is-black.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .button.is-black.is-outlined.is-loading:focus::after,html.theme--documenter-dark .button.is-black.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}html.theme--documenter-dark .button.is-black.is-outlined[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-black.is-outlined{background-color:transparent;border-color:#0a0a0a;box-shadow:none;color:#0a0a0a}html.theme--documenter-dark .button.is-black.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}html.theme--documenter-dark .button.is-black.is-inverted.is-outlined:hover,html.theme--documenter-dark .button.is-black.is-inverted.is-outlined.is-hovered,html.theme--documenter-dark .button.is-black.is-inverted.is-outlined:focus,html.theme--documenter-dark .button.is-black.is-inverted.is-outlined.is-focused{background-color:#fff;color:#0a0a0a}html.theme--documenter-dark .button.is-black.is-inverted.is-outlined.is-loading:hover::after,html.theme--documenter-dark .button.is-black.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .button.is-black.is-inverted.is-outlined.is-loading:focus::after,html.theme--documenter-dark .button.is-black.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #0a0a0a #0a0a0a !important}html.theme--documenter-dark .button.is-black.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-black.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--documenter-dark .button.is-light{background-color:#ecf0f1;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .button.is-light:hover,html.theme--documenter-dark .button.is-light.is-hovered{background-color:#e5eaec;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .button.is-light:focus,html.theme--documenter-dark .button.is-light.is-focused{border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .button.is-light:focus:not(:active),html.theme--documenter-dark .button.is-light.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(236,240,241,0.25)}html.theme--documenter-dark .button.is-light:active,html.theme--documenter-dark .button.is-light.is-active{background-color:#dde4e6;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .button.is-light[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-light{background-color:#ecf0f1;border-color:#ecf0f1;box-shadow:none}html.theme--documenter-dark .button.is-light.is-inverted{background-color:rgba(0,0,0,0.7);color:#ecf0f1}html.theme--documenter-dark .button.is-light.is-inverted:hover,html.theme--documenter-dark .button.is-light.is-inverted.is-hovered{background-color:rgba(0,0,0,0.7)}html.theme--documenter-dark .button.is-light.is-inverted[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-light.is-inverted{background-color:rgba(0,0,0,0.7);border-color:transparent;box-shadow:none;color:#ecf0f1}html.theme--documenter-dark .button.is-light.is-loading::after{border-color:transparent transparent rgba(0,0,0,0.7) rgba(0,0,0,0.7) !important}html.theme--documenter-dark .button.is-light.is-outlined{background-color:transparent;border-color:#ecf0f1;color:#ecf0f1}html.theme--documenter-dark .button.is-light.is-outlined:hover,html.theme--documenter-dark .button.is-light.is-outlined.is-hovered,html.theme--documenter-dark .button.is-light.is-outlined:focus,html.theme--documenter-dark .button.is-light.is-outlined.is-focused{background-color:#ecf0f1;border-color:#ecf0f1;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .button.is-light.is-outlined.is-loading::after{border-color:transparent transparent #ecf0f1 #ecf0f1 !important}html.theme--documenter-dark .button.is-light.is-outlined.is-loading:hover::after,html.theme--documenter-dark .button.is-light.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .button.is-light.is-outlined.is-loading:focus::after,html.theme--documenter-dark .button.is-light.is-outlined.is-loading.is-focused::after{border-color:transparent transparent rgba(0,0,0,0.7) rgba(0,0,0,0.7) !important}html.theme--documenter-dark .button.is-light.is-outlined[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-light.is-outlined{background-color:transparent;border-color:#ecf0f1;box-shadow:none;color:#ecf0f1}html.theme--documenter-dark .button.is-light.is-inverted.is-outlined{background-color:transparent;border-color:rgba(0,0,0,0.7);color:rgba(0,0,0,0.7)}html.theme--documenter-dark .button.is-light.is-inverted.is-outlined:hover,html.theme--documenter-dark .button.is-light.is-inverted.is-outlined.is-hovered,html.theme--documenter-dark .button.is-light.is-inverted.is-outlined:focus,html.theme--documenter-dark .button.is-light.is-inverted.is-outlined.is-focused{background-color:rgba(0,0,0,0.7);color:#ecf0f1}html.theme--documenter-dark .button.is-light.is-inverted.is-outlined.is-loading:hover::after,html.theme--documenter-dark .button.is-light.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .button.is-light.is-inverted.is-outlined.is-loading:focus::after,html.theme--documenter-dark .button.is-light.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #ecf0f1 #ecf0f1 !important}html.theme--documenter-dark .button.is-light.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-light.is-inverted.is-outlined{background-color:transparent;border-color:rgba(0,0,0,0.7);box-shadow:none;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .button.is-dark,html.theme--documenter-dark .content kbd.button{background-color:#282f2f;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-dark:hover,html.theme--documenter-dark .content kbd.button:hover,html.theme--documenter-dark .button.is-dark.is-hovered,html.theme--documenter-dark .content kbd.button.is-hovered{background-color:#232829;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-dark:focus,html.theme--documenter-dark .content kbd.button:focus,html.theme--documenter-dark .button.is-dark.is-focused,html.theme--documenter-dark .content kbd.button.is-focused{border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-dark:focus:not(:active),html.theme--documenter-dark .content kbd.button:focus:not(:active),html.theme--documenter-dark .button.is-dark.is-focused:not(:active),html.theme--documenter-dark .content kbd.button.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(40,47,47,0.25)}html.theme--documenter-dark .button.is-dark:active,html.theme--documenter-dark .content kbd.button:active,html.theme--documenter-dark .button.is-dark.is-active,html.theme--documenter-dark .content kbd.button.is-active{background-color:#1d2122;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-dark[disabled],html.theme--documenter-dark .content kbd.button[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-dark,fieldset[disabled] html.theme--documenter-dark .content kbd.button{background-color:#282f2f;border-color:#282f2f;box-shadow:none}html.theme--documenter-dark .button.is-dark.is-inverted,html.theme--documenter-dark .content kbd.button.is-inverted{background-color:#fff;color:#282f2f}html.theme--documenter-dark .button.is-dark.is-inverted:hover,html.theme--documenter-dark .content kbd.button.is-inverted:hover,html.theme--documenter-dark .button.is-dark.is-inverted.is-hovered,html.theme--documenter-dark .content kbd.button.is-inverted.is-hovered{background-color:#f2f2f2}html.theme--documenter-dark .button.is-dark.is-inverted[disabled],html.theme--documenter-dark .content kbd.button.is-inverted[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-dark.is-inverted,fieldset[disabled] html.theme--documenter-dark .content kbd.button.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#282f2f}html.theme--documenter-dark .button.is-dark.is-loading::after,html.theme--documenter-dark .content kbd.button.is-loading::after{border-color:transparent transparent #fff #fff !important}html.theme--documenter-dark .button.is-dark.is-outlined,html.theme--documenter-dark .content kbd.button.is-outlined{background-color:transparent;border-color:#282f2f;color:#282f2f}html.theme--documenter-dark .button.is-dark.is-outlined:hover,html.theme--documenter-dark .content kbd.button.is-outlined:hover,html.theme--documenter-dark .button.is-dark.is-outlined.is-hovered,html.theme--documenter-dark .content kbd.button.is-outlined.is-hovered,html.theme--documenter-dark .button.is-dark.is-outlined:focus,html.theme--documenter-dark .content kbd.button.is-outlined:focus,html.theme--documenter-dark .button.is-dark.is-outlined.is-focused,html.theme--documenter-dark .content kbd.button.is-outlined.is-focused{background-color:#282f2f;border-color:#282f2f;color:#fff}html.theme--documenter-dark .button.is-dark.is-outlined.is-loading::after,html.theme--documenter-dark .content kbd.button.is-outlined.is-loading::after{border-color:transparent transparent #282f2f #282f2f !important}html.theme--documenter-dark .button.is-dark.is-outlined.is-loading:hover::after,html.theme--documenter-dark .content kbd.button.is-outlined.is-loading:hover::after,html.theme--documenter-dark .button.is-dark.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .content kbd.button.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .button.is-dark.is-outlined.is-loading:focus::after,html.theme--documenter-dark .content kbd.button.is-outlined.is-loading:focus::after,html.theme--documenter-dark .button.is-dark.is-outlined.is-loading.is-focused::after,html.theme--documenter-dark .content kbd.button.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}html.theme--documenter-dark .button.is-dark.is-outlined[disabled],html.theme--documenter-dark .content kbd.button.is-outlined[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-dark.is-outlined,fieldset[disabled] html.theme--documenter-dark .content kbd.button.is-outlined{background-color:transparent;border-color:#282f2f;box-shadow:none;color:#282f2f}html.theme--documenter-dark .button.is-dark.is-inverted.is-outlined,html.theme--documenter-dark .content kbd.button.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}html.theme--documenter-dark .button.is-dark.is-inverted.is-outlined:hover,html.theme--documenter-dark .content kbd.button.is-inverted.is-outlined:hover,html.theme--documenter-dark .button.is-dark.is-inverted.is-outlined.is-hovered,html.theme--documenter-dark .content kbd.button.is-inverted.is-outlined.is-hovered,html.theme--documenter-dark .button.is-dark.is-inverted.is-outlined:focus,html.theme--documenter-dark .content kbd.button.is-inverted.is-outlined:focus,html.theme--documenter-dark .button.is-dark.is-inverted.is-outlined.is-focused,html.theme--documenter-dark .content kbd.button.is-inverted.is-outlined.is-focused{background-color:#fff;color:#282f2f}html.theme--documenter-dark .button.is-dark.is-inverted.is-outlined.is-loading:hover::after,html.theme--documenter-dark .content kbd.button.is-inverted.is-outlined.is-loading:hover::after,html.theme--documenter-dark .button.is-dark.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .content kbd.button.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .button.is-dark.is-inverted.is-outlined.is-loading:focus::after,html.theme--documenter-dark .content kbd.button.is-inverted.is-outlined.is-loading:focus::after,html.theme--documenter-dark .button.is-dark.is-inverted.is-outlined.is-loading.is-focused::after,html.theme--documenter-dark .content kbd.button.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #282f2f #282f2f !important}html.theme--documenter-dark .button.is-dark.is-inverted.is-outlined[disabled],html.theme--documenter-dark .content kbd.button.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-dark.is-inverted.is-outlined,fieldset[disabled] html.theme--documenter-dark .content kbd.button.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--documenter-dark .button.is-primary,html.theme--documenter-dark .docstring>section>a.button.docs-sourcelink{background-color:#375a7f;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-primary:hover,html.theme--documenter-dark .docstring>section>a.button.docs-sourcelink:hover,html.theme--documenter-dark .button.is-primary.is-hovered,html.theme--documenter-dark .docstring>section>a.button.is-hovered.docs-sourcelink{background-color:#335476;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-primary:focus,html.theme--documenter-dark .docstring>section>a.button.docs-sourcelink:focus,html.theme--documenter-dark .button.is-primary.is-focused,html.theme--documenter-dark .docstring>section>a.button.is-focused.docs-sourcelink{border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-primary:focus:not(:active),html.theme--documenter-dark .docstring>section>a.button.docs-sourcelink:focus:not(:active),html.theme--documenter-dark .button.is-primary.is-focused:not(:active),html.theme--documenter-dark .docstring>section>a.button.is-focused.docs-sourcelink:not(:active){box-shadow:0 0 0 0.125em rgba(55,90,127,0.25)}html.theme--documenter-dark .button.is-primary:active,html.theme--documenter-dark .docstring>section>a.button.docs-sourcelink:active,html.theme--documenter-dark .button.is-primary.is-active,html.theme--documenter-dark .docstring>section>a.button.is-active.docs-sourcelink{background-color:#2f4d6d;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-primary[disabled],html.theme--documenter-dark .docstring>section>a.button.docs-sourcelink[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-primary,fieldset[disabled] html.theme--documenter-dark .docstring>section>a.button.docs-sourcelink{background-color:#375a7f;border-color:#375a7f;box-shadow:none}html.theme--documenter-dark .button.is-primary.is-inverted,html.theme--documenter-dark .docstring>section>a.button.is-inverted.docs-sourcelink{background-color:#fff;color:#375a7f}html.theme--documenter-dark .button.is-primary.is-inverted:hover,html.theme--documenter-dark .docstring>section>a.button.is-inverted.docs-sourcelink:hover,html.theme--documenter-dark .button.is-primary.is-inverted.is-hovered,html.theme--documenter-dark .docstring>section>a.button.is-inverted.is-hovered.docs-sourcelink{background-color:#f2f2f2}html.theme--documenter-dark .button.is-primary.is-inverted[disabled],html.theme--documenter-dark .docstring>section>a.button.is-inverted.docs-sourcelink[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-primary.is-inverted,fieldset[disabled] html.theme--documenter-dark .docstring>section>a.button.is-inverted.docs-sourcelink{background-color:#fff;border-color:transparent;box-shadow:none;color:#375a7f}html.theme--documenter-dark .button.is-primary.is-loading::after,html.theme--documenter-dark .docstring>section>a.button.is-loading.docs-sourcelink::after{border-color:transparent transparent #fff #fff !important}html.theme--documenter-dark .button.is-primary.is-outlined,html.theme--documenter-dark .docstring>section>a.button.is-outlined.docs-sourcelink{background-color:transparent;border-color:#375a7f;color:#375a7f}html.theme--documenter-dark .button.is-primary.is-outlined:hover,html.theme--documenter-dark .docstring>section>a.button.is-outlined.docs-sourcelink:hover,html.theme--documenter-dark .button.is-primary.is-outlined.is-hovered,html.theme--documenter-dark .docstring>section>a.button.is-outlined.is-hovered.docs-sourcelink,html.theme--documenter-dark .button.is-primary.is-outlined:focus,html.theme--documenter-dark .docstring>section>a.button.is-outlined.docs-sourcelink:focus,html.theme--documenter-dark .button.is-primary.is-outlined.is-focused,html.theme--documenter-dark .docstring>section>a.button.is-outlined.is-focused.docs-sourcelink{background-color:#375a7f;border-color:#375a7f;color:#fff}html.theme--documenter-dark .button.is-primary.is-outlined.is-loading::after,html.theme--documenter-dark .docstring>section>a.button.is-outlined.is-loading.docs-sourcelink::after{border-color:transparent transparent #375a7f #375a7f !important}html.theme--documenter-dark .button.is-primary.is-outlined.is-loading:hover::after,html.theme--documenter-dark .docstring>section>a.button.is-outlined.is-loading.docs-sourcelink:hover::after,html.theme--documenter-dark .button.is-primary.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .docstring>section>a.button.is-outlined.is-loading.is-hovered.docs-sourcelink::after,html.theme--documenter-dark .button.is-primary.is-outlined.is-loading:focus::after,html.theme--documenter-dark .docstring>section>a.button.is-outlined.is-loading.docs-sourcelink:focus::after,html.theme--documenter-dark .button.is-primary.is-outlined.is-loading.is-focused::after,html.theme--documenter-dark .docstring>section>a.button.is-outlined.is-loading.is-focused.docs-sourcelink::after{border-color:transparent transparent #fff #fff !important}html.theme--documenter-dark .button.is-primary.is-outlined[disabled],html.theme--documenter-dark .docstring>section>a.button.is-outlined.docs-sourcelink[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-primary.is-outlined,fieldset[disabled] html.theme--documenter-dark .docstring>section>a.button.is-outlined.docs-sourcelink{background-color:transparent;border-color:#375a7f;box-shadow:none;color:#375a7f}html.theme--documenter-dark .button.is-primary.is-inverted.is-outlined,html.theme--documenter-dark .docstring>section>a.button.is-inverted.is-outlined.docs-sourcelink{background-color:transparent;border-color:#fff;color:#fff}html.theme--documenter-dark .button.is-primary.is-inverted.is-outlined:hover,html.theme--documenter-dark .docstring>section>a.button.is-inverted.is-outlined.docs-sourcelink:hover,html.theme--documenter-dark .button.is-primary.is-inverted.is-outlined.is-hovered,html.theme--documenter-dark .docstring>section>a.button.is-inverted.is-outlined.is-hovered.docs-sourcelink,html.theme--documenter-dark .button.is-primary.is-inverted.is-outlined:focus,html.theme--documenter-dark .docstring>section>a.button.is-inverted.is-outlined.docs-sourcelink:focus,html.theme--documenter-dark .button.is-primary.is-inverted.is-outlined.is-focused,html.theme--documenter-dark .docstring>section>a.button.is-inverted.is-outlined.is-focused.docs-sourcelink{background-color:#fff;color:#375a7f}html.theme--documenter-dark .button.is-primary.is-inverted.is-outlined.is-loading:hover::after,html.theme--documenter-dark .docstring>section>a.button.is-inverted.is-outlined.is-loading.docs-sourcelink:hover::after,html.theme--documenter-dark .button.is-primary.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .docstring>section>a.button.is-inverted.is-outlined.is-loading.is-hovered.docs-sourcelink::after,html.theme--documenter-dark .button.is-primary.is-inverted.is-outlined.is-loading:focus::after,html.theme--documenter-dark .docstring>section>a.button.is-inverted.is-outlined.is-loading.docs-sourcelink:focus::after,html.theme--documenter-dark .button.is-primary.is-inverted.is-outlined.is-loading.is-focused::after,html.theme--documenter-dark .docstring>section>a.button.is-inverted.is-outlined.is-loading.is-focused.docs-sourcelink::after{border-color:transparent transparent #375a7f #375a7f !important}html.theme--documenter-dark .button.is-primary.is-inverted.is-outlined[disabled],html.theme--documenter-dark .docstring>section>a.button.is-inverted.is-outlined.docs-sourcelink[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-primary.is-inverted.is-outlined,fieldset[disabled] html.theme--documenter-dark .docstring>section>a.button.is-inverted.is-outlined.docs-sourcelink{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--documenter-dark .button.is-primary.is-light,html.theme--documenter-dark .docstring>section>a.button.is-light.docs-sourcelink{background-color:#f1f5f9;color:#4d7eb2}html.theme--documenter-dark .button.is-primary.is-light:hover,html.theme--documenter-dark .docstring>section>a.button.is-light.docs-sourcelink:hover,html.theme--documenter-dark .button.is-primary.is-light.is-hovered,html.theme--documenter-dark .docstring>section>a.button.is-light.is-hovered.docs-sourcelink{background-color:#e8eef5;border-color:transparent;color:#4d7eb2}html.theme--documenter-dark .button.is-primary.is-light:active,html.theme--documenter-dark .docstring>section>a.button.is-light.docs-sourcelink:active,html.theme--documenter-dark .button.is-primary.is-light.is-active,html.theme--documenter-dark .docstring>section>a.button.is-light.is-active.docs-sourcelink{background-color:#dfe8f1;border-color:transparent;color:#4d7eb2}html.theme--documenter-dark .button.is-link{background-color:#1abc9c;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-link:hover,html.theme--documenter-dark .button.is-link.is-hovered{background-color:#18b193;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-link:focus,html.theme--documenter-dark .button.is-link.is-focused{border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-link:focus:not(:active),html.theme--documenter-dark .button.is-link.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(26,188,156,0.25)}html.theme--documenter-dark .button.is-link:active,html.theme--documenter-dark .button.is-link.is-active{background-color:#17a689;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-link[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-link{background-color:#1abc9c;border-color:#1abc9c;box-shadow:none}html.theme--documenter-dark .button.is-link.is-inverted{background-color:#fff;color:#1abc9c}html.theme--documenter-dark .button.is-link.is-inverted:hover,html.theme--documenter-dark .button.is-link.is-inverted.is-hovered{background-color:#f2f2f2}html.theme--documenter-dark .button.is-link.is-inverted[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-link.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#1abc9c}html.theme--documenter-dark .button.is-link.is-loading::after{border-color:transparent transparent #fff #fff !important}html.theme--documenter-dark .button.is-link.is-outlined{background-color:transparent;border-color:#1abc9c;color:#1abc9c}html.theme--documenter-dark .button.is-link.is-outlined:hover,html.theme--documenter-dark .button.is-link.is-outlined.is-hovered,html.theme--documenter-dark .button.is-link.is-outlined:focus,html.theme--documenter-dark .button.is-link.is-outlined.is-focused{background-color:#1abc9c;border-color:#1abc9c;color:#fff}html.theme--documenter-dark .button.is-link.is-outlined.is-loading::after{border-color:transparent transparent #1abc9c #1abc9c !important}html.theme--documenter-dark .button.is-link.is-outlined.is-loading:hover::after,html.theme--documenter-dark .button.is-link.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .button.is-link.is-outlined.is-loading:focus::after,html.theme--documenter-dark .button.is-link.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}html.theme--documenter-dark .button.is-link.is-outlined[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-link.is-outlined{background-color:transparent;border-color:#1abc9c;box-shadow:none;color:#1abc9c}html.theme--documenter-dark .button.is-link.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}html.theme--documenter-dark .button.is-link.is-inverted.is-outlined:hover,html.theme--documenter-dark .button.is-link.is-inverted.is-outlined.is-hovered,html.theme--documenter-dark .button.is-link.is-inverted.is-outlined:focus,html.theme--documenter-dark .button.is-link.is-inverted.is-outlined.is-focused{background-color:#fff;color:#1abc9c}html.theme--documenter-dark .button.is-link.is-inverted.is-outlined.is-loading:hover::after,html.theme--documenter-dark .button.is-link.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .button.is-link.is-inverted.is-outlined.is-loading:focus::after,html.theme--documenter-dark .button.is-link.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #1abc9c #1abc9c !important}html.theme--documenter-dark .button.is-link.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-link.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--documenter-dark .button.is-link.is-light{background-color:#edfdf9;color:#15987e}html.theme--documenter-dark .button.is-link.is-light:hover,html.theme--documenter-dark .button.is-link.is-light.is-hovered{background-color:#e2fbf6;border-color:transparent;color:#15987e}html.theme--documenter-dark .button.is-link.is-light:active,html.theme--documenter-dark .button.is-link.is-light.is-active{background-color:#d7f9f3;border-color:transparent;color:#15987e}html.theme--documenter-dark .button.is-info{background-color:#024c7d;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-info:hover,html.theme--documenter-dark .button.is-info.is-hovered{background-color:#024470;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-info:focus,html.theme--documenter-dark .button.is-info.is-focused{border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-info:focus:not(:active),html.theme--documenter-dark .button.is-info.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(2,76,125,0.25)}html.theme--documenter-dark .button.is-info:active,html.theme--documenter-dark .button.is-info.is-active{background-color:#023d64;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-info[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-info{background-color:#024c7d;border-color:#024c7d;box-shadow:none}html.theme--documenter-dark .button.is-info.is-inverted{background-color:#fff;color:#024c7d}html.theme--documenter-dark .button.is-info.is-inverted:hover,html.theme--documenter-dark .button.is-info.is-inverted.is-hovered{background-color:#f2f2f2}html.theme--documenter-dark .button.is-info.is-inverted[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-info.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#024c7d}html.theme--documenter-dark .button.is-info.is-loading::after{border-color:transparent transparent #fff #fff !important}html.theme--documenter-dark .button.is-info.is-outlined{background-color:transparent;border-color:#024c7d;color:#024c7d}html.theme--documenter-dark .button.is-info.is-outlined:hover,html.theme--documenter-dark .button.is-info.is-outlined.is-hovered,html.theme--documenter-dark .button.is-info.is-outlined:focus,html.theme--documenter-dark .button.is-info.is-outlined.is-focused{background-color:#024c7d;border-color:#024c7d;color:#fff}html.theme--documenter-dark .button.is-info.is-outlined.is-loading::after{border-color:transparent transparent #024c7d #024c7d !important}html.theme--documenter-dark .button.is-info.is-outlined.is-loading:hover::after,html.theme--documenter-dark .button.is-info.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .button.is-info.is-outlined.is-loading:focus::after,html.theme--documenter-dark .button.is-info.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}html.theme--documenter-dark .button.is-info.is-outlined[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-info.is-outlined{background-color:transparent;border-color:#024c7d;box-shadow:none;color:#024c7d}html.theme--documenter-dark .button.is-info.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}html.theme--documenter-dark .button.is-info.is-inverted.is-outlined:hover,html.theme--documenter-dark .button.is-info.is-inverted.is-outlined.is-hovered,html.theme--documenter-dark .button.is-info.is-inverted.is-outlined:focus,html.theme--documenter-dark .button.is-info.is-inverted.is-outlined.is-focused{background-color:#fff;color:#024c7d}html.theme--documenter-dark .button.is-info.is-inverted.is-outlined.is-loading:hover::after,html.theme--documenter-dark .button.is-info.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .button.is-info.is-inverted.is-outlined.is-loading:focus::after,html.theme--documenter-dark .button.is-info.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #024c7d #024c7d !important}html.theme--documenter-dark .button.is-info.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-info.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--documenter-dark .button.is-info.is-light{background-color:#ebf7ff;color:#0e9dfb}html.theme--documenter-dark .button.is-info.is-light:hover,html.theme--documenter-dark .button.is-info.is-light.is-hovered{background-color:#def2fe;border-color:transparent;color:#0e9dfb}html.theme--documenter-dark .button.is-info.is-light:active,html.theme--documenter-dark .button.is-info.is-light.is-active{background-color:#d2edfe;border-color:transparent;color:#0e9dfb}html.theme--documenter-dark .button.is-success{background-color:#008438;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-success:hover,html.theme--documenter-dark .button.is-success.is-hovered{background-color:#073;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-success:focus,html.theme--documenter-dark .button.is-success.is-focused{border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-success:focus:not(:active),html.theme--documenter-dark .button.is-success.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(0,132,56,0.25)}html.theme--documenter-dark .button.is-success:active,html.theme--documenter-dark .button.is-success.is-active{background-color:#006b2d;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-success[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-success{background-color:#008438;border-color:#008438;box-shadow:none}html.theme--documenter-dark .button.is-success.is-inverted{background-color:#fff;color:#008438}html.theme--documenter-dark .button.is-success.is-inverted:hover,html.theme--documenter-dark .button.is-success.is-inverted.is-hovered{background-color:#f2f2f2}html.theme--documenter-dark .button.is-success.is-inverted[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-success.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#008438}html.theme--documenter-dark .button.is-success.is-loading::after{border-color:transparent transparent #fff #fff !important}html.theme--documenter-dark .button.is-success.is-outlined{background-color:transparent;border-color:#008438;color:#008438}html.theme--documenter-dark .button.is-success.is-outlined:hover,html.theme--documenter-dark .button.is-success.is-outlined.is-hovered,html.theme--documenter-dark .button.is-success.is-outlined:focus,html.theme--documenter-dark .button.is-success.is-outlined.is-focused{background-color:#008438;border-color:#008438;color:#fff}html.theme--documenter-dark .button.is-success.is-outlined.is-loading::after{border-color:transparent transparent #008438 #008438 !important}html.theme--documenter-dark .button.is-success.is-outlined.is-loading:hover::after,html.theme--documenter-dark .button.is-success.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .button.is-success.is-outlined.is-loading:focus::after,html.theme--documenter-dark .button.is-success.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}html.theme--documenter-dark .button.is-success.is-outlined[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-success.is-outlined{background-color:transparent;border-color:#008438;box-shadow:none;color:#008438}html.theme--documenter-dark .button.is-success.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}html.theme--documenter-dark .button.is-success.is-inverted.is-outlined:hover,html.theme--documenter-dark .button.is-success.is-inverted.is-outlined.is-hovered,html.theme--documenter-dark .button.is-success.is-inverted.is-outlined:focus,html.theme--documenter-dark .button.is-success.is-inverted.is-outlined.is-focused{background-color:#fff;color:#008438}html.theme--documenter-dark .button.is-success.is-inverted.is-outlined.is-loading:hover::after,html.theme--documenter-dark .button.is-success.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .button.is-success.is-inverted.is-outlined.is-loading:focus::after,html.theme--documenter-dark .button.is-success.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #008438 #008438 !important}html.theme--documenter-dark .button.is-success.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-success.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--documenter-dark .button.is-success.is-light{background-color:#ebfff3;color:#00eb64}html.theme--documenter-dark .button.is-success.is-light:hover,html.theme--documenter-dark .button.is-success.is-light.is-hovered{background-color:#deffec;border-color:transparent;color:#00eb64}html.theme--documenter-dark .button.is-success.is-light:active,html.theme--documenter-dark .button.is-success.is-light.is-active{background-color:#d1ffe5;border-color:transparent;color:#00eb64}html.theme--documenter-dark .button.is-warning{background-color:#ad8100;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-warning:hover,html.theme--documenter-dark .button.is-warning.is-hovered{background-color:#a07700;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-warning:focus,html.theme--documenter-dark .button.is-warning.is-focused{border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-warning:focus:not(:active),html.theme--documenter-dark .button.is-warning.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(173,129,0,0.25)}html.theme--documenter-dark .button.is-warning:active,html.theme--documenter-dark .button.is-warning.is-active{background-color:#946e00;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-warning[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-warning{background-color:#ad8100;border-color:#ad8100;box-shadow:none}html.theme--documenter-dark .button.is-warning.is-inverted{background-color:#fff;color:#ad8100}html.theme--documenter-dark .button.is-warning.is-inverted:hover,html.theme--documenter-dark .button.is-warning.is-inverted.is-hovered{background-color:#f2f2f2}html.theme--documenter-dark .button.is-warning.is-inverted[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-warning.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#ad8100}html.theme--documenter-dark .button.is-warning.is-loading::after{border-color:transparent transparent #fff #fff !important}html.theme--documenter-dark .button.is-warning.is-outlined{background-color:transparent;border-color:#ad8100;color:#ad8100}html.theme--documenter-dark .button.is-warning.is-outlined:hover,html.theme--documenter-dark .button.is-warning.is-outlined.is-hovered,html.theme--documenter-dark .button.is-warning.is-outlined:focus,html.theme--documenter-dark .button.is-warning.is-outlined.is-focused{background-color:#ad8100;border-color:#ad8100;color:#fff}html.theme--documenter-dark .button.is-warning.is-outlined.is-loading::after{border-color:transparent transparent #ad8100 #ad8100 !important}html.theme--documenter-dark .button.is-warning.is-outlined.is-loading:hover::after,html.theme--documenter-dark .button.is-warning.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .button.is-warning.is-outlined.is-loading:focus::after,html.theme--documenter-dark .button.is-warning.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}html.theme--documenter-dark .button.is-warning.is-outlined[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-warning.is-outlined{background-color:transparent;border-color:#ad8100;box-shadow:none;color:#ad8100}html.theme--documenter-dark .button.is-warning.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}html.theme--documenter-dark .button.is-warning.is-inverted.is-outlined:hover,html.theme--documenter-dark .button.is-warning.is-inverted.is-outlined.is-hovered,html.theme--documenter-dark .button.is-warning.is-inverted.is-outlined:focus,html.theme--documenter-dark .button.is-warning.is-inverted.is-outlined.is-focused{background-color:#fff;color:#ad8100}html.theme--documenter-dark .button.is-warning.is-inverted.is-outlined.is-loading:hover::after,html.theme--documenter-dark .button.is-warning.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .button.is-warning.is-inverted.is-outlined.is-loading:focus::after,html.theme--documenter-dark .button.is-warning.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #ad8100 #ad8100 !important}html.theme--documenter-dark .button.is-warning.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-warning.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--documenter-dark .button.is-warning.is-light{background-color:#fffaeb;color:#d19c00}html.theme--documenter-dark .button.is-warning.is-light:hover,html.theme--documenter-dark .button.is-warning.is-light.is-hovered{background-color:#fff7de;border-color:transparent;color:#d19c00}html.theme--documenter-dark .button.is-warning.is-light:active,html.theme--documenter-dark .button.is-warning.is-light.is-active{background-color:#fff3d1;border-color:transparent;color:#d19c00}html.theme--documenter-dark .button.is-danger{background-color:#9e1b0d;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-danger:hover,html.theme--documenter-dark .button.is-danger.is-hovered{background-color:#92190c;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-danger:focus,html.theme--documenter-dark .button.is-danger.is-focused{border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-danger:focus:not(:active),html.theme--documenter-dark .button.is-danger.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(158,27,13,0.25)}html.theme--documenter-dark .button.is-danger:active,html.theme--documenter-dark .button.is-danger.is-active{background-color:#86170b;border-color:transparent;color:#fff}html.theme--documenter-dark .button.is-danger[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-danger{background-color:#9e1b0d;border-color:#9e1b0d;box-shadow:none}html.theme--documenter-dark .button.is-danger.is-inverted{background-color:#fff;color:#9e1b0d}html.theme--documenter-dark .button.is-danger.is-inverted:hover,html.theme--documenter-dark .button.is-danger.is-inverted.is-hovered{background-color:#f2f2f2}html.theme--documenter-dark .button.is-danger.is-inverted[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-danger.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#9e1b0d}html.theme--documenter-dark .button.is-danger.is-loading::after{border-color:transparent transparent #fff #fff !important}html.theme--documenter-dark .button.is-danger.is-outlined{background-color:transparent;border-color:#9e1b0d;color:#9e1b0d}html.theme--documenter-dark .button.is-danger.is-outlined:hover,html.theme--documenter-dark .button.is-danger.is-outlined.is-hovered,html.theme--documenter-dark .button.is-danger.is-outlined:focus,html.theme--documenter-dark .button.is-danger.is-outlined.is-focused{background-color:#9e1b0d;border-color:#9e1b0d;color:#fff}html.theme--documenter-dark .button.is-danger.is-outlined.is-loading::after{border-color:transparent transparent #9e1b0d #9e1b0d !important}html.theme--documenter-dark .button.is-danger.is-outlined.is-loading:hover::after,html.theme--documenter-dark .button.is-danger.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .button.is-danger.is-outlined.is-loading:focus::after,html.theme--documenter-dark .button.is-danger.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}html.theme--documenter-dark .button.is-danger.is-outlined[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-danger.is-outlined{background-color:transparent;border-color:#9e1b0d;box-shadow:none;color:#9e1b0d}html.theme--documenter-dark .button.is-danger.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}html.theme--documenter-dark .button.is-danger.is-inverted.is-outlined:hover,html.theme--documenter-dark .button.is-danger.is-inverted.is-outlined.is-hovered,html.theme--documenter-dark .button.is-danger.is-inverted.is-outlined:focus,html.theme--documenter-dark .button.is-danger.is-inverted.is-outlined.is-focused{background-color:#fff;color:#9e1b0d}html.theme--documenter-dark .button.is-danger.is-inverted.is-outlined.is-loading:hover::after,html.theme--documenter-dark .button.is-danger.is-inverted.is-outlined.is-loading.is-hovered::after,html.theme--documenter-dark .button.is-danger.is-inverted.is-outlined.is-loading:focus::after,html.theme--documenter-dark .button.is-danger.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #9e1b0d #9e1b0d !important}html.theme--documenter-dark .button.is-danger.is-inverted.is-outlined[disabled],fieldset[disabled] html.theme--documenter-dark .button.is-danger.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}html.theme--documenter-dark .button.is-danger.is-light{background-color:#fdeeec;color:#ec311d}html.theme--documenter-dark .button.is-danger.is-light:hover,html.theme--documenter-dark .button.is-danger.is-light.is-hovered{background-color:#fce3e0;border-color:transparent;color:#ec311d}html.theme--documenter-dark .button.is-danger.is-light:active,html.theme--documenter-dark .button.is-danger.is-light.is-active{background-color:#fcd8d5;border-color:transparent;color:#ec311d}html.theme--documenter-dark .button.is-small,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.button{font-size:.75rem}html.theme--documenter-dark .button.is-small:not(.is-rounded),html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.button:not(.is-rounded){border-radius:3px}html.theme--documenter-dark .button.is-normal{font-size:1rem}html.theme--documenter-dark .button.is-medium{font-size:1.25rem}html.theme--documenter-dark .button.is-large{font-size:1.5rem}html.theme--documenter-dark .button[disabled],fieldset[disabled] html.theme--documenter-dark .button{background-color:#8c9b9d;border-color:#5e6d6f;box-shadow:none;opacity:.5}html.theme--documenter-dark .button.is-fullwidth{display:flex;width:100%}html.theme--documenter-dark .button.is-loading{color:transparent !important;pointer-events:none}html.theme--documenter-dark .button.is-loading::after{position:absolute;left:calc(50% - (1em * 0.5));top:calc(50% - (1em * 0.5));position:absolute !important}html.theme--documenter-dark .button.is-static{background-color:#282f2f;border-color:#5e6d6f;color:#dbdee0;box-shadow:none;pointer-events:none}html.theme--documenter-dark .button.is-rounded,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.button{border-radius:9999px;padding-left:calc(1em + 0.25em);padding-right:calc(1em + 0.25em)}html.theme--documenter-dark .buttons{align-items:center;display:flex;flex-wrap:wrap;justify-content:flex-start}html.theme--documenter-dark .buttons .button{margin-bottom:0.5rem}html.theme--documenter-dark .buttons .button:not(:last-child):not(.is-fullwidth){margin-right:.5rem}html.theme--documenter-dark .buttons:last-child{margin-bottom:-0.5rem}html.theme--documenter-dark .buttons:not(:last-child){margin-bottom:1rem}html.theme--documenter-dark .buttons.are-small .button:not(.is-normal):not(.is-medium):not(.is-large){font-size:.75rem}html.theme--documenter-dark .buttons.are-small .button:not(.is-normal):not(.is-medium):not(.is-large):not(.is-rounded){border-radius:3px}html.theme--documenter-dark .buttons.are-medium .button:not(.is-small):not(.is-normal):not(.is-large){font-size:1.25rem}html.theme--documenter-dark .buttons.are-large .button:not(.is-small):not(.is-normal):not(.is-medium){font-size:1.5rem}html.theme--documenter-dark .buttons.has-addons .button:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}html.theme--documenter-dark .buttons.has-addons .button:not(:last-child){border-bottom-right-radius:0;border-top-right-radius:0;margin-right:-1px}html.theme--documenter-dark .buttons.has-addons .button:last-child{margin-right:0}html.theme--documenter-dark .buttons.has-addons .button:hover,html.theme--documenter-dark .buttons.has-addons .button.is-hovered{z-index:2}html.theme--documenter-dark .buttons.has-addons .button:focus,html.theme--documenter-dark .buttons.has-addons .button.is-focused,html.theme--documenter-dark .buttons.has-addons .button:active,html.theme--documenter-dark .buttons.has-addons .button.is-active,html.theme--documenter-dark .buttons.has-addons .button.is-selected{z-index:3}html.theme--documenter-dark .buttons.has-addons .button:focus:hover,html.theme--documenter-dark .buttons.has-addons .button.is-focused:hover,html.theme--documenter-dark .buttons.has-addons .button:active:hover,html.theme--documenter-dark .buttons.has-addons .button.is-active:hover,html.theme--documenter-dark .buttons.has-addons .button.is-selected:hover{z-index:4}html.theme--documenter-dark .buttons.has-addons .button.is-expanded{flex-grow:1;flex-shrink:1}html.theme--documenter-dark .buttons.is-centered{justify-content:center}html.theme--documenter-dark .buttons.is-centered:not(.has-addons) .button:not(.is-fullwidth){margin-left:0.25rem;margin-right:0.25rem}html.theme--documenter-dark .buttons.is-right{justify-content:flex-end}html.theme--documenter-dark .buttons.is-right:not(.has-addons) .button:not(.is-fullwidth){margin-left:0.25rem;margin-right:0.25rem}@media screen and (max-width: 768px){html.theme--documenter-dark .button.is-responsive.is-small,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-responsive{font-size:.5625rem}html.theme--documenter-dark .button.is-responsive,html.theme--documenter-dark .button.is-responsive.is-normal{font-size:.65625rem}html.theme--documenter-dark .button.is-responsive.is-medium{font-size:.75rem}html.theme--documenter-dark .button.is-responsive.is-large{font-size:1rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--documenter-dark .button.is-responsive.is-small,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-responsive{font-size:.65625rem}html.theme--documenter-dark .button.is-responsive,html.theme--documenter-dark .button.is-responsive.is-normal{font-size:.75rem}html.theme--documenter-dark .button.is-responsive.is-medium{font-size:1rem}html.theme--documenter-dark .button.is-responsive.is-large{font-size:1.25rem}}html.theme--documenter-dark .container{flex-grow:1;margin:0 auto;position:relative;width:auto}html.theme--documenter-dark .container.is-fluid{max-width:none !important;padding-left:32px;padding-right:32px;width:100%}@media screen and (min-width: 1056px){html.theme--documenter-dark .container{max-width:992px}}@media screen and (max-width: 1215px){html.theme--documenter-dark .container.is-widescreen:not(.is-max-desktop){max-width:1152px}}@media screen and (max-width: 1407px){html.theme--documenter-dark .container.is-fullhd:not(.is-max-desktop):not(.is-max-widescreen){max-width:1344px}}@media screen and (min-width: 1216px){html.theme--documenter-dark .container:not(.is-max-desktop){max-width:1152px}}@media screen and (min-width: 1408px){html.theme--documenter-dark .container:not(.is-max-desktop):not(.is-max-widescreen){max-width:1344px}}html.theme--documenter-dark .content li+li{margin-top:0.25em}html.theme--documenter-dark .content p:not(:last-child),html.theme--documenter-dark .content dl:not(:last-child),html.theme--documenter-dark .content ol:not(:last-child),html.theme--documenter-dark .content ul:not(:last-child),html.theme--documenter-dark .content blockquote:not(:last-child),html.theme--documenter-dark .content pre:not(:last-child),html.theme--documenter-dark .content table:not(:last-child){margin-bottom:1em}html.theme--documenter-dark .content h1,html.theme--documenter-dark .content h2,html.theme--documenter-dark .content h3,html.theme--documenter-dark .content h4,html.theme--documenter-dark .content h5,html.theme--documenter-dark .content h6{color:#f2f2f2;font-weight:600;line-height:1.125}html.theme--documenter-dark .content h1{font-size:2em;margin-bottom:0.5em}html.theme--documenter-dark .content h1:not(:first-child){margin-top:1em}html.theme--documenter-dark .content h2{font-size:1.75em;margin-bottom:0.5714em}html.theme--documenter-dark .content h2:not(:first-child){margin-top:1.1428em}html.theme--documenter-dark .content h3{font-size:1.5em;margin-bottom:0.6666em}html.theme--documenter-dark .content h3:not(:first-child){margin-top:1.3333em}html.theme--documenter-dark .content h4{font-size:1.25em;margin-bottom:0.8em}html.theme--documenter-dark .content h5{font-size:1.125em;margin-bottom:0.8888em}html.theme--documenter-dark .content h6{font-size:1em;margin-bottom:1em}html.theme--documenter-dark .content blockquote{background-color:#282f2f;border-left:5px solid #5e6d6f;padding:1.25em 1.5em}html.theme--documenter-dark .content ol{list-style-position:outside;margin-left:2em;margin-top:1em}html.theme--documenter-dark .content ol:not([type]){list-style-type:decimal}html.theme--documenter-dark .content ol.is-lower-alpha:not([type]){list-style-type:lower-alpha}html.theme--documenter-dark .content ol.is-lower-roman:not([type]){list-style-type:lower-roman}html.theme--documenter-dark .content ol.is-upper-alpha:not([type]){list-style-type:upper-alpha}html.theme--documenter-dark .content ol.is-upper-roman:not([type]){list-style-type:upper-roman}html.theme--documenter-dark .content ul{list-style:disc outside;margin-left:2em;margin-top:1em}html.theme--documenter-dark .content ul ul{list-style-type:circle;margin-top:0.5em}html.theme--documenter-dark .content ul ul ul{list-style-type:square}html.theme--documenter-dark .content dd{margin-left:2em}html.theme--documenter-dark .content figure{margin-left:2em;margin-right:2em;text-align:center}html.theme--documenter-dark .content figure:not(:first-child){margin-top:2em}html.theme--documenter-dark .content figure:not(:last-child){margin-bottom:2em}html.theme--documenter-dark .content figure img{display:inline-block}html.theme--documenter-dark .content figure figcaption{font-style:italic}html.theme--documenter-dark .content pre{-webkit-overflow-scrolling:touch;overflow-x:auto;padding:0;white-space:pre;word-wrap:normal}html.theme--documenter-dark .content sup,html.theme--documenter-dark .content sub{font-size:75%}html.theme--documenter-dark .content table{width:100%}html.theme--documenter-dark .content table td,html.theme--documenter-dark .content table th{border:1px solid #5e6d6f;border-width:0 0 1px;padding:0.5em 0.75em;vertical-align:top}html.theme--documenter-dark .content table th{color:#f2f2f2}html.theme--documenter-dark .content table th:not([align]){text-align:inherit}html.theme--documenter-dark .content table thead td,html.theme--documenter-dark .content table thead th{border-width:0 0 2px;color:#f2f2f2}html.theme--documenter-dark .content table tfoot td,html.theme--documenter-dark .content table tfoot th{border-width:2px 0 0;color:#f2f2f2}html.theme--documenter-dark .content table tbody tr:last-child td,html.theme--documenter-dark .content table tbody tr:last-child th{border-bottom-width:0}html.theme--documenter-dark .content .tabs li+li{margin-top:0}html.theme--documenter-dark .content.is-small,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.content{font-size:.75rem}html.theme--documenter-dark .content.is-normal{font-size:1rem}html.theme--documenter-dark .content.is-medium{font-size:1.25rem}html.theme--documenter-dark .content.is-large{font-size:1.5rem}html.theme--documenter-dark .icon{align-items:center;display:inline-flex;justify-content:center;height:1.5rem;width:1.5rem}html.theme--documenter-dark .icon.is-small,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.icon{height:1rem;width:1rem}html.theme--documenter-dark .icon.is-medium{height:2rem;width:2rem}html.theme--documenter-dark .icon.is-large{height:3rem;width:3rem}html.theme--documenter-dark .icon-text{align-items:flex-start;color:inherit;display:inline-flex;flex-wrap:wrap;line-height:1.5rem;vertical-align:top}html.theme--documenter-dark .icon-text .icon{flex-grow:0;flex-shrink:0}html.theme--documenter-dark .icon-text .icon:not(:last-child){margin-right:.25em}html.theme--documenter-dark .icon-text .icon:not(:first-child){margin-left:.25em}html.theme--documenter-dark div.icon-text{display:flex}html.theme--documenter-dark .image,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img{display:block;position:relative}html.theme--documenter-dark .image img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img img{display:block;height:auto;width:100%}html.theme--documenter-dark .image img.is-rounded,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img img.is-rounded{border-radius:9999px}html.theme--documenter-dark .image.is-fullwidth,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-fullwidth{width:100%}html.theme--documenter-dark .image.is-square img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-square img,html.theme--documenter-dark .image.is-square .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-square .has-ratio,html.theme--documenter-dark .image.is-1by1 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-1by1 img,html.theme--documenter-dark .image.is-1by1 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-1by1 .has-ratio,html.theme--documenter-dark .image.is-5by4 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-5by4 img,html.theme--documenter-dark .image.is-5by4 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-5by4 .has-ratio,html.theme--documenter-dark .image.is-4by3 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-4by3 img,html.theme--documenter-dark .image.is-4by3 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-4by3 .has-ratio,html.theme--documenter-dark .image.is-3by2 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-3by2 img,html.theme--documenter-dark .image.is-3by2 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-3by2 .has-ratio,html.theme--documenter-dark .image.is-5by3 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-5by3 img,html.theme--documenter-dark .image.is-5by3 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-5by3 .has-ratio,html.theme--documenter-dark .image.is-16by9 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-16by9 img,html.theme--documenter-dark .image.is-16by9 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-16by9 .has-ratio,html.theme--documenter-dark .image.is-2by1 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-2by1 img,html.theme--documenter-dark .image.is-2by1 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-2by1 .has-ratio,html.theme--documenter-dark .image.is-3by1 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-3by1 img,html.theme--documenter-dark .image.is-3by1 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-3by1 .has-ratio,html.theme--documenter-dark .image.is-4by5 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-4by5 img,html.theme--documenter-dark .image.is-4by5 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-4by5 .has-ratio,html.theme--documenter-dark .image.is-3by4 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-3by4 img,html.theme--documenter-dark .image.is-3by4 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-3by4 .has-ratio,html.theme--documenter-dark .image.is-2by3 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-2by3 img,html.theme--documenter-dark .image.is-2by3 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-2by3 .has-ratio,html.theme--documenter-dark .image.is-3by5 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-3by5 img,html.theme--documenter-dark .image.is-3by5 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-3by5 .has-ratio,html.theme--documenter-dark .image.is-9by16 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-9by16 img,html.theme--documenter-dark .image.is-9by16 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-9by16 .has-ratio,html.theme--documenter-dark .image.is-1by2 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-1by2 img,html.theme--documenter-dark .image.is-1by2 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-1by2 .has-ratio,html.theme--documenter-dark .image.is-1by3 img,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-1by3 img,html.theme--documenter-dark .image.is-1by3 .has-ratio,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-1by3 .has-ratio{height:100%;width:100%}html.theme--documenter-dark .image.is-square,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-square,html.theme--documenter-dark .image.is-1by1,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-1by1{padding-top:100%}html.theme--documenter-dark .image.is-5by4,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-5by4{padding-top:80%}html.theme--documenter-dark .image.is-4by3,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-4by3{padding-top:75%}html.theme--documenter-dark .image.is-3by2,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-3by2{padding-top:66.6666%}html.theme--documenter-dark .image.is-5by3,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-5by3{padding-top:60%}html.theme--documenter-dark .image.is-16by9,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-16by9{padding-top:56.25%}html.theme--documenter-dark .image.is-2by1,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-2by1{padding-top:50%}html.theme--documenter-dark .image.is-3by1,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-3by1{padding-top:33.3333%}html.theme--documenter-dark .image.is-4by5,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-4by5{padding-top:125%}html.theme--documenter-dark .image.is-3by4,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-3by4{padding-top:133.3333%}html.theme--documenter-dark .image.is-2by3,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-2by3{padding-top:150%}html.theme--documenter-dark .image.is-3by5,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-3by5{padding-top:166.6666%}html.theme--documenter-dark .image.is-9by16,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-9by16{padding-top:177.7777%}html.theme--documenter-dark .image.is-1by2,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-1by2{padding-top:200%}html.theme--documenter-dark .image.is-1by3,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-1by3{padding-top:300%}html.theme--documenter-dark .image.is-16x16,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-16x16{height:16px;width:16px}html.theme--documenter-dark .image.is-24x24,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-24x24{height:24px;width:24px}html.theme--documenter-dark .image.is-32x32,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-32x32{height:32px;width:32px}html.theme--documenter-dark .image.is-48x48,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-48x48{height:48px;width:48px}html.theme--documenter-dark .image.is-64x64,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-64x64{height:64px;width:64px}html.theme--documenter-dark .image.is-96x96,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-96x96{height:96px;width:96px}html.theme--documenter-dark .image.is-128x128,html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img.is-128x128{height:128px;width:128px}html.theme--documenter-dark .notification{background-color:#282f2f;border-radius:.4em;position:relative;padding:1.25rem 2.5rem 1.25rem 1.5rem}html.theme--documenter-dark .notification a:not(.button):not(.dropdown-item){color:currentColor;text-decoration:underline}html.theme--documenter-dark .notification strong{color:currentColor}html.theme--documenter-dark .notification code,html.theme--documenter-dark .notification pre{background:#fff}html.theme--documenter-dark .notification pre code{background:transparent}html.theme--documenter-dark .notification>.delete{right:.5rem;position:absolute;top:0.5rem}html.theme--documenter-dark .notification .title,html.theme--documenter-dark .notification .subtitle,html.theme--documenter-dark .notification .content{color:currentColor}html.theme--documenter-dark .notification.is-white{background-color:#fff;color:#0a0a0a}html.theme--documenter-dark .notification.is-black{background-color:#0a0a0a;color:#fff}html.theme--documenter-dark .notification.is-light{background-color:#ecf0f1;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .notification.is-dark,html.theme--documenter-dark .content kbd.notification{background-color:#282f2f;color:#fff}html.theme--documenter-dark .notification.is-primary,html.theme--documenter-dark .docstring>section>a.notification.docs-sourcelink{background-color:#375a7f;color:#fff}html.theme--documenter-dark .notification.is-primary.is-light,html.theme--documenter-dark .docstring>section>a.notification.is-light.docs-sourcelink{background-color:#f1f5f9;color:#4d7eb2}html.theme--documenter-dark .notification.is-link{background-color:#1abc9c;color:#fff}html.theme--documenter-dark .notification.is-link.is-light{background-color:#edfdf9;color:#15987e}html.theme--documenter-dark .notification.is-info{background-color:#024c7d;color:#fff}html.theme--documenter-dark .notification.is-info.is-light{background-color:#ebf7ff;color:#0e9dfb}html.theme--documenter-dark .notification.is-success{background-color:#008438;color:#fff}html.theme--documenter-dark .notification.is-success.is-light{background-color:#ebfff3;color:#00eb64}html.theme--documenter-dark .notification.is-warning{background-color:#ad8100;color:#fff}html.theme--documenter-dark .notification.is-warning.is-light{background-color:#fffaeb;color:#d19c00}html.theme--documenter-dark .notification.is-danger{background-color:#9e1b0d;color:#fff}html.theme--documenter-dark .notification.is-danger.is-light{background-color:#fdeeec;color:#ec311d}html.theme--documenter-dark .progress{-moz-appearance:none;-webkit-appearance:none;border:none;border-radius:9999px;display:block;height:1rem;overflow:hidden;padding:0;width:100%}html.theme--documenter-dark .progress::-webkit-progress-bar{background-color:#343c3d}html.theme--documenter-dark .progress::-webkit-progress-value{background-color:#dbdee0}html.theme--documenter-dark .progress::-moz-progress-bar{background-color:#dbdee0}html.theme--documenter-dark .progress::-ms-fill{background-color:#dbdee0;border:none}html.theme--documenter-dark .progress.is-white::-webkit-progress-value{background-color:#fff}html.theme--documenter-dark .progress.is-white::-moz-progress-bar{background-color:#fff}html.theme--documenter-dark .progress.is-white::-ms-fill{background-color:#fff}html.theme--documenter-dark .progress.is-white:indeterminate{background-image:linear-gradient(to right, #fff 30%, #343c3d 30%)}html.theme--documenter-dark .progress.is-black::-webkit-progress-value{background-color:#0a0a0a}html.theme--documenter-dark .progress.is-black::-moz-progress-bar{background-color:#0a0a0a}html.theme--documenter-dark .progress.is-black::-ms-fill{background-color:#0a0a0a}html.theme--documenter-dark .progress.is-black:indeterminate{background-image:linear-gradient(to right, #0a0a0a 30%, #343c3d 30%)}html.theme--documenter-dark .progress.is-light::-webkit-progress-value{background-color:#ecf0f1}html.theme--documenter-dark .progress.is-light::-moz-progress-bar{background-color:#ecf0f1}html.theme--documenter-dark .progress.is-light::-ms-fill{background-color:#ecf0f1}html.theme--documenter-dark .progress.is-light:indeterminate{background-image:linear-gradient(to right, #ecf0f1 30%, #343c3d 30%)}html.theme--documenter-dark .progress.is-dark::-webkit-progress-value,html.theme--documenter-dark .content kbd.progress::-webkit-progress-value{background-color:#282f2f}html.theme--documenter-dark .progress.is-dark::-moz-progress-bar,html.theme--documenter-dark .content kbd.progress::-moz-progress-bar{background-color:#282f2f}html.theme--documenter-dark .progress.is-dark::-ms-fill,html.theme--documenter-dark .content kbd.progress::-ms-fill{background-color:#282f2f}html.theme--documenter-dark .progress.is-dark:indeterminate,html.theme--documenter-dark .content kbd.progress:indeterminate{background-image:linear-gradient(to right, #282f2f 30%, #343c3d 30%)}html.theme--documenter-dark .progress.is-primary::-webkit-progress-value,html.theme--documenter-dark .docstring>section>a.progress.docs-sourcelink::-webkit-progress-value{background-color:#375a7f}html.theme--documenter-dark .progress.is-primary::-moz-progress-bar,html.theme--documenter-dark .docstring>section>a.progress.docs-sourcelink::-moz-progress-bar{background-color:#375a7f}html.theme--documenter-dark .progress.is-primary::-ms-fill,html.theme--documenter-dark .docstring>section>a.progress.docs-sourcelink::-ms-fill{background-color:#375a7f}html.theme--documenter-dark .progress.is-primary:indeterminate,html.theme--documenter-dark .docstring>section>a.progress.docs-sourcelink:indeterminate{background-image:linear-gradient(to right, #375a7f 30%, #343c3d 30%)}html.theme--documenter-dark .progress.is-link::-webkit-progress-value{background-color:#1abc9c}html.theme--documenter-dark .progress.is-link::-moz-progress-bar{background-color:#1abc9c}html.theme--documenter-dark .progress.is-link::-ms-fill{background-color:#1abc9c}html.theme--documenter-dark .progress.is-link:indeterminate{background-image:linear-gradient(to right, #1abc9c 30%, #343c3d 30%)}html.theme--documenter-dark .progress.is-info::-webkit-progress-value{background-color:#024c7d}html.theme--documenter-dark .progress.is-info::-moz-progress-bar{background-color:#024c7d}html.theme--documenter-dark .progress.is-info::-ms-fill{background-color:#024c7d}html.theme--documenter-dark .progress.is-info:indeterminate{background-image:linear-gradient(to right, #024c7d 30%, #343c3d 30%)}html.theme--documenter-dark .progress.is-success::-webkit-progress-value{background-color:#008438}html.theme--documenter-dark .progress.is-success::-moz-progress-bar{background-color:#008438}html.theme--documenter-dark .progress.is-success::-ms-fill{background-color:#008438}html.theme--documenter-dark .progress.is-success:indeterminate{background-image:linear-gradient(to right, #008438 30%, #343c3d 30%)}html.theme--documenter-dark .progress.is-warning::-webkit-progress-value{background-color:#ad8100}html.theme--documenter-dark .progress.is-warning::-moz-progress-bar{background-color:#ad8100}html.theme--documenter-dark .progress.is-warning::-ms-fill{background-color:#ad8100}html.theme--documenter-dark .progress.is-warning:indeterminate{background-image:linear-gradient(to right, #ad8100 30%, #343c3d 30%)}html.theme--documenter-dark .progress.is-danger::-webkit-progress-value{background-color:#9e1b0d}html.theme--documenter-dark .progress.is-danger::-moz-progress-bar{background-color:#9e1b0d}html.theme--documenter-dark .progress.is-danger::-ms-fill{background-color:#9e1b0d}html.theme--documenter-dark .progress.is-danger:indeterminate{background-image:linear-gradient(to right, #9e1b0d 30%, #343c3d 30%)}html.theme--documenter-dark .progress:indeterminate{animation-duration:1.5s;animation-iteration-count:infinite;animation-name:moveIndeterminate;animation-timing-function:linear;background-color:#343c3d;background-image:linear-gradient(to right, #fff 30%, #343c3d 30%);background-position:top left;background-repeat:no-repeat;background-size:150% 150%}html.theme--documenter-dark .progress:indeterminate::-webkit-progress-bar{background-color:transparent}html.theme--documenter-dark .progress:indeterminate::-moz-progress-bar{background-color:transparent}html.theme--documenter-dark .progress:indeterminate::-ms-fill{animation-name:none}html.theme--documenter-dark .progress.is-small,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.progress{height:.75rem}html.theme--documenter-dark .progress.is-medium{height:1.25rem}html.theme--documenter-dark .progress.is-large{height:1.5rem}@keyframes moveIndeterminate{from{background-position:200% 0}to{background-position:-200% 0}}html.theme--documenter-dark .table{background-color:#343c3d;color:#fff}html.theme--documenter-dark .table td,html.theme--documenter-dark .table th{border:1px solid #5e6d6f;border-width:0 0 1px;padding:0.5em 0.75em;vertical-align:top}html.theme--documenter-dark .table td.is-white,html.theme--documenter-dark .table th.is-white{background-color:#fff;border-color:#fff;color:#0a0a0a}html.theme--documenter-dark .table td.is-black,html.theme--documenter-dark .table th.is-black{background-color:#0a0a0a;border-color:#0a0a0a;color:#fff}html.theme--documenter-dark .table td.is-light,html.theme--documenter-dark .table th.is-light{background-color:#ecf0f1;border-color:#ecf0f1;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .table td.is-dark,html.theme--documenter-dark .table th.is-dark{background-color:#282f2f;border-color:#282f2f;color:#fff}html.theme--documenter-dark .table td.is-primary,html.theme--documenter-dark .table th.is-primary{background-color:#375a7f;border-color:#375a7f;color:#fff}html.theme--documenter-dark .table td.is-link,html.theme--documenter-dark .table th.is-link{background-color:#1abc9c;border-color:#1abc9c;color:#fff}html.theme--documenter-dark .table td.is-info,html.theme--documenter-dark .table th.is-info{background-color:#024c7d;border-color:#024c7d;color:#fff}html.theme--documenter-dark .table td.is-success,html.theme--documenter-dark .table th.is-success{background-color:#008438;border-color:#008438;color:#fff}html.theme--documenter-dark .table td.is-warning,html.theme--documenter-dark .table th.is-warning{background-color:#ad8100;border-color:#ad8100;color:#fff}html.theme--documenter-dark .table td.is-danger,html.theme--documenter-dark .table th.is-danger{background-color:#9e1b0d;border-color:#9e1b0d;color:#fff}html.theme--documenter-dark .table td.is-narrow,html.theme--documenter-dark .table th.is-narrow{white-space:nowrap;width:1%}html.theme--documenter-dark .table td.is-selected,html.theme--documenter-dark .table th.is-selected{background-color:#375a7f;color:#fff}html.theme--documenter-dark .table td.is-selected a,html.theme--documenter-dark .table td.is-selected strong,html.theme--documenter-dark .table th.is-selected a,html.theme--documenter-dark .table th.is-selected strong{color:currentColor}html.theme--documenter-dark .table td.is-vcentered,html.theme--documenter-dark .table th.is-vcentered{vertical-align:middle}html.theme--documenter-dark .table th{color:#f2f2f2}html.theme--documenter-dark .table th:not([align]){text-align:left}html.theme--documenter-dark .table tr.is-selected{background-color:#375a7f;color:#fff}html.theme--documenter-dark .table tr.is-selected a,html.theme--documenter-dark .table tr.is-selected strong{color:currentColor}html.theme--documenter-dark .table tr.is-selected td,html.theme--documenter-dark .table tr.is-selected th{border-color:#fff;color:currentColor}html.theme--documenter-dark .table thead{background-color:rgba(0,0,0,0)}html.theme--documenter-dark .table thead td,html.theme--documenter-dark .table thead th{border-width:0 0 2px;color:#f2f2f2}html.theme--documenter-dark .table tfoot{background-color:rgba(0,0,0,0)}html.theme--documenter-dark .table tfoot td,html.theme--documenter-dark .table tfoot th{border-width:2px 0 0;color:#f2f2f2}html.theme--documenter-dark .table tbody{background-color:rgba(0,0,0,0)}html.theme--documenter-dark .table tbody tr:last-child td,html.theme--documenter-dark .table tbody tr:last-child th{border-bottom-width:0}html.theme--documenter-dark .table.is-bordered td,html.theme--documenter-dark .table.is-bordered th{border-width:1px}html.theme--documenter-dark .table.is-bordered tr:last-child td,html.theme--documenter-dark .table.is-bordered tr:last-child th{border-bottom-width:1px}html.theme--documenter-dark .table.is-fullwidth{width:100%}html.theme--documenter-dark .table.is-hoverable tbody tr:not(.is-selected):hover{background-color:#282f2f}html.theme--documenter-dark .table.is-hoverable.is-striped tbody tr:not(.is-selected):hover{background-color:#282f2f}html.theme--documenter-dark .table.is-hoverable.is-striped tbody tr:not(.is-selected):hover:nth-child(even){background-color:#2d3435}html.theme--documenter-dark .table.is-narrow td,html.theme--documenter-dark .table.is-narrow th{padding:0.25em 0.5em}html.theme--documenter-dark .table.is-striped tbody tr:not(.is-selected):nth-child(even){background-color:#282f2f}html.theme--documenter-dark .table-container{-webkit-overflow-scrolling:touch;overflow:auto;overflow-y:hidden;max-width:100%}html.theme--documenter-dark .tags{align-items:center;display:flex;flex-wrap:wrap;justify-content:flex-start}html.theme--documenter-dark .tags .tag,html.theme--documenter-dark .tags .content kbd,html.theme--documenter-dark .content .tags kbd,html.theme--documenter-dark .tags .docstring>section>a.docs-sourcelink{margin-bottom:0.5rem}html.theme--documenter-dark .tags .tag:not(:last-child),html.theme--documenter-dark .tags .content kbd:not(:last-child),html.theme--documenter-dark .content .tags kbd:not(:last-child),html.theme--documenter-dark .tags .docstring>section>a.docs-sourcelink:not(:last-child){margin-right:.5rem}html.theme--documenter-dark .tags:last-child{margin-bottom:-0.5rem}html.theme--documenter-dark .tags:not(:last-child){margin-bottom:1rem}html.theme--documenter-dark .tags.are-medium .tag:not(.is-normal):not(.is-large),html.theme--documenter-dark .tags.are-medium .content kbd:not(.is-normal):not(.is-large),html.theme--documenter-dark .content .tags.are-medium kbd:not(.is-normal):not(.is-large),html.theme--documenter-dark .tags.are-medium .docstring>section>a.docs-sourcelink:not(.is-normal):not(.is-large){font-size:1rem}html.theme--documenter-dark .tags.are-large .tag:not(.is-normal):not(.is-medium),html.theme--documenter-dark .tags.are-large .content kbd:not(.is-normal):not(.is-medium),html.theme--documenter-dark .content .tags.are-large kbd:not(.is-normal):not(.is-medium),html.theme--documenter-dark .tags.are-large .docstring>section>a.docs-sourcelink:not(.is-normal):not(.is-medium){font-size:1.25rem}html.theme--documenter-dark .tags.is-centered{justify-content:center}html.theme--documenter-dark .tags.is-centered .tag,html.theme--documenter-dark .tags.is-centered .content kbd,html.theme--documenter-dark .content .tags.is-centered kbd,html.theme--documenter-dark .tags.is-centered .docstring>section>a.docs-sourcelink{margin-right:0.25rem;margin-left:0.25rem}html.theme--documenter-dark .tags.is-right{justify-content:flex-end}html.theme--documenter-dark .tags.is-right .tag:not(:first-child),html.theme--documenter-dark .tags.is-right .content kbd:not(:first-child),html.theme--documenter-dark .content .tags.is-right kbd:not(:first-child),html.theme--documenter-dark .tags.is-right .docstring>section>a.docs-sourcelink:not(:first-child){margin-left:0.5rem}html.theme--documenter-dark .tags.is-right .tag:not(:last-child),html.theme--documenter-dark .tags.is-right .content kbd:not(:last-child),html.theme--documenter-dark .content .tags.is-right kbd:not(:last-child),html.theme--documenter-dark .tags.is-right .docstring>section>a.docs-sourcelink:not(:last-child){margin-right:0}html.theme--documenter-dark .tags.has-addons .tag,html.theme--documenter-dark .tags.has-addons .content kbd,html.theme--documenter-dark .content .tags.has-addons kbd,html.theme--documenter-dark .tags.has-addons .docstring>section>a.docs-sourcelink{margin-right:0}html.theme--documenter-dark .tags.has-addons .tag:not(:first-child),html.theme--documenter-dark .tags.has-addons .content kbd:not(:first-child),html.theme--documenter-dark .content .tags.has-addons kbd:not(:first-child),html.theme--documenter-dark .tags.has-addons .docstring>section>a.docs-sourcelink:not(:first-child){margin-left:0;border-top-left-radius:0;border-bottom-left-radius:0}html.theme--documenter-dark .tags.has-addons .tag:not(:last-child),html.theme--documenter-dark .tags.has-addons .content kbd:not(:last-child),html.theme--documenter-dark .content .tags.has-addons kbd:not(:last-child),html.theme--documenter-dark .tags.has-addons .docstring>section>a.docs-sourcelink:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}html.theme--documenter-dark .tag:not(body),html.theme--documenter-dark .content kbd:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink:not(body){align-items:center;background-color:#282f2f;border-radius:.4em;color:#fff;display:inline-flex;font-size:.75rem;height:2em;justify-content:center;line-height:1.5;padding-left:0.75em;padding-right:0.75em;white-space:nowrap}html.theme--documenter-dark .tag:not(body) .delete,html.theme--documenter-dark .content kbd:not(body) .delete,html.theme--documenter-dark .docstring>section>a.docs-sourcelink:not(body) .delete{margin-left:.25rem;margin-right:-.375rem}html.theme--documenter-dark .tag.is-white:not(body),html.theme--documenter-dark .content kbd.is-white:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-white:not(body){background-color:#fff;color:#0a0a0a}html.theme--documenter-dark .tag.is-black:not(body),html.theme--documenter-dark .content kbd.is-black:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-black:not(body){background-color:#0a0a0a;color:#fff}html.theme--documenter-dark .tag.is-light:not(body),html.theme--documenter-dark .content kbd.is-light:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-light:not(body){background-color:#ecf0f1;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .tag.is-dark:not(body),html.theme--documenter-dark .content kbd:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-dark:not(body),html.theme--documenter-dark .content .docstring>section>kbd:not(body){background-color:#282f2f;color:#fff}html.theme--documenter-dark .tag.is-primary:not(body),html.theme--documenter-dark .content kbd.is-primary:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink:not(body){background-color:#375a7f;color:#fff}html.theme--documenter-dark .tag.is-primary.is-light:not(body),html.theme--documenter-dark .content kbd.is-primary.is-light:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-light:not(body){background-color:#f1f5f9;color:#4d7eb2}html.theme--documenter-dark .tag.is-link:not(body),html.theme--documenter-dark .content kbd.is-link:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-link:not(body){background-color:#1abc9c;color:#fff}html.theme--documenter-dark .tag.is-link.is-light:not(body),html.theme--documenter-dark .content kbd.is-link.is-light:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-link.is-light:not(body){background-color:#edfdf9;color:#15987e}html.theme--documenter-dark .tag.is-info:not(body),html.theme--documenter-dark .content kbd.is-info:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-info:not(body){background-color:#024c7d;color:#fff}html.theme--documenter-dark .tag.is-info.is-light:not(body),html.theme--documenter-dark .content kbd.is-info.is-light:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-info.is-light:not(body){background-color:#ebf7ff;color:#0e9dfb}html.theme--documenter-dark .tag.is-success:not(body),html.theme--documenter-dark .content kbd.is-success:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-success:not(body){background-color:#008438;color:#fff}html.theme--documenter-dark .tag.is-success.is-light:not(body),html.theme--documenter-dark .content kbd.is-success.is-light:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-success.is-light:not(body){background-color:#ebfff3;color:#00eb64}html.theme--documenter-dark .tag.is-warning:not(body),html.theme--documenter-dark .content kbd.is-warning:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-warning:not(body){background-color:#ad8100;color:#fff}html.theme--documenter-dark .tag.is-warning.is-light:not(body),html.theme--documenter-dark .content kbd.is-warning.is-light:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-warning.is-light:not(body){background-color:#fffaeb;color:#d19c00}html.theme--documenter-dark .tag.is-danger:not(body),html.theme--documenter-dark .content kbd.is-danger:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-danger:not(body){background-color:#9e1b0d;color:#fff}html.theme--documenter-dark .tag.is-danger.is-light:not(body),html.theme--documenter-dark .content kbd.is-danger.is-light:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-danger.is-light:not(body){background-color:#fdeeec;color:#ec311d}html.theme--documenter-dark .tag.is-normal:not(body),html.theme--documenter-dark .content kbd.is-normal:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-normal:not(body){font-size:.75rem}html.theme--documenter-dark .tag.is-medium:not(body),html.theme--documenter-dark .content kbd.is-medium:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-medium:not(body){font-size:1rem}html.theme--documenter-dark .tag.is-large:not(body),html.theme--documenter-dark .content kbd.is-large:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-large:not(body){font-size:1.25rem}html.theme--documenter-dark .tag:not(body) .icon:first-child:not(:last-child),html.theme--documenter-dark .content kbd:not(body) .icon:first-child:not(:last-child),html.theme--documenter-dark .docstring>section>a.docs-sourcelink:not(body) .icon:first-child:not(:last-child){margin-left:-.375em;margin-right:.1875em}html.theme--documenter-dark .tag:not(body) .icon:last-child:not(:first-child),html.theme--documenter-dark .content kbd:not(body) .icon:last-child:not(:first-child),html.theme--documenter-dark .docstring>section>a.docs-sourcelink:not(body) .icon:last-child:not(:first-child){margin-left:.1875em;margin-right:-.375em}html.theme--documenter-dark .tag:not(body) .icon:first-child:last-child,html.theme--documenter-dark .content kbd:not(body) .icon:first-child:last-child,html.theme--documenter-dark .docstring>section>a.docs-sourcelink:not(body) .icon:first-child:last-child{margin-left:-.375em;margin-right:-.375em}html.theme--documenter-dark .tag.is-delete:not(body),html.theme--documenter-dark .content kbd.is-delete:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-delete:not(body){margin-left:1px;padding:0;position:relative;width:2em}html.theme--documenter-dark .tag.is-delete:not(body)::before,html.theme--documenter-dark .content kbd.is-delete:not(body)::before,html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-delete:not(body)::before,html.theme--documenter-dark .tag.is-delete:not(body)::after,html.theme--documenter-dark .content kbd.is-delete:not(body)::after,html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-delete:not(body)::after{background-color:currentColor;content:"";display:block;left:50%;position:absolute;top:50%;transform:translateX(-50%) translateY(-50%) rotate(45deg);transform-origin:center center}html.theme--documenter-dark .tag.is-delete:not(body)::before,html.theme--documenter-dark .content kbd.is-delete:not(body)::before,html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-delete:not(body)::before{height:1px;width:50%}html.theme--documenter-dark .tag.is-delete:not(body)::after,html.theme--documenter-dark .content kbd.is-delete:not(body)::after,html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-delete:not(body)::after{height:50%;width:1px}html.theme--documenter-dark .tag.is-delete:not(body):hover,html.theme--documenter-dark .content kbd.is-delete:not(body):hover,html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-delete:not(body):hover,html.theme--documenter-dark .tag.is-delete:not(body):focus,html.theme--documenter-dark .content kbd.is-delete:not(body):focus,html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-delete:not(body):focus{background-color:#1d2122}html.theme--documenter-dark .tag.is-delete:not(body):active,html.theme--documenter-dark .content kbd.is-delete:not(body):active,html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-delete:not(body):active{background-color:#111414}html.theme--documenter-dark .tag.is-rounded:not(body),html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input:not(body),html.theme--documenter-dark .content kbd.is-rounded:not(body),html.theme--documenter-dark #documenter .docs-sidebar .content form.docs-search>input:not(body),html.theme--documenter-dark .docstring>section>a.docs-sourcelink.is-rounded:not(body){border-radius:9999px}html.theme--documenter-dark a.tag:hover,html.theme--documenter-dark .docstring>section>a.docs-sourcelink:hover{text-decoration:underline}html.theme--documenter-dark .title,html.theme--documenter-dark .subtitle{word-break:break-word}html.theme--documenter-dark .title em,html.theme--documenter-dark .title span,html.theme--documenter-dark .subtitle em,html.theme--documenter-dark .subtitle span{font-weight:inherit}html.theme--documenter-dark .title sub,html.theme--documenter-dark .subtitle sub{font-size:.75em}html.theme--documenter-dark .title sup,html.theme--documenter-dark .subtitle sup{font-size:.75em}html.theme--documenter-dark .title .tag,html.theme--documenter-dark .title .content kbd,html.theme--documenter-dark .content .title kbd,html.theme--documenter-dark .title .docstring>section>a.docs-sourcelink,html.theme--documenter-dark .subtitle .tag,html.theme--documenter-dark .subtitle .content kbd,html.theme--documenter-dark .content .subtitle kbd,html.theme--documenter-dark .subtitle .docstring>section>a.docs-sourcelink{vertical-align:middle}html.theme--documenter-dark .title{color:#fff;font-size:2rem;font-weight:500;line-height:1.125}html.theme--documenter-dark .title strong{color:inherit;font-weight:inherit}html.theme--documenter-dark .title:not(.is-spaced)+.subtitle{margin-top:-1.25rem}html.theme--documenter-dark .title.is-1{font-size:3rem}html.theme--documenter-dark .title.is-2{font-size:2.5rem}html.theme--documenter-dark .title.is-3{font-size:2rem}html.theme--documenter-dark .title.is-4{font-size:1.5rem}html.theme--documenter-dark .title.is-5{font-size:1.25rem}html.theme--documenter-dark .title.is-6{font-size:1rem}html.theme--documenter-dark .title.is-7{font-size:.75rem}html.theme--documenter-dark .subtitle{color:#8c9b9d;font-size:1.25rem;font-weight:400;line-height:1.25}html.theme--documenter-dark .subtitle strong{color:#8c9b9d;font-weight:600}html.theme--documenter-dark .subtitle:not(.is-spaced)+.title{margin-top:-1.25rem}html.theme--documenter-dark .subtitle.is-1{font-size:3rem}html.theme--documenter-dark .subtitle.is-2{font-size:2.5rem}html.theme--documenter-dark .subtitle.is-3{font-size:2rem}html.theme--documenter-dark .subtitle.is-4{font-size:1.5rem}html.theme--documenter-dark .subtitle.is-5{font-size:1.25rem}html.theme--documenter-dark .subtitle.is-6{font-size:1rem}html.theme--documenter-dark .subtitle.is-7{font-size:.75rem}html.theme--documenter-dark .heading{display:block;font-size:11px;letter-spacing:1px;margin-bottom:5px;text-transform:uppercase}html.theme--documenter-dark .number{align-items:center;background-color:#282f2f;border-radius:9999px;display:inline-flex;font-size:1.25rem;height:2em;justify-content:center;margin-right:1.5rem;min-width:2.5em;padding:0.25rem 0.5rem;text-align:center;vertical-align:top}html.theme--documenter-dark .select select,html.theme--documenter-dark .textarea,html.theme--documenter-dark .input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input{background-color:#1f2424;border-color:#5e6d6f;border-radius:.4em;color:#dbdee0}html.theme--documenter-dark .select select::-moz-placeholder,html.theme--documenter-dark .textarea::-moz-placeholder,html.theme--documenter-dark .input::-moz-placeholder,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input::-moz-placeholder{color:#868c98}html.theme--documenter-dark .select select::-webkit-input-placeholder,html.theme--documenter-dark .textarea::-webkit-input-placeholder,html.theme--documenter-dark .input::-webkit-input-placeholder,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input::-webkit-input-placeholder{color:#868c98}html.theme--documenter-dark .select select:-moz-placeholder,html.theme--documenter-dark .textarea:-moz-placeholder,html.theme--documenter-dark .input:-moz-placeholder,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input:-moz-placeholder{color:#868c98}html.theme--documenter-dark .select select:-ms-input-placeholder,html.theme--documenter-dark .textarea:-ms-input-placeholder,html.theme--documenter-dark .input:-ms-input-placeholder,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input:-ms-input-placeholder{color:#868c98}html.theme--documenter-dark .select select:hover,html.theme--documenter-dark .textarea:hover,html.theme--documenter-dark .input:hover,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input:hover,html.theme--documenter-dark .select select.is-hovered,html.theme--documenter-dark .is-hovered.textarea,html.theme--documenter-dark .is-hovered.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-hovered{border-color:#8c9b9d}html.theme--documenter-dark .select select:focus,html.theme--documenter-dark .textarea:focus,html.theme--documenter-dark .input:focus,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input:focus,html.theme--documenter-dark .select select.is-focused,html.theme--documenter-dark .is-focused.textarea,html.theme--documenter-dark .is-focused.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--documenter-dark .select select:active,html.theme--documenter-dark .textarea:active,html.theme--documenter-dark .input:active,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input:active,html.theme--documenter-dark .select select.is-active,html.theme--documenter-dark .is-active.textarea,html.theme--documenter-dark .is-active.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-active{border-color:#1abc9c;box-shadow:0 0 0 0.125em rgba(26,188,156,0.25)}html.theme--documenter-dark .select select[disabled],html.theme--documenter-dark .textarea[disabled],html.theme--documenter-dark .input[disabled],html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input[disabled],fieldset[disabled] html.theme--documenter-dark .select select,fieldset[disabled] html.theme--documenter-dark .textarea,fieldset[disabled] html.theme--documenter-dark .input,fieldset[disabled] html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input{background-color:#8c9b9d;border-color:#282f2f;box-shadow:none;color:#fff}html.theme--documenter-dark .select select[disabled]::-moz-placeholder,html.theme--documenter-dark .textarea[disabled]::-moz-placeholder,html.theme--documenter-dark .input[disabled]::-moz-placeholder,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input[disabled]::-moz-placeholder,fieldset[disabled] html.theme--documenter-dark .select select::-moz-placeholder,fieldset[disabled] html.theme--documenter-dark .textarea::-moz-placeholder,fieldset[disabled] html.theme--documenter-dark .input::-moz-placeholder,fieldset[disabled] html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input::-moz-placeholder{color:rgba(255,255,255,0.3)}html.theme--documenter-dark .select select[disabled]::-webkit-input-placeholder,html.theme--documenter-dark .textarea[disabled]::-webkit-input-placeholder,html.theme--documenter-dark .input[disabled]::-webkit-input-placeholder,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input[disabled]::-webkit-input-placeholder,fieldset[disabled] html.theme--documenter-dark .select select::-webkit-input-placeholder,fieldset[disabled] html.theme--documenter-dark .textarea::-webkit-input-placeholder,fieldset[disabled] html.theme--documenter-dark .input::-webkit-input-placeholder,fieldset[disabled] html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input::-webkit-input-placeholder{color:rgba(255,255,255,0.3)}html.theme--documenter-dark .select select[disabled]:-moz-placeholder,html.theme--documenter-dark .textarea[disabled]:-moz-placeholder,html.theme--documenter-dark .input[disabled]:-moz-placeholder,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input[disabled]:-moz-placeholder,fieldset[disabled] html.theme--documenter-dark .select select:-moz-placeholder,fieldset[disabled] html.theme--documenter-dark .textarea:-moz-placeholder,fieldset[disabled] html.theme--documenter-dark .input:-moz-placeholder,fieldset[disabled] html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input:-moz-placeholder{color:rgba(255,255,255,0.3)}html.theme--documenter-dark .select select[disabled]:-ms-input-placeholder,html.theme--documenter-dark .textarea[disabled]:-ms-input-placeholder,html.theme--documenter-dark .input[disabled]:-ms-input-placeholder,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input[disabled]:-ms-input-placeholder,fieldset[disabled] html.theme--documenter-dark .select select:-ms-input-placeholder,fieldset[disabled] html.theme--documenter-dark .textarea:-ms-input-placeholder,fieldset[disabled] html.theme--documenter-dark .input:-ms-input-placeholder,fieldset[disabled] html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input:-ms-input-placeholder{color:rgba(255,255,255,0.3)}html.theme--documenter-dark .textarea,html.theme--documenter-dark .input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input{box-shadow:inset 0 0.0625em 0.125em rgba(10,10,10,0.05);max-width:100%;width:100%}html.theme--documenter-dark .textarea[readonly],html.theme--documenter-dark .input[readonly],html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input[readonly]{box-shadow:none}html.theme--documenter-dark .is-white.textarea,html.theme--documenter-dark .is-white.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-white{border-color:#fff}html.theme--documenter-dark .is-white.textarea:focus,html.theme--documenter-dark .is-white.input:focus,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-white:focus,html.theme--documenter-dark .is-white.is-focused.textarea,html.theme--documenter-dark .is-white.is-focused.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--documenter-dark .is-white.textarea:active,html.theme--documenter-dark .is-white.input:active,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-white:active,html.theme--documenter-dark .is-white.is-active.textarea,html.theme--documenter-dark .is-white.is-active.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(255,255,255,0.25)}html.theme--documenter-dark .is-black.textarea,html.theme--documenter-dark .is-black.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-black{border-color:#0a0a0a}html.theme--documenter-dark .is-black.textarea:focus,html.theme--documenter-dark .is-black.input:focus,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-black:focus,html.theme--documenter-dark .is-black.is-focused.textarea,html.theme--documenter-dark .is-black.is-focused.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--documenter-dark .is-black.textarea:active,html.theme--documenter-dark .is-black.input:active,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-black:active,html.theme--documenter-dark .is-black.is-active.textarea,html.theme--documenter-dark .is-black.is-active.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(10,10,10,0.25)}html.theme--documenter-dark .is-light.textarea,html.theme--documenter-dark .is-light.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-light{border-color:#ecf0f1}html.theme--documenter-dark .is-light.textarea:focus,html.theme--documenter-dark .is-light.input:focus,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-light:focus,html.theme--documenter-dark .is-light.is-focused.textarea,html.theme--documenter-dark .is-light.is-focused.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--documenter-dark .is-light.textarea:active,html.theme--documenter-dark .is-light.input:active,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-light:active,html.theme--documenter-dark .is-light.is-active.textarea,html.theme--documenter-dark .is-light.is-active.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(236,240,241,0.25)}html.theme--documenter-dark .is-dark.textarea,html.theme--documenter-dark .content kbd.textarea,html.theme--documenter-dark .is-dark.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-dark,html.theme--documenter-dark .content kbd.input{border-color:#282f2f}html.theme--documenter-dark .is-dark.textarea:focus,html.theme--documenter-dark .content kbd.textarea:focus,html.theme--documenter-dark .is-dark.input:focus,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-dark:focus,html.theme--documenter-dark .content kbd.input:focus,html.theme--documenter-dark .is-dark.is-focused.textarea,html.theme--documenter-dark .content kbd.is-focused.textarea,html.theme--documenter-dark .is-dark.is-focused.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--documenter-dark .content kbd.is-focused.input,html.theme--documenter-dark #documenter .docs-sidebar .content form.docs-search>input.is-focused,html.theme--documenter-dark .is-dark.textarea:active,html.theme--documenter-dark .content kbd.textarea:active,html.theme--documenter-dark .is-dark.input:active,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-dark:active,html.theme--documenter-dark .content kbd.input:active,html.theme--documenter-dark .is-dark.is-active.textarea,html.theme--documenter-dark .content kbd.is-active.textarea,html.theme--documenter-dark .is-dark.is-active.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-active,html.theme--documenter-dark .content kbd.is-active.input,html.theme--documenter-dark #documenter .docs-sidebar .content form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(40,47,47,0.25)}html.theme--documenter-dark .is-primary.textarea,html.theme--documenter-dark .docstring>section>a.textarea.docs-sourcelink,html.theme--documenter-dark .is-primary.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-primary,html.theme--documenter-dark .docstring>section>a.input.docs-sourcelink{border-color:#375a7f}html.theme--documenter-dark .is-primary.textarea:focus,html.theme--documenter-dark .docstring>section>a.textarea.docs-sourcelink:focus,html.theme--documenter-dark .is-primary.input:focus,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-primary:focus,html.theme--documenter-dark .docstring>section>a.input.docs-sourcelink:focus,html.theme--documenter-dark .is-primary.is-focused.textarea,html.theme--documenter-dark .docstring>section>a.is-focused.textarea.docs-sourcelink,html.theme--documenter-dark .is-primary.is-focused.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--documenter-dark .docstring>section>a.is-focused.input.docs-sourcelink,html.theme--documenter-dark .is-primary.textarea:active,html.theme--documenter-dark .docstring>section>a.textarea.docs-sourcelink:active,html.theme--documenter-dark .is-primary.input:active,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-primary:active,html.theme--documenter-dark .docstring>section>a.input.docs-sourcelink:active,html.theme--documenter-dark .is-primary.is-active.textarea,html.theme--documenter-dark .docstring>section>a.is-active.textarea.docs-sourcelink,html.theme--documenter-dark .is-primary.is-active.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-active,html.theme--documenter-dark .docstring>section>a.is-active.input.docs-sourcelink{box-shadow:0 0 0 0.125em rgba(55,90,127,0.25)}html.theme--documenter-dark .is-link.textarea,html.theme--documenter-dark .is-link.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-link{border-color:#1abc9c}html.theme--documenter-dark .is-link.textarea:focus,html.theme--documenter-dark .is-link.input:focus,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-link:focus,html.theme--documenter-dark .is-link.is-focused.textarea,html.theme--documenter-dark .is-link.is-focused.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--documenter-dark .is-link.textarea:active,html.theme--documenter-dark .is-link.input:active,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-link:active,html.theme--documenter-dark .is-link.is-active.textarea,html.theme--documenter-dark .is-link.is-active.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(26,188,156,0.25)}html.theme--documenter-dark .is-info.textarea,html.theme--documenter-dark .is-info.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-info{border-color:#024c7d}html.theme--documenter-dark .is-info.textarea:focus,html.theme--documenter-dark .is-info.input:focus,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-info:focus,html.theme--documenter-dark .is-info.is-focused.textarea,html.theme--documenter-dark .is-info.is-focused.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--documenter-dark .is-info.textarea:active,html.theme--documenter-dark .is-info.input:active,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-info:active,html.theme--documenter-dark .is-info.is-active.textarea,html.theme--documenter-dark .is-info.is-active.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(2,76,125,0.25)}html.theme--documenter-dark .is-success.textarea,html.theme--documenter-dark .is-success.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-success{border-color:#008438}html.theme--documenter-dark .is-success.textarea:focus,html.theme--documenter-dark .is-success.input:focus,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-success:focus,html.theme--documenter-dark .is-success.is-focused.textarea,html.theme--documenter-dark .is-success.is-focused.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--documenter-dark .is-success.textarea:active,html.theme--documenter-dark .is-success.input:active,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-success:active,html.theme--documenter-dark .is-success.is-active.textarea,html.theme--documenter-dark .is-success.is-active.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(0,132,56,0.25)}html.theme--documenter-dark .is-warning.textarea,html.theme--documenter-dark .is-warning.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-warning{border-color:#ad8100}html.theme--documenter-dark .is-warning.textarea:focus,html.theme--documenter-dark .is-warning.input:focus,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-warning:focus,html.theme--documenter-dark .is-warning.is-focused.textarea,html.theme--documenter-dark .is-warning.is-focused.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--documenter-dark .is-warning.textarea:active,html.theme--documenter-dark .is-warning.input:active,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-warning:active,html.theme--documenter-dark .is-warning.is-active.textarea,html.theme--documenter-dark .is-warning.is-active.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(173,129,0,0.25)}html.theme--documenter-dark .is-danger.textarea,html.theme--documenter-dark .is-danger.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-danger{border-color:#9e1b0d}html.theme--documenter-dark .is-danger.textarea:focus,html.theme--documenter-dark .is-danger.input:focus,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-danger:focus,html.theme--documenter-dark .is-danger.is-focused.textarea,html.theme--documenter-dark .is-danger.is-focused.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-focused,html.theme--documenter-dark .is-danger.textarea:active,html.theme--documenter-dark .is-danger.input:active,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-danger:active,html.theme--documenter-dark .is-danger.is-active.textarea,html.theme--documenter-dark .is-danger.is-active.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(158,27,13,0.25)}html.theme--documenter-dark .is-small.textarea,html.theme--documenter-dark .is-small.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input{border-radius:3px;font-size:.75rem}html.theme--documenter-dark .is-medium.textarea,html.theme--documenter-dark .is-medium.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-medium{font-size:1.25rem}html.theme--documenter-dark .is-large.textarea,html.theme--documenter-dark .is-large.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-large{font-size:1.5rem}html.theme--documenter-dark .is-fullwidth.textarea,html.theme--documenter-dark .is-fullwidth.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-fullwidth{display:block;width:100%}html.theme--documenter-dark .is-inline.textarea,html.theme--documenter-dark .is-inline.input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-inline{display:inline;width:auto}html.theme--documenter-dark .input.is-rounded,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input{border-radius:9999px;padding-left:calc(calc(0.75em - 1px) + 0.375em);padding-right:calc(calc(0.75em - 1px) + 0.375em)}html.theme--documenter-dark .input.is-static,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-static{background-color:transparent;border-color:transparent;box-shadow:none;padding-left:0;padding-right:0}html.theme--documenter-dark .textarea{display:block;max-width:100%;min-width:100%;padding:calc(0.75em - 1px);resize:vertical}html.theme--documenter-dark .textarea:not([rows]){max-height:40em;min-height:8em}html.theme--documenter-dark .textarea[rows]{height:initial}html.theme--documenter-dark .textarea.has-fixed-size{resize:none}html.theme--documenter-dark .radio,html.theme--documenter-dark .checkbox{cursor:pointer;display:inline-block;line-height:1.25;position:relative}html.theme--documenter-dark .radio input,html.theme--documenter-dark .checkbox input{cursor:pointer}html.theme--documenter-dark .radio:hover,html.theme--documenter-dark .checkbox:hover{color:#8c9b9d}html.theme--documenter-dark .radio[disabled],html.theme--documenter-dark .checkbox[disabled],fieldset[disabled] html.theme--documenter-dark .radio,fieldset[disabled] html.theme--documenter-dark .checkbox,html.theme--documenter-dark .radio input[disabled],html.theme--documenter-dark .checkbox input[disabled]{color:#fff;cursor:not-allowed}html.theme--documenter-dark .radio+.radio{margin-left:.5em}html.theme--documenter-dark .select{display:inline-block;max-width:100%;position:relative;vertical-align:top}html.theme--documenter-dark .select:not(.is-multiple){height:2.5em}html.theme--documenter-dark .select:not(.is-multiple):not(.is-loading)::after{border-color:#1abc9c;right:1.125em;z-index:4}html.theme--documenter-dark .select.is-rounded select,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.select select{border-radius:9999px;padding-left:1em}html.theme--documenter-dark .select select{cursor:pointer;display:block;font-size:1em;max-width:100%;outline:none}html.theme--documenter-dark .select select::-ms-expand{display:none}html.theme--documenter-dark .select select[disabled]:hover,fieldset[disabled] html.theme--documenter-dark .select select:hover{border-color:#282f2f}html.theme--documenter-dark .select select:not([multiple]){padding-right:2.5em}html.theme--documenter-dark .select select[multiple]{height:auto;padding:0}html.theme--documenter-dark .select select[multiple] option{padding:0.5em 1em}html.theme--documenter-dark .select:not(.is-multiple):not(.is-loading):hover::after{border-color:#8c9b9d}html.theme--documenter-dark .select.is-white:not(:hover)::after{border-color:#fff}html.theme--documenter-dark .select.is-white select{border-color:#fff}html.theme--documenter-dark .select.is-white select:hover,html.theme--documenter-dark .select.is-white select.is-hovered{border-color:#f2f2f2}html.theme--documenter-dark .select.is-white select:focus,html.theme--documenter-dark .select.is-white select.is-focused,html.theme--documenter-dark .select.is-white select:active,html.theme--documenter-dark .select.is-white select.is-active{box-shadow:0 0 0 0.125em rgba(255,255,255,0.25)}html.theme--documenter-dark .select.is-black:not(:hover)::after{border-color:#0a0a0a}html.theme--documenter-dark .select.is-black select{border-color:#0a0a0a}html.theme--documenter-dark .select.is-black select:hover,html.theme--documenter-dark .select.is-black select.is-hovered{border-color:#000}html.theme--documenter-dark .select.is-black select:focus,html.theme--documenter-dark .select.is-black select.is-focused,html.theme--documenter-dark .select.is-black select:active,html.theme--documenter-dark .select.is-black select.is-active{box-shadow:0 0 0 0.125em rgba(10,10,10,0.25)}html.theme--documenter-dark .select.is-light:not(:hover)::after{border-color:#ecf0f1}html.theme--documenter-dark .select.is-light select{border-color:#ecf0f1}html.theme--documenter-dark .select.is-light select:hover,html.theme--documenter-dark .select.is-light select.is-hovered{border-color:#dde4e6}html.theme--documenter-dark .select.is-light select:focus,html.theme--documenter-dark .select.is-light select.is-focused,html.theme--documenter-dark .select.is-light select:active,html.theme--documenter-dark .select.is-light select.is-active{box-shadow:0 0 0 0.125em rgba(236,240,241,0.25)}html.theme--documenter-dark .select.is-dark:not(:hover)::after,html.theme--documenter-dark .content kbd.select:not(:hover)::after{border-color:#282f2f}html.theme--documenter-dark .select.is-dark select,html.theme--documenter-dark .content kbd.select select{border-color:#282f2f}html.theme--documenter-dark .select.is-dark select:hover,html.theme--documenter-dark .content kbd.select select:hover,html.theme--documenter-dark .select.is-dark select.is-hovered,html.theme--documenter-dark .content kbd.select select.is-hovered{border-color:#1d2122}html.theme--documenter-dark .select.is-dark select:focus,html.theme--documenter-dark .content kbd.select select:focus,html.theme--documenter-dark .select.is-dark select.is-focused,html.theme--documenter-dark .content kbd.select select.is-focused,html.theme--documenter-dark .select.is-dark select:active,html.theme--documenter-dark .content kbd.select select:active,html.theme--documenter-dark .select.is-dark select.is-active,html.theme--documenter-dark .content kbd.select select.is-active{box-shadow:0 0 0 0.125em rgba(40,47,47,0.25)}html.theme--documenter-dark .select.is-primary:not(:hover)::after,html.theme--documenter-dark .docstring>section>a.select.docs-sourcelink:not(:hover)::after{border-color:#375a7f}html.theme--documenter-dark .select.is-primary select,html.theme--documenter-dark .docstring>section>a.select.docs-sourcelink select{border-color:#375a7f}html.theme--documenter-dark .select.is-primary select:hover,html.theme--documenter-dark .docstring>section>a.select.docs-sourcelink select:hover,html.theme--documenter-dark .select.is-primary select.is-hovered,html.theme--documenter-dark .docstring>section>a.select.docs-sourcelink select.is-hovered{border-color:#2f4d6d}html.theme--documenter-dark .select.is-primary select:focus,html.theme--documenter-dark .docstring>section>a.select.docs-sourcelink select:focus,html.theme--documenter-dark .select.is-primary select.is-focused,html.theme--documenter-dark .docstring>section>a.select.docs-sourcelink select.is-focused,html.theme--documenter-dark .select.is-primary select:active,html.theme--documenter-dark .docstring>section>a.select.docs-sourcelink select:active,html.theme--documenter-dark .select.is-primary select.is-active,html.theme--documenter-dark .docstring>section>a.select.docs-sourcelink select.is-active{box-shadow:0 0 0 0.125em rgba(55,90,127,0.25)}html.theme--documenter-dark .select.is-link:not(:hover)::after{border-color:#1abc9c}html.theme--documenter-dark .select.is-link select{border-color:#1abc9c}html.theme--documenter-dark .select.is-link select:hover,html.theme--documenter-dark .select.is-link select.is-hovered{border-color:#17a689}html.theme--documenter-dark .select.is-link select:focus,html.theme--documenter-dark .select.is-link select.is-focused,html.theme--documenter-dark .select.is-link select:active,html.theme--documenter-dark .select.is-link select.is-active{box-shadow:0 0 0 0.125em rgba(26,188,156,0.25)}html.theme--documenter-dark .select.is-info:not(:hover)::after{border-color:#024c7d}html.theme--documenter-dark .select.is-info select{border-color:#024c7d}html.theme--documenter-dark .select.is-info select:hover,html.theme--documenter-dark .select.is-info select.is-hovered{border-color:#023d64}html.theme--documenter-dark .select.is-info select:focus,html.theme--documenter-dark .select.is-info select.is-focused,html.theme--documenter-dark .select.is-info select:active,html.theme--documenter-dark .select.is-info select.is-active{box-shadow:0 0 0 0.125em rgba(2,76,125,0.25)}html.theme--documenter-dark .select.is-success:not(:hover)::after{border-color:#008438}html.theme--documenter-dark .select.is-success select{border-color:#008438}html.theme--documenter-dark .select.is-success select:hover,html.theme--documenter-dark .select.is-success select.is-hovered{border-color:#006b2d}html.theme--documenter-dark .select.is-success select:focus,html.theme--documenter-dark .select.is-success select.is-focused,html.theme--documenter-dark .select.is-success select:active,html.theme--documenter-dark .select.is-success select.is-active{box-shadow:0 0 0 0.125em rgba(0,132,56,0.25)}html.theme--documenter-dark .select.is-warning:not(:hover)::after{border-color:#ad8100}html.theme--documenter-dark .select.is-warning select{border-color:#ad8100}html.theme--documenter-dark .select.is-warning select:hover,html.theme--documenter-dark .select.is-warning select.is-hovered{border-color:#946e00}html.theme--documenter-dark .select.is-warning select:focus,html.theme--documenter-dark .select.is-warning select.is-focused,html.theme--documenter-dark .select.is-warning select:active,html.theme--documenter-dark .select.is-warning select.is-active{box-shadow:0 0 0 0.125em rgba(173,129,0,0.25)}html.theme--documenter-dark .select.is-danger:not(:hover)::after{border-color:#9e1b0d}html.theme--documenter-dark .select.is-danger select{border-color:#9e1b0d}html.theme--documenter-dark .select.is-danger select:hover,html.theme--documenter-dark .select.is-danger select.is-hovered{border-color:#86170b}html.theme--documenter-dark .select.is-danger select:focus,html.theme--documenter-dark .select.is-danger select.is-focused,html.theme--documenter-dark .select.is-danger select:active,html.theme--documenter-dark .select.is-danger select.is-active{box-shadow:0 0 0 0.125em rgba(158,27,13,0.25)}html.theme--documenter-dark .select.is-small,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.select{border-radius:3px;font-size:.75rem}html.theme--documenter-dark .select.is-medium{font-size:1.25rem}html.theme--documenter-dark .select.is-large{font-size:1.5rem}html.theme--documenter-dark .select.is-disabled::after{border-color:#fff !important;opacity:0.5}html.theme--documenter-dark .select.is-fullwidth{width:100%}html.theme--documenter-dark .select.is-fullwidth select{width:100%}html.theme--documenter-dark .select.is-loading::after{margin-top:0;position:absolute;right:.625em;top:0.625em;transform:none}html.theme--documenter-dark .select.is-loading.is-small:after,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-loading:after{font-size:.75rem}html.theme--documenter-dark .select.is-loading.is-medium:after{font-size:1.25rem}html.theme--documenter-dark .select.is-loading.is-large:after{font-size:1.5rem}html.theme--documenter-dark .file{align-items:stretch;display:flex;justify-content:flex-start;position:relative}html.theme--documenter-dark .file.is-white .file-cta{background-color:#fff;border-color:transparent;color:#0a0a0a}html.theme--documenter-dark .file.is-white:hover .file-cta,html.theme--documenter-dark .file.is-white.is-hovered .file-cta{background-color:#f9f9f9;border-color:transparent;color:#0a0a0a}html.theme--documenter-dark .file.is-white:focus .file-cta,html.theme--documenter-dark .file.is-white.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(255,255,255,0.25);color:#0a0a0a}html.theme--documenter-dark .file.is-white:active .file-cta,html.theme--documenter-dark .file.is-white.is-active .file-cta{background-color:#f2f2f2;border-color:transparent;color:#0a0a0a}html.theme--documenter-dark .file.is-black .file-cta{background-color:#0a0a0a;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-black:hover .file-cta,html.theme--documenter-dark .file.is-black.is-hovered .file-cta{background-color:#040404;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-black:focus .file-cta,html.theme--documenter-dark .file.is-black.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(10,10,10,0.25);color:#fff}html.theme--documenter-dark .file.is-black:active .file-cta,html.theme--documenter-dark .file.is-black.is-active .file-cta{background-color:#000;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-light .file-cta{background-color:#ecf0f1;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .file.is-light:hover .file-cta,html.theme--documenter-dark .file.is-light.is-hovered .file-cta{background-color:#e5eaec;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .file.is-light:focus .file-cta,html.theme--documenter-dark .file.is-light.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(236,240,241,0.25);color:rgba(0,0,0,0.7)}html.theme--documenter-dark .file.is-light:active .file-cta,html.theme--documenter-dark .file.is-light.is-active .file-cta{background-color:#dde4e6;border-color:transparent;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .file.is-dark .file-cta,html.theme--documenter-dark .content kbd.file .file-cta{background-color:#282f2f;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-dark:hover .file-cta,html.theme--documenter-dark .content kbd.file:hover .file-cta,html.theme--documenter-dark .file.is-dark.is-hovered .file-cta,html.theme--documenter-dark .content kbd.file.is-hovered .file-cta{background-color:#232829;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-dark:focus .file-cta,html.theme--documenter-dark .content kbd.file:focus .file-cta,html.theme--documenter-dark .file.is-dark.is-focused .file-cta,html.theme--documenter-dark .content kbd.file.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(40,47,47,0.25);color:#fff}html.theme--documenter-dark .file.is-dark:active .file-cta,html.theme--documenter-dark .content kbd.file:active .file-cta,html.theme--documenter-dark .file.is-dark.is-active .file-cta,html.theme--documenter-dark .content kbd.file.is-active .file-cta{background-color:#1d2122;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-primary .file-cta,html.theme--documenter-dark .docstring>section>a.file.docs-sourcelink .file-cta{background-color:#375a7f;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-primary:hover .file-cta,html.theme--documenter-dark .docstring>section>a.file.docs-sourcelink:hover .file-cta,html.theme--documenter-dark .file.is-primary.is-hovered .file-cta,html.theme--documenter-dark .docstring>section>a.file.is-hovered.docs-sourcelink .file-cta{background-color:#335476;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-primary:focus .file-cta,html.theme--documenter-dark .docstring>section>a.file.docs-sourcelink:focus .file-cta,html.theme--documenter-dark .file.is-primary.is-focused .file-cta,html.theme--documenter-dark .docstring>section>a.file.is-focused.docs-sourcelink .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(55,90,127,0.25);color:#fff}html.theme--documenter-dark .file.is-primary:active .file-cta,html.theme--documenter-dark .docstring>section>a.file.docs-sourcelink:active .file-cta,html.theme--documenter-dark .file.is-primary.is-active .file-cta,html.theme--documenter-dark .docstring>section>a.file.is-active.docs-sourcelink .file-cta{background-color:#2f4d6d;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-link .file-cta{background-color:#1abc9c;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-link:hover .file-cta,html.theme--documenter-dark .file.is-link.is-hovered .file-cta{background-color:#18b193;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-link:focus .file-cta,html.theme--documenter-dark .file.is-link.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(26,188,156,0.25);color:#fff}html.theme--documenter-dark .file.is-link:active .file-cta,html.theme--documenter-dark .file.is-link.is-active .file-cta{background-color:#17a689;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-info .file-cta{background-color:#024c7d;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-info:hover .file-cta,html.theme--documenter-dark .file.is-info.is-hovered .file-cta{background-color:#024470;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-info:focus .file-cta,html.theme--documenter-dark .file.is-info.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(2,76,125,0.25);color:#fff}html.theme--documenter-dark .file.is-info:active .file-cta,html.theme--documenter-dark .file.is-info.is-active .file-cta{background-color:#023d64;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-success .file-cta{background-color:#008438;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-success:hover .file-cta,html.theme--documenter-dark .file.is-success.is-hovered .file-cta{background-color:#073;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-success:focus .file-cta,html.theme--documenter-dark .file.is-success.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(0,132,56,0.25);color:#fff}html.theme--documenter-dark .file.is-success:active .file-cta,html.theme--documenter-dark .file.is-success.is-active .file-cta{background-color:#006b2d;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-warning .file-cta{background-color:#ad8100;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-warning:hover .file-cta,html.theme--documenter-dark .file.is-warning.is-hovered .file-cta{background-color:#a07700;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-warning:focus .file-cta,html.theme--documenter-dark .file.is-warning.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(173,129,0,0.25);color:#fff}html.theme--documenter-dark .file.is-warning:active .file-cta,html.theme--documenter-dark .file.is-warning.is-active .file-cta{background-color:#946e00;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-danger .file-cta{background-color:#9e1b0d;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-danger:hover .file-cta,html.theme--documenter-dark .file.is-danger.is-hovered .file-cta{background-color:#92190c;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-danger:focus .file-cta,html.theme--documenter-dark .file.is-danger.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(158,27,13,0.25);color:#fff}html.theme--documenter-dark .file.is-danger:active .file-cta,html.theme--documenter-dark .file.is-danger.is-active .file-cta{background-color:#86170b;border-color:transparent;color:#fff}html.theme--documenter-dark .file.is-small,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.file{font-size:.75rem}html.theme--documenter-dark .file.is-normal{font-size:1rem}html.theme--documenter-dark .file.is-medium{font-size:1.25rem}html.theme--documenter-dark .file.is-medium .file-icon .fa{font-size:21px}html.theme--documenter-dark .file.is-large{font-size:1.5rem}html.theme--documenter-dark .file.is-large .file-icon .fa{font-size:28px}html.theme--documenter-dark .file.has-name .file-cta{border-bottom-right-radius:0;border-top-right-radius:0}html.theme--documenter-dark .file.has-name .file-name{border-bottom-left-radius:0;border-top-left-radius:0}html.theme--documenter-dark .file.has-name.is-empty .file-cta{border-radius:.4em}html.theme--documenter-dark .file.has-name.is-empty .file-name{display:none}html.theme--documenter-dark .file.is-boxed .file-label{flex-direction:column}html.theme--documenter-dark .file.is-boxed .file-cta{flex-direction:column;height:auto;padding:1em 3em}html.theme--documenter-dark .file.is-boxed .file-name{border-width:0 1px 1px}html.theme--documenter-dark .file.is-boxed .file-icon{height:1.5em;width:1.5em}html.theme--documenter-dark .file.is-boxed .file-icon .fa{font-size:21px}html.theme--documenter-dark .file.is-boxed.is-small .file-icon .fa,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-boxed .file-icon .fa{font-size:14px}html.theme--documenter-dark .file.is-boxed.is-medium .file-icon .fa{font-size:28px}html.theme--documenter-dark .file.is-boxed.is-large .file-icon .fa{font-size:35px}html.theme--documenter-dark .file.is-boxed.has-name .file-cta{border-radius:.4em .4em 0 0}html.theme--documenter-dark .file.is-boxed.has-name .file-name{border-radius:0 0 .4em .4em;border-width:0 1px 1px}html.theme--documenter-dark .file.is-centered{justify-content:center}html.theme--documenter-dark .file.is-fullwidth .file-label{width:100%}html.theme--documenter-dark .file.is-fullwidth .file-name{flex-grow:1;max-width:none}html.theme--documenter-dark .file.is-right{justify-content:flex-end}html.theme--documenter-dark .file.is-right .file-cta{border-radius:0 .4em .4em 0}html.theme--documenter-dark .file.is-right .file-name{border-radius:.4em 0 0 .4em;border-width:1px 0 1px 1px;order:-1}html.theme--documenter-dark .file-label{align-items:stretch;display:flex;cursor:pointer;justify-content:flex-start;overflow:hidden;position:relative}html.theme--documenter-dark .file-label:hover .file-cta{background-color:#232829;color:#f2f2f2}html.theme--documenter-dark .file-label:hover .file-name{border-color:#596668}html.theme--documenter-dark .file-label:active .file-cta{background-color:#1d2122;color:#f2f2f2}html.theme--documenter-dark .file-label:active .file-name{border-color:#535f61}html.theme--documenter-dark .file-input{height:100%;left:0;opacity:0;outline:none;position:absolute;top:0;width:100%}html.theme--documenter-dark .file-cta,html.theme--documenter-dark .file-name{border-color:#5e6d6f;border-radius:.4em;font-size:1em;padding-left:1em;padding-right:1em;white-space:nowrap}html.theme--documenter-dark .file-cta{background-color:#282f2f;color:#fff}html.theme--documenter-dark .file-name{border-color:#5e6d6f;border-style:solid;border-width:1px 1px 1px 0;display:block;max-width:16em;overflow:hidden;text-align:inherit;text-overflow:ellipsis}html.theme--documenter-dark .file-icon{align-items:center;display:flex;height:1em;justify-content:center;margin-right:.5em;width:1em}html.theme--documenter-dark .file-icon .fa{font-size:14px}html.theme--documenter-dark .label{color:#f2f2f2;display:block;font-size:1rem;font-weight:700}html.theme--documenter-dark .label:not(:last-child){margin-bottom:0.5em}html.theme--documenter-dark .label.is-small,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.label{font-size:.75rem}html.theme--documenter-dark .label.is-medium{font-size:1.25rem}html.theme--documenter-dark .label.is-large{font-size:1.5rem}html.theme--documenter-dark .help{display:block;font-size:.75rem;margin-top:0.25rem}html.theme--documenter-dark .help.is-white{color:#fff}html.theme--documenter-dark .help.is-black{color:#0a0a0a}html.theme--documenter-dark .help.is-light{color:#ecf0f1}html.theme--documenter-dark .help.is-dark,html.theme--documenter-dark .content kbd.help{color:#282f2f}html.theme--documenter-dark .help.is-primary,html.theme--documenter-dark .docstring>section>a.help.docs-sourcelink{color:#375a7f}html.theme--documenter-dark .help.is-link{color:#1abc9c}html.theme--documenter-dark .help.is-info{color:#024c7d}html.theme--documenter-dark .help.is-success{color:#008438}html.theme--documenter-dark .help.is-warning{color:#ad8100}html.theme--documenter-dark .help.is-danger{color:#9e1b0d}html.theme--documenter-dark .field:not(:last-child){margin-bottom:0.75rem}html.theme--documenter-dark .field.has-addons{display:flex;justify-content:flex-start}html.theme--documenter-dark .field.has-addons .control:not(:last-child){margin-right:-1px}html.theme--documenter-dark .field.has-addons .control:not(:first-child):not(:last-child) .button,html.theme--documenter-dark .field.has-addons .control:not(:first-child):not(:last-child) .input,html.theme--documenter-dark .field.has-addons .control:not(:first-child):not(:last-child) #documenter .docs-sidebar form.docs-search>input,html.theme--documenter-dark #documenter .docs-sidebar .field.has-addons .control:not(:first-child):not(:last-child) form.docs-search>input,html.theme--documenter-dark .field.has-addons .control:not(:first-child):not(:last-child) .select select{border-radius:0}html.theme--documenter-dark .field.has-addons .control:first-child:not(:only-child) .button,html.theme--documenter-dark .field.has-addons .control:first-child:not(:only-child) .input,html.theme--documenter-dark .field.has-addons .control:first-child:not(:only-child) #documenter .docs-sidebar form.docs-search>input,html.theme--documenter-dark #documenter .docs-sidebar .field.has-addons .control:first-child:not(:only-child) form.docs-search>input,html.theme--documenter-dark .field.has-addons .control:first-child:not(:only-child) .select select{border-bottom-right-radius:0;border-top-right-radius:0}html.theme--documenter-dark .field.has-addons .control:last-child:not(:only-child) .button,html.theme--documenter-dark .field.has-addons .control:last-child:not(:only-child) .input,html.theme--documenter-dark .field.has-addons .control:last-child:not(:only-child) #documenter .docs-sidebar form.docs-search>input,html.theme--documenter-dark #documenter .docs-sidebar .field.has-addons .control:last-child:not(:only-child) form.docs-search>input,html.theme--documenter-dark .field.has-addons .control:last-child:not(:only-child) .select select{border-bottom-left-radius:0;border-top-left-radius:0}html.theme--documenter-dark .field.has-addons .control .button:not([disabled]):hover,html.theme--documenter-dark .field.has-addons .control .button.is-hovered:not([disabled]),html.theme--documenter-dark .field.has-addons .control .input:not([disabled]):hover,html.theme--documenter-dark .field.has-addons .control #documenter .docs-sidebar form.docs-search>input:not([disabled]):hover,html.theme--documenter-dark #documenter .docs-sidebar .field.has-addons .control form.docs-search>input:not([disabled]):hover,html.theme--documenter-dark .field.has-addons .control .input.is-hovered:not([disabled]),html.theme--documenter-dark .field.has-addons .control #documenter .docs-sidebar form.docs-search>input.is-hovered:not([disabled]),html.theme--documenter-dark #documenter .docs-sidebar .field.has-addons .control form.docs-search>input.is-hovered:not([disabled]),html.theme--documenter-dark .field.has-addons .control .select select:not([disabled]):hover,html.theme--documenter-dark .field.has-addons .control .select select.is-hovered:not([disabled]){z-index:2}html.theme--documenter-dark .field.has-addons .control .button:not([disabled]):focus,html.theme--documenter-dark .field.has-addons .control .button.is-focused:not([disabled]),html.theme--documenter-dark .field.has-addons .control .button:not([disabled]):active,html.theme--documenter-dark .field.has-addons .control .button.is-active:not([disabled]),html.theme--documenter-dark .field.has-addons .control .input:not([disabled]):focus,html.theme--documenter-dark .field.has-addons .control #documenter .docs-sidebar form.docs-search>input:not([disabled]):focus,html.theme--documenter-dark #documenter .docs-sidebar .field.has-addons .control form.docs-search>input:not([disabled]):focus,html.theme--documenter-dark .field.has-addons .control .input.is-focused:not([disabled]),html.theme--documenter-dark .field.has-addons .control #documenter .docs-sidebar form.docs-search>input.is-focused:not([disabled]),html.theme--documenter-dark #documenter .docs-sidebar .field.has-addons .control form.docs-search>input.is-focused:not([disabled]),html.theme--documenter-dark .field.has-addons .control .input:not([disabled]):active,html.theme--documenter-dark .field.has-addons .control #documenter .docs-sidebar form.docs-search>input:not([disabled]):active,html.theme--documenter-dark #documenter .docs-sidebar .field.has-addons .control form.docs-search>input:not([disabled]):active,html.theme--documenter-dark .field.has-addons .control .input.is-active:not([disabled]),html.theme--documenter-dark .field.has-addons .control #documenter .docs-sidebar form.docs-search>input.is-active:not([disabled]),html.theme--documenter-dark #documenter .docs-sidebar .field.has-addons .control form.docs-search>input.is-active:not([disabled]),html.theme--documenter-dark .field.has-addons .control .select select:not([disabled]):focus,html.theme--documenter-dark .field.has-addons .control .select select.is-focused:not([disabled]),html.theme--documenter-dark .field.has-addons .control .select select:not([disabled]):active,html.theme--documenter-dark .field.has-addons .control .select select.is-active:not([disabled]){z-index:3}html.theme--documenter-dark .field.has-addons .control .button:not([disabled]):focus:hover,html.theme--documenter-dark .field.has-addons .control .button.is-focused:not([disabled]):hover,html.theme--documenter-dark .field.has-addons .control .button:not([disabled]):active:hover,html.theme--documenter-dark .field.has-addons .control .button.is-active:not([disabled]):hover,html.theme--documenter-dark .field.has-addons .control .input:not([disabled]):focus:hover,html.theme--documenter-dark .field.has-addons .control #documenter .docs-sidebar form.docs-search>input:not([disabled]):focus:hover,html.theme--documenter-dark #documenter .docs-sidebar .field.has-addons .control form.docs-search>input:not([disabled]):focus:hover,html.theme--documenter-dark .field.has-addons .control .input.is-focused:not([disabled]):hover,html.theme--documenter-dark .field.has-addons .control #documenter .docs-sidebar form.docs-search>input.is-focused:not([disabled]):hover,html.theme--documenter-dark #documenter .docs-sidebar .field.has-addons .control form.docs-search>input.is-focused:not([disabled]):hover,html.theme--documenter-dark .field.has-addons .control .input:not([disabled]):active:hover,html.theme--documenter-dark .field.has-addons .control #documenter .docs-sidebar form.docs-search>input:not([disabled]):active:hover,html.theme--documenter-dark #documenter .docs-sidebar .field.has-addons .control form.docs-search>input:not([disabled]):active:hover,html.theme--documenter-dark .field.has-addons .control .input.is-active:not([disabled]):hover,html.theme--documenter-dark .field.has-addons .control #documenter .docs-sidebar form.docs-search>input.is-active:not([disabled]):hover,html.theme--documenter-dark #documenter .docs-sidebar .field.has-addons .control form.docs-search>input.is-active:not([disabled]):hover,html.theme--documenter-dark .field.has-addons .control .select select:not([disabled]):focus:hover,html.theme--documenter-dark .field.has-addons .control .select select.is-focused:not([disabled]):hover,html.theme--documenter-dark .field.has-addons .control .select select:not([disabled]):active:hover,html.theme--documenter-dark .field.has-addons .control .select select.is-active:not([disabled]):hover{z-index:4}html.theme--documenter-dark .field.has-addons .control.is-expanded{flex-grow:1;flex-shrink:1}html.theme--documenter-dark .field.has-addons.has-addons-centered{justify-content:center}html.theme--documenter-dark .field.has-addons.has-addons-right{justify-content:flex-end}html.theme--documenter-dark .field.has-addons.has-addons-fullwidth .control{flex-grow:1;flex-shrink:0}html.theme--documenter-dark .field.is-grouped{display:flex;justify-content:flex-start}html.theme--documenter-dark .field.is-grouped>.control{flex-shrink:0}html.theme--documenter-dark .field.is-grouped>.control:not(:last-child){margin-bottom:0;margin-right:.75rem}html.theme--documenter-dark .field.is-grouped>.control.is-expanded{flex-grow:1;flex-shrink:1}html.theme--documenter-dark .field.is-grouped.is-grouped-centered{justify-content:center}html.theme--documenter-dark .field.is-grouped.is-grouped-right{justify-content:flex-end}html.theme--documenter-dark .field.is-grouped.is-grouped-multiline{flex-wrap:wrap}html.theme--documenter-dark .field.is-grouped.is-grouped-multiline>.control:last-child,html.theme--documenter-dark .field.is-grouped.is-grouped-multiline>.control:not(:last-child){margin-bottom:0.75rem}html.theme--documenter-dark .field.is-grouped.is-grouped-multiline:last-child{margin-bottom:-0.75rem}html.theme--documenter-dark .field.is-grouped.is-grouped-multiline:not(:last-child){margin-bottom:0}@media screen and (min-width: 769px),print{html.theme--documenter-dark .field.is-horizontal{display:flex}}html.theme--documenter-dark .field-label .label{font-size:inherit}@media screen and (max-width: 768px){html.theme--documenter-dark .field-label{margin-bottom:0.5rem}}@media screen and (min-width: 769px),print{html.theme--documenter-dark .field-label{flex-basis:0;flex-grow:1;flex-shrink:0;margin-right:1.5rem;text-align:right}html.theme--documenter-dark .field-label.is-small,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.field-label{font-size:.75rem;padding-top:0.375em}html.theme--documenter-dark .field-label.is-normal{padding-top:0.375em}html.theme--documenter-dark .field-label.is-medium{font-size:1.25rem;padding-top:0.375em}html.theme--documenter-dark .field-label.is-large{font-size:1.5rem;padding-top:0.375em}}html.theme--documenter-dark .field-body .field .field{margin-bottom:0}@media screen and (min-width: 769px),print{html.theme--documenter-dark .field-body{display:flex;flex-basis:0;flex-grow:5;flex-shrink:1}html.theme--documenter-dark .field-body .field{margin-bottom:0}html.theme--documenter-dark .field-body>.field{flex-shrink:1}html.theme--documenter-dark .field-body>.field:not(.is-narrow){flex-grow:1}html.theme--documenter-dark .field-body>.field:not(:last-child){margin-right:.75rem}}html.theme--documenter-dark .control{box-sizing:border-box;clear:both;font-size:1rem;position:relative;text-align:inherit}html.theme--documenter-dark .control.has-icons-left .input:focus~.icon,html.theme--documenter-dark .control.has-icons-left #documenter .docs-sidebar form.docs-search>input:focus~.icon,html.theme--documenter-dark #documenter .docs-sidebar .control.has-icons-left form.docs-search>input:focus~.icon,html.theme--documenter-dark .control.has-icons-left .select:focus~.icon,html.theme--documenter-dark .control.has-icons-right .input:focus~.icon,html.theme--documenter-dark .control.has-icons-right #documenter .docs-sidebar form.docs-search>input:focus~.icon,html.theme--documenter-dark #documenter .docs-sidebar .control.has-icons-right form.docs-search>input:focus~.icon,html.theme--documenter-dark .control.has-icons-right .select:focus~.icon{color:#282f2f}html.theme--documenter-dark .control.has-icons-left .input.is-small~.icon,html.theme--documenter-dark .control.has-icons-left #documenter .docs-sidebar form.docs-search>input~.icon,html.theme--documenter-dark #documenter .docs-sidebar .control.has-icons-left form.docs-search>input~.icon,html.theme--documenter-dark .control.has-icons-left .select.is-small~.icon,html.theme--documenter-dark .control.has-icons-right .input.is-small~.icon,html.theme--documenter-dark .control.has-icons-right #documenter .docs-sidebar form.docs-search>input~.icon,html.theme--documenter-dark #documenter .docs-sidebar .control.has-icons-right form.docs-search>input~.icon,html.theme--documenter-dark .control.has-icons-right .select.is-small~.icon{font-size:.75rem}html.theme--documenter-dark .control.has-icons-left .input.is-medium~.icon,html.theme--documenter-dark .control.has-icons-left #documenter .docs-sidebar form.docs-search>input.is-medium~.icon,html.theme--documenter-dark #documenter .docs-sidebar .control.has-icons-left form.docs-search>input.is-medium~.icon,html.theme--documenter-dark .control.has-icons-left .select.is-medium~.icon,html.theme--documenter-dark .control.has-icons-right .input.is-medium~.icon,html.theme--documenter-dark .control.has-icons-right #documenter .docs-sidebar form.docs-search>input.is-medium~.icon,html.theme--documenter-dark #documenter .docs-sidebar .control.has-icons-right form.docs-search>input.is-medium~.icon,html.theme--documenter-dark .control.has-icons-right .select.is-medium~.icon{font-size:1.25rem}html.theme--documenter-dark .control.has-icons-left .input.is-large~.icon,html.theme--documenter-dark .control.has-icons-left #documenter .docs-sidebar form.docs-search>input.is-large~.icon,html.theme--documenter-dark #documenter .docs-sidebar .control.has-icons-left form.docs-search>input.is-large~.icon,html.theme--documenter-dark .control.has-icons-left .select.is-large~.icon,html.theme--documenter-dark .control.has-icons-right .input.is-large~.icon,html.theme--documenter-dark .control.has-icons-right #documenter .docs-sidebar form.docs-search>input.is-large~.icon,html.theme--documenter-dark #documenter .docs-sidebar .control.has-icons-right form.docs-search>input.is-large~.icon,html.theme--documenter-dark .control.has-icons-right .select.is-large~.icon{font-size:1.5rem}html.theme--documenter-dark .control.has-icons-left .icon,html.theme--documenter-dark .control.has-icons-right .icon{color:#5e6d6f;height:2.5em;pointer-events:none;position:absolute;top:0;width:2.5em;z-index:4}html.theme--documenter-dark .control.has-icons-left .input,html.theme--documenter-dark .control.has-icons-left #documenter .docs-sidebar form.docs-search>input,html.theme--documenter-dark #documenter .docs-sidebar .control.has-icons-left form.docs-search>input,html.theme--documenter-dark .control.has-icons-left .select select{padding-left:2.5em}html.theme--documenter-dark .control.has-icons-left .icon.is-left{left:0}html.theme--documenter-dark .control.has-icons-right .input,html.theme--documenter-dark .control.has-icons-right #documenter .docs-sidebar form.docs-search>input,html.theme--documenter-dark #documenter .docs-sidebar .control.has-icons-right form.docs-search>input,html.theme--documenter-dark .control.has-icons-right .select select{padding-right:2.5em}html.theme--documenter-dark .control.has-icons-right .icon.is-right{right:0}html.theme--documenter-dark .control.is-loading::after{position:absolute !important;right:.625em;top:0.625em;z-index:4}html.theme--documenter-dark .control.is-loading.is-small:after,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.is-loading:after{font-size:.75rem}html.theme--documenter-dark .control.is-loading.is-medium:after{font-size:1.25rem}html.theme--documenter-dark .control.is-loading.is-large:after{font-size:1.5rem}html.theme--documenter-dark .breadcrumb{font-size:1rem;white-space:nowrap}html.theme--documenter-dark .breadcrumb a{align-items:center;color:#1abc9c;display:flex;justify-content:center;padding:0 .75em}html.theme--documenter-dark .breadcrumb a:hover{color:#1dd2af}html.theme--documenter-dark .breadcrumb li{align-items:center;display:flex}html.theme--documenter-dark .breadcrumb li:first-child a{padding-left:0}html.theme--documenter-dark .breadcrumb li.is-active a{color:#f2f2f2;cursor:default;pointer-events:none}html.theme--documenter-dark .breadcrumb li+li::before{color:#8c9b9d;content:"\0002f"}html.theme--documenter-dark .breadcrumb ul,html.theme--documenter-dark .breadcrumb ol{align-items:flex-start;display:flex;flex-wrap:wrap;justify-content:flex-start}html.theme--documenter-dark .breadcrumb .icon:first-child{margin-right:.5em}html.theme--documenter-dark .breadcrumb .icon:last-child{margin-left:.5em}html.theme--documenter-dark .breadcrumb.is-centered ol,html.theme--documenter-dark .breadcrumb.is-centered ul{justify-content:center}html.theme--documenter-dark .breadcrumb.is-right ol,html.theme--documenter-dark .breadcrumb.is-right ul{justify-content:flex-end}html.theme--documenter-dark .breadcrumb.is-small,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.breadcrumb{font-size:.75rem}html.theme--documenter-dark .breadcrumb.is-medium{font-size:1.25rem}html.theme--documenter-dark .breadcrumb.is-large{font-size:1.5rem}html.theme--documenter-dark .breadcrumb.has-arrow-separator li+li::before{content:"\02192"}html.theme--documenter-dark .breadcrumb.has-bullet-separator li+li::before{content:"\02022"}html.theme--documenter-dark .breadcrumb.has-dot-separator li+li::before{content:"\000b7"}html.theme--documenter-dark .breadcrumb.has-succeeds-separator li+li::before{content:"\0227B"}html.theme--documenter-dark .card{background-color:#fff;border-radius:.25rem;box-shadow:#171717;color:#fff;max-width:100%;position:relative}html.theme--documenter-dark .card-footer:first-child,html.theme--documenter-dark .card-content:first-child,html.theme--documenter-dark .card-header:first-child{border-top-left-radius:.25rem;border-top-right-radius:.25rem}html.theme--documenter-dark .card-footer:last-child,html.theme--documenter-dark .card-content:last-child,html.theme--documenter-dark .card-header:last-child{border-bottom-left-radius:.25rem;border-bottom-right-radius:.25rem}html.theme--documenter-dark .card-header{background-color:rgba(0,0,0,0);align-items:stretch;box-shadow:0 0.125em 0.25em rgba(10,10,10,0.1);display:flex}html.theme--documenter-dark .card-header-title{align-items:center;color:#f2f2f2;display:flex;flex-grow:1;font-weight:700;padding:0.75rem 1rem}html.theme--documenter-dark .card-header-title.is-centered{justify-content:center}html.theme--documenter-dark .card-header-icon{-moz-appearance:none;-webkit-appearance:none;appearance:none;background:none;border:none;color:currentColor;font-family:inherit;font-size:1em;margin:0;padding:0;align-items:center;cursor:pointer;display:flex;justify-content:center;padding:0.75rem 1rem}html.theme--documenter-dark .card-image{display:block;position:relative}html.theme--documenter-dark .card-image:first-child img{border-top-left-radius:.25rem;border-top-right-radius:.25rem}html.theme--documenter-dark .card-image:last-child img{border-bottom-left-radius:.25rem;border-bottom-right-radius:.25rem}html.theme--documenter-dark .card-content{background-color:rgba(0,0,0,0);padding:1.5rem}html.theme--documenter-dark .card-footer{background-color:rgba(0,0,0,0);border-top:1px solid #ededed;align-items:stretch;display:flex}html.theme--documenter-dark .card-footer-item{align-items:center;display:flex;flex-basis:0;flex-grow:1;flex-shrink:0;justify-content:center;padding:.75rem}html.theme--documenter-dark .card-footer-item:not(:last-child){border-right:1px solid #ededed}html.theme--documenter-dark .card .media:not(:last-child){margin-bottom:1.5rem}html.theme--documenter-dark .dropdown{display:inline-flex;position:relative;vertical-align:top}html.theme--documenter-dark .dropdown.is-active .dropdown-menu,html.theme--documenter-dark .dropdown.is-hoverable:hover .dropdown-menu{display:block}html.theme--documenter-dark .dropdown.is-right .dropdown-menu{left:auto;right:0}html.theme--documenter-dark .dropdown.is-up .dropdown-menu{bottom:100%;padding-bottom:4px;padding-top:initial;top:auto}html.theme--documenter-dark .dropdown-menu{display:none;left:0;min-width:12rem;padding-top:4px;position:absolute;top:100%;z-index:20}html.theme--documenter-dark .dropdown-content{background-color:#282f2f;border-radius:.4em;box-shadow:#171717;padding-bottom:.5rem;padding-top:.5rem}html.theme--documenter-dark .dropdown-item{color:#fff;display:block;font-size:0.875rem;line-height:1.5;padding:0.375rem 1rem;position:relative}html.theme--documenter-dark a.dropdown-item,html.theme--documenter-dark button.dropdown-item{padding-right:3rem;text-align:inherit;white-space:nowrap;width:100%}html.theme--documenter-dark a.dropdown-item:hover,html.theme--documenter-dark button.dropdown-item:hover{background-color:#282f2f;color:#0a0a0a}html.theme--documenter-dark a.dropdown-item.is-active,html.theme--documenter-dark button.dropdown-item.is-active{background-color:#1abc9c;color:#fff}html.theme--documenter-dark .dropdown-divider{background-color:#ededed;border:none;display:block;height:1px;margin:0.5rem 0}html.theme--documenter-dark .level{align-items:center;justify-content:space-between}html.theme--documenter-dark .level code{border-radius:.4em}html.theme--documenter-dark .level img{display:inline-block;vertical-align:top}html.theme--documenter-dark .level.is-mobile{display:flex}html.theme--documenter-dark .level.is-mobile .level-left,html.theme--documenter-dark .level.is-mobile .level-right{display:flex}html.theme--documenter-dark .level.is-mobile .level-left+.level-right{margin-top:0}html.theme--documenter-dark .level.is-mobile .level-item:not(:last-child){margin-bottom:0;margin-right:.75rem}html.theme--documenter-dark .level.is-mobile .level-item:not(.is-narrow){flex-grow:1}@media screen and (min-width: 769px),print{html.theme--documenter-dark .level{display:flex}html.theme--documenter-dark .level>.level-item:not(.is-narrow){flex-grow:1}}html.theme--documenter-dark .level-item{align-items:center;display:flex;flex-basis:auto;flex-grow:0;flex-shrink:0;justify-content:center}html.theme--documenter-dark .level-item .title,html.theme--documenter-dark .level-item .subtitle{margin-bottom:0}@media screen and (max-width: 768px){html.theme--documenter-dark .level-item:not(:last-child){margin-bottom:.75rem}}html.theme--documenter-dark .level-left,html.theme--documenter-dark .level-right{flex-basis:auto;flex-grow:0;flex-shrink:0}html.theme--documenter-dark .level-left .level-item.is-flexible,html.theme--documenter-dark .level-right .level-item.is-flexible{flex-grow:1}@media screen and (min-width: 769px),print{html.theme--documenter-dark .level-left .level-item:not(:last-child),html.theme--documenter-dark .level-right .level-item:not(:last-child){margin-right:.75rem}}html.theme--documenter-dark .level-left{align-items:center;justify-content:flex-start}@media screen and (max-width: 768px){html.theme--documenter-dark .level-left+.level-right{margin-top:1.5rem}}@media screen and (min-width: 769px),print{html.theme--documenter-dark .level-left{display:flex}}html.theme--documenter-dark .level-right{align-items:center;justify-content:flex-end}@media screen and (min-width: 769px),print{html.theme--documenter-dark .level-right{display:flex}}html.theme--documenter-dark .media{align-items:flex-start;display:flex;text-align:inherit}html.theme--documenter-dark .media .content:not(:last-child){margin-bottom:.75rem}html.theme--documenter-dark .media .media{border-top:1px solid rgba(94,109,111,0.5);display:flex;padding-top:.75rem}html.theme--documenter-dark .media .media .content:not(:last-child),html.theme--documenter-dark .media .media .control:not(:last-child){margin-bottom:.5rem}html.theme--documenter-dark .media .media .media{padding-top:.5rem}html.theme--documenter-dark .media .media .media+.media{margin-top:.5rem}html.theme--documenter-dark .media+.media{border-top:1px solid rgba(94,109,111,0.5);margin-top:1rem;padding-top:1rem}html.theme--documenter-dark .media.is-large+.media{margin-top:1.5rem;padding-top:1.5rem}html.theme--documenter-dark .media-left,html.theme--documenter-dark .media-right{flex-basis:auto;flex-grow:0;flex-shrink:0}html.theme--documenter-dark .media-left{margin-right:1rem}html.theme--documenter-dark .media-right{margin-left:1rem}html.theme--documenter-dark .media-content{flex-basis:auto;flex-grow:1;flex-shrink:1;text-align:inherit}@media screen and (max-width: 768px){html.theme--documenter-dark .media-content{overflow-x:auto}}html.theme--documenter-dark .menu{font-size:1rem}html.theme--documenter-dark .menu.is-small,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.menu{font-size:.75rem}html.theme--documenter-dark .menu.is-medium{font-size:1.25rem}html.theme--documenter-dark .menu.is-large{font-size:1.5rem}html.theme--documenter-dark .menu-list{line-height:1.25}html.theme--documenter-dark .menu-list a{border-radius:3px;color:#fff;display:block;padding:0.5em 0.75em}html.theme--documenter-dark .menu-list a:hover{background-color:#282f2f;color:#f2f2f2}html.theme--documenter-dark .menu-list a.is-active{background-color:#1abc9c;color:#fff}html.theme--documenter-dark .menu-list li ul{border-left:1px solid #5e6d6f;margin:.75em;padding-left:.75em}html.theme--documenter-dark .menu-label{color:#fff;font-size:.75em;letter-spacing:.1em;text-transform:uppercase}html.theme--documenter-dark .menu-label:not(:first-child){margin-top:1em}html.theme--documenter-dark .menu-label:not(:last-child){margin-bottom:1em}html.theme--documenter-dark .message{background-color:#282f2f;border-radius:.4em;font-size:1rem}html.theme--documenter-dark .message strong{color:currentColor}html.theme--documenter-dark .message a:not(.button):not(.tag):not(.dropdown-item){color:currentColor;text-decoration:underline}html.theme--documenter-dark .message.is-small,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.message{font-size:.75rem}html.theme--documenter-dark .message.is-medium{font-size:1.25rem}html.theme--documenter-dark .message.is-large{font-size:1.5rem}html.theme--documenter-dark .message.is-white{background-color:#fff}html.theme--documenter-dark .message.is-white .message-header{background-color:#fff;color:#0a0a0a}html.theme--documenter-dark .message.is-white .message-body{border-color:#fff}html.theme--documenter-dark .message.is-black{background-color:#fafafa}html.theme--documenter-dark .message.is-black .message-header{background-color:#0a0a0a;color:#fff}html.theme--documenter-dark .message.is-black .message-body{border-color:#0a0a0a}html.theme--documenter-dark .message.is-light{background-color:#f9fafb}html.theme--documenter-dark .message.is-light .message-header{background-color:#ecf0f1;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .message.is-light .message-body{border-color:#ecf0f1}html.theme--documenter-dark .message.is-dark,html.theme--documenter-dark .content kbd.message{background-color:#f9fafa}html.theme--documenter-dark .message.is-dark .message-header,html.theme--documenter-dark .content kbd.message .message-header{background-color:#282f2f;color:#fff}html.theme--documenter-dark .message.is-dark .message-body,html.theme--documenter-dark .content kbd.message .message-body{border-color:#282f2f}html.theme--documenter-dark .message.is-primary,html.theme--documenter-dark .docstring>section>a.message.docs-sourcelink{background-color:#f1f5f9}html.theme--documenter-dark .message.is-primary .message-header,html.theme--documenter-dark .docstring>section>a.message.docs-sourcelink .message-header{background-color:#375a7f;color:#fff}html.theme--documenter-dark .message.is-primary .message-body,html.theme--documenter-dark .docstring>section>a.message.docs-sourcelink .message-body{border-color:#375a7f;color:#4d7eb2}html.theme--documenter-dark .message.is-link{background-color:#edfdf9}html.theme--documenter-dark .message.is-link .message-header{background-color:#1abc9c;color:#fff}html.theme--documenter-dark .message.is-link .message-body{border-color:#1abc9c;color:#15987e}html.theme--documenter-dark .message.is-info{background-color:#ebf7ff}html.theme--documenter-dark .message.is-info .message-header{background-color:#024c7d;color:#fff}html.theme--documenter-dark .message.is-info .message-body{border-color:#024c7d;color:#0e9dfb}html.theme--documenter-dark .message.is-success{background-color:#ebfff3}html.theme--documenter-dark .message.is-success .message-header{background-color:#008438;color:#fff}html.theme--documenter-dark .message.is-success .message-body{border-color:#008438;color:#00eb64}html.theme--documenter-dark .message.is-warning{background-color:#fffaeb}html.theme--documenter-dark .message.is-warning .message-header{background-color:#ad8100;color:#fff}html.theme--documenter-dark .message.is-warning .message-body{border-color:#ad8100;color:#d19c00}html.theme--documenter-dark .message.is-danger{background-color:#fdeeec}html.theme--documenter-dark .message.is-danger .message-header{background-color:#9e1b0d;color:#fff}html.theme--documenter-dark .message.is-danger .message-body{border-color:#9e1b0d;color:#ec311d}html.theme--documenter-dark .message-header{align-items:center;background-color:#fff;border-radius:.4em .4em 0 0;color:rgba(0,0,0,0.7);display:flex;font-weight:700;justify-content:space-between;line-height:1.25;padding:0.75em 1em;position:relative}html.theme--documenter-dark .message-header .delete{flex-grow:0;flex-shrink:0;margin-left:.75em}html.theme--documenter-dark .message-header+.message-body{border-width:0;border-top-left-radius:0;border-top-right-radius:0}html.theme--documenter-dark .message-body{border-color:#5e6d6f;border-radius:.4em;border-style:solid;border-width:0 0 0 4px;color:#fff;padding:1.25em 1.5em}html.theme--documenter-dark .message-body code,html.theme--documenter-dark .message-body pre{background-color:#fff}html.theme--documenter-dark .message-body pre code{background-color:rgba(0,0,0,0)}html.theme--documenter-dark .modal{align-items:center;display:none;flex-direction:column;justify-content:center;overflow:hidden;position:fixed;z-index:40}html.theme--documenter-dark .modal.is-active{display:flex}html.theme--documenter-dark .modal-background{background-color:rgba(10,10,10,0.86)}html.theme--documenter-dark .modal-content,html.theme--documenter-dark .modal-card{margin:0 20px;max-height:calc(100vh - 160px);overflow:auto;position:relative;width:100%}@media screen and (min-width: 769px){html.theme--documenter-dark .modal-content,html.theme--documenter-dark .modal-card{margin:0 auto;max-height:calc(100vh - 40px);width:640px}}html.theme--documenter-dark .modal-close{background:none;height:40px;position:fixed;right:20px;top:20px;width:40px}html.theme--documenter-dark .modal-card{display:flex;flex-direction:column;max-height:calc(100vh - 40px);overflow:hidden;-ms-overflow-y:visible}html.theme--documenter-dark .modal-card-head,html.theme--documenter-dark .modal-card-foot{align-items:center;background-color:#282f2f;display:flex;flex-shrink:0;justify-content:flex-start;padding:20px;position:relative}html.theme--documenter-dark .modal-card-head{border-bottom:1px solid #5e6d6f;border-top-left-radius:8px;border-top-right-radius:8px}html.theme--documenter-dark .modal-card-title{color:#f2f2f2;flex-grow:1;flex-shrink:0;font-size:1.5rem;line-height:1}html.theme--documenter-dark .modal-card-foot{border-bottom-left-radius:8px;border-bottom-right-radius:8px;border-top:1px solid #5e6d6f}html.theme--documenter-dark .modal-card-foot .button:not(:last-child){margin-right:.5em}html.theme--documenter-dark .modal-card-body{-webkit-overflow-scrolling:touch;background-color:#fff;flex-grow:1;flex-shrink:1;overflow:auto;padding:20px}html.theme--documenter-dark .navbar{background-color:#375a7f;min-height:4rem;position:relative;z-index:30}html.theme--documenter-dark .navbar.is-white{background-color:#fff;color:#0a0a0a}html.theme--documenter-dark .navbar.is-white .navbar-brand>.navbar-item,html.theme--documenter-dark .navbar.is-white .navbar-brand .navbar-link{color:#0a0a0a}html.theme--documenter-dark .navbar.is-white .navbar-brand>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-white .navbar-brand>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-white .navbar-brand>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-white .navbar-brand .navbar-link:focus,html.theme--documenter-dark .navbar.is-white .navbar-brand .navbar-link:hover,html.theme--documenter-dark .navbar.is-white .navbar-brand .navbar-link.is-active{background-color:#f2f2f2;color:#0a0a0a}html.theme--documenter-dark .navbar.is-white .navbar-brand .navbar-link::after{border-color:#0a0a0a}html.theme--documenter-dark .navbar.is-white .navbar-burger{color:#0a0a0a}@media screen and (min-width: 1056px){html.theme--documenter-dark .navbar.is-white .navbar-start>.navbar-item,html.theme--documenter-dark .navbar.is-white .navbar-start .navbar-link,html.theme--documenter-dark .navbar.is-white .navbar-end>.navbar-item,html.theme--documenter-dark .navbar.is-white .navbar-end .navbar-link{color:#0a0a0a}html.theme--documenter-dark .navbar.is-white .navbar-start>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-white .navbar-start>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-white .navbar-start>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-white .navbar-start .navbar-link:focus,html.theme--documenter-dark .navbar.is-white .navbar-start .navbar-link:hover,html.theme--documenter-dark .navbar.is-white .navbar-start .navbar-link.is-active,html.theme--documenter-dark .navbar.is-white .navbar-end>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-white .navbar-end>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-white .navbar-end>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-white .navbar-end .navbar-link:focus,html.theme--documenter-dark .navbar.is-white .navbar-end .navbar-link:hover,html.theme--documenter-dark .navbar.is-white .navbar-end .navbar-link.is-active{background-color:#f2f2f2;color:#0a0a0a}html.theme--documenter-dark .navbar.is-white .navbar-start .navbar-link::after,html.theme--documenter-dark .navbar.is-white .navbar-end .navbar-link::after{border-color:#0a0a0a}html.theme--documenter-dark .navbar.is-white .navbar-item.has-dropdown:focus .navbar-link,html.theme--documenter-dark .navbar.is-white .navbar-item.has-dropdown:hover .navbar-link,html.theme--documenter-dark .navbar.is-white .navbar-item.has-dropdown.is-active .navbar-link{background-color:#f2f2f2;color:#0a0a0a}html.theme--documenter-dark .navbar.is-white .navbar-dropdown a.navbar-item.is-active{background-color:#fff;color:#0a0a0a}}html.theme--documenter-dark .navbar.is-black{background-color:#0a0a0a;color:#fff}html.theme--documenter-dark .navbar.is-black .navbar-brand>.navbar-item,html.theme--documenter-dark .navbar.is-black .navbar-brand .navbar-link{color:#fff}html.theme--documenter-dark .navbar.is-black .navbar-brand>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-black .navbar-brand>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-black .navbar-brand>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-black .navbar-brand .navbar-link:focus,html.theme--documenter-dark .navbar.is-black .navbar-brand .navbar-link:hover,html.theme--documenter-dark .navbar.is-black .navbar-brand .navbar-link.is-active{background-color:#000;color:#fff}html.theme--documenter-dark .navbar.is-black .navbar-brand .navbar-link::after{border-color:#fff}html.theme--documenter-dark .navbar.is-black .navbar-burger{color:#fff}@media screen and (min-width: 1056px){html.theme--documenter-dark .navbar.is-black .navbar-start>.navbar-item,html.theme--documenter-dark .navbar.is-black .navbar-start .navbar-link,html.theme--documenter-dark .navbar.is-black .navbar-end>.navbar-item,html.theme--documenter-dark .navbar.is-black .navbar-end .navbar-link{color:#fff}html.theme--documenter-dark .navbar.is-black .navbar-start>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-black .navbar-start>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-black .navbar-start>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-black .navbar-start .navbar-link:focus,html.theme--documenter-dark .navbar.is-black .navbar-start .navbar-link:hover,html.theme--documenter-dark .navbar.is-black .navbar-start .navbar-link.is-active,html.theme--documenter-dark .navbar.is-black .navbar-end>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-black .navbar-end>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-black .navbar-end>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-black .navbar-end .navbar-link:focus,html.theme--documenter-dark .navbar.is-black .navbar-end .navbar-link:hover,html.theme--documenter-dark .navbar.is-black .navbar-end .navbar-link.is-active{background-color:#000;color:#fff}html.theme--documenter-dark .navbar.is-black .navbar-start .navbar-link::after,html.theme--documenter-dark .navbar.is-black .navbar-end .navbar-link::after{border-color:#fff}html.theme--documenter-dark .navbar.is-black .navbar-item.has-dropdown:focus .navbar-link,html.theme--documenter-dark .navbar.is-black .navbar-item.has-dropdown:hover .navbar-link,html.theme--documenter-dark .navbar.is-black .navbar-item.has-dropdown.is-active .navbar-link{background-color:#000;color:#fff}html.theme--documenter-dark .navbar.is-black .navbar-dropdown a.navbar-item.is-active{background-color:#0a0a0a;color:#fff}}html.theme--documenter-dark .navbar.is-light{background-color:#ecf0f1;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .navbar.is-light .navbar-brand>.navbar-item,html.theme--documenter-dark .navbar.is-light .navbar-brand .navbar-link{color:rgba(0,0,0,0.7)}html.theme--documenter-dark .navbar.is-light .navbar-brand>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-light .navbar-brand>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-light .navbar-brand>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-light .navbar-brand .navbar-link:focus,html.theme--documenter-dark .navbar.is-light .navbar-brand .navbar-link:hover,html.theme--documenter-dark .navbar.is-light .navbar-brand .navbar-link.is-active{background-color:#dde4e6;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .navbar.is-light .navbar-brand .navbar-link::after{border-color:rgba(0,0,0,0.7)}html.theme--documenter-dark .navbar.is-light .navbar-burger{color:rgba(0,0,0,0.7)}@media screen and (min-width: 1056px){html.theme--documenter-dark .navbar.is-light .navbar-start>.navbar-item,html.theme--documenter-dark .navbar.is-light .navbar-start .navbar-link,html.theme--documenter-dark .navbar.is-light .navbar-end>.navbar-item,html.theme--documenter-dark .navbar.is-light .navbar-end .navbar-link{color:rgba(0,0,0,0.7)}html.theme--documenter-dark .navbar.is-light .navbar-start>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-light .navbar-start>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-light .navbar-start>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-light .navbar-start .navbar-link:focus,html.theme--documenter-dark .navbar.is-light .navbar-start .navbar-link:hover,html.theme--documenter-dark .navbar.is-light .navbar-start .navbar-link.is-active,html.theme--documenter-dark .navbar.is-light .navbar-end>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-light .navbar-end>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-light .navbar-end>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-light .navbar-end .navbar-link:focus,html.theme--documenter-dark .navbar.is-light .navbar-end .navbar-link:hover,html.theme--documenter-dark .navbar.is-light .navbar-end .navbar-link.is-active{background-color:#dde4e6;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .navbar.is-light .navbar-start .navbar-link::after,html.theme--documenter-dark .navbar.is-light .navbar-end .navbar-link::after{border-color:rgba(0,0,0,0.7)}html.theme--documenter-dark .navbar.is-light .navbar-item.has-dropdown:focus .navbar-link,html.theme--documenter-dark .navbar.is-light .navbar-item.has-dropdown:hover .navbar-link,html.theme--documenter-dark .navbar.is-light .navbar-item.has-dropdown.is-active .navbar-link{background-color:#dde4e6;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .navbar.is-light .navbar-dropdown a.navbar-item.is-active{background-color:#ecf0f1;color:rgba(0,0,0,0.7)}}html.theme--documenter-dark .navbar.is-dark,html.theme--documenter-dark .content kbd.navbar{background-color:#282f2f;color:#fff}html.theme--documenter-dark .navbar.is-dark .navbar-brand>.navbar-item,html.theme--documenter-dark .content kbd.navbar .navbar-brand>.navbar-item,html.theme--documenter-dark .navbar.is-dark .navbar-brand .navbar-link,html.theme--documenter-dark .content kbd.navbar .navbar-brand .navbar-link{color:#fff}html.theme--documenter-dark .navbar.is-dark .navbar-brand>a.navbar-item:focus,html.theme--documenter-dark .content kbd.navbar .navbar-brand>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-dark .navbar-brand>a.navbar-item:hover,html.theme--documenter-dark .content kbd.navbar .navbar-brand>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-dark .navbar-brand>a.navbar-item.is-active,html.theme--documenter-dark .content kbd.navbar .navbar-brand>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-dark .navbar-brand .navbar-link:focus,html.theme--documenter-dark .content kbd.navbar .navbar-brand .navbar-link:focus,html.theme--documenter-dark .navbar.is-dark .navbar-brand .navbar-link:hover,html.theme--documenter-dark .content kbd.navbar .navbar-brand .navbar-link:hover,html.theme--documenter-dark .navbar.is-dark .navbar-brand .navbar-link.is-active,html.theme--documenter-dark .content kbd.navbar .navbar-brand .navbar-link.is-active{background-color:#1d2122;color:#fff}html.theme--documenter-dark .navbar.is-dark .navbar-brand .navbar-link::after,html.theme--documenter-dark .content kbd.navbar .navbar-brand .navbar-link::after{border-color:#fff}html.theme--documenter-dark .navbar.is-dark .navbar-burger,html.theme--documenter-dark .content kbd.navbar .navbar-burger{color:#fff}@media screen and (min-width: 1056px){html.theme--documenter-dark .navbar.is-dark .navbar-start>.navbar-item,html.theme--documenter-dark .content kbd.navbar .navbar-start>.navbar-item,html.theme--documenter-dark .navbar.is-dark .navbar-start .navbar-link,html.theme--documenter-dark .content kbd.navbar .navbar-start .navbar-link,html.theme--documenter-dark .navbar.is-dark .navbar-end>.navbar-item,html.theme--documenter-dark .content kbd.navbar .navbar-end>.navbar-item,html.theme--documenter-dark .navbar.is-dark .navbar-end .navbar-link,html.theme--documenter-dark .content kbd.navbar .navbar-end .navbar-link{color:#fff}html.theme--documenter-dark .navbar.is-dark .navbar-start>a.navbar-item:focus,html.theme--documenter-dark .content kbd.navbar .navbar-start>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-dark .navbar-start>a.navbar-item:hover,html.theme--documenter-dark .content kbd.navbar .navbar-start>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-dark .navbar-start>a.navbar-item.is-active,html.theme--documenter-dark .content kbd.navbar .navbar-start>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-dark .navbar-start .navbar-link:focus,html.theme--documenter-dark .content kbd.navbar .navbar-start .navbar-link:focus,html.theme--documenter-dark .navbar.is-dark .navbar-start .navbar-link:hover,html.theme--documenter-dark .content kbd.navbar .navbar-start .navbar-link:hover,html.theme--documenter-dark .navbar.is-dark .navbar-start .navbar-link.is-active,html.theme--documenter-dark .content kbd.navbar .navbar-start .navbar-link.is-active,html.theme--documenter-dark .navbar.is-dark .navbar-end>a.navbar-item:focus,html.theme--documenter-dark .content kbd.navbar .navbar-end>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-dark .navbar-end>a.navbar-item:hover,html.theme--documenter-dark .content kbd.navbar .navbar-end>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-dark .navbar-end>a.navbar-item.is-active,html.theme--documenter-dark .content kbd.navbar .navbar-end>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-dark .navbar-end .navbar-link:focus,html.theme--documenter-dark .content kbd.navbar .navbar-end .navbar-link:focus,html.theme--documenter-dark .navbar.is-dark .navbar-end .navbar-link:hover,html.theme--documenter-dark .content kbd.navbar .navbar-end .navbar-link:hover,html.theme--documenter-dark .navbar.is-dark .navbar-end .navbar-link.is-active,html.theme--documenter-dark .content kbd.navbar .navbar-end .navbar-link.is-active{background-color:#1d2122;color:#fff}html.theme--documenter-dark .navbar.is-dark .navbar-start .navbar-link::after,html.theme--documenter-dark .content kbd.navbar .navbar-start .navbar-link::after,html.theme--documenter-dark .navbar.is-dark .navbar-end .navbar-link::after,html.theme--documenter-dark .content kbd.navbar .navbar-end .navbar-link::after{border-color:#fff}html.theme--documenter-dark .navbar.is-dark .navbar-item.has-dropdown:focus .navbar-link,html.theme--documenter-dark .content kbd.navbar .navbar-item.has-dropdown:focus .navbar-link,html.theme--documenter-dark .navbar.is-dark .navbar-item.has-dropdown:hover .navbar-link,html.theme--documenter-dark .content kbd.navbar .navbar-item.has-dropdown:hover .navbar-link,html.theme--documenter-dark .navbar.is-dark .navbar-item.has-dropdown.is-active .navbar-link,html.theme--documenter-dark .content kbd.navbar .navbar-item.has-dropdown.is-active .navbar-link{background-color:#1d2122;color:#fff}html.theme--documenter-dark .navbar.is-dark .navbar-dropdown a.navbar-item.is-active,html.theme--documenter-dark .content kbd.navbar .navbar-dropdown a.navbar-item.is-active{background-color:#282f2f;color:#fff}}html.theme--documenter-dark .navbar.is-primary,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink{background-color:#375a7f;color:#fff}html.theme--documenter-dark .navbar.is-primary .navbar-brand>.navbar-item,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-brand>.navbar-item,html.theme--documenter-dark .navbar.is-primary .navbar-brand .navbar-link,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-brand .navbar-link{color:#fff}html.theme--documenter-dark .navbar.is-primary .navbar-brand>a.navbar-item:focus,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-brand>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-primary .navbar-brand>a.navbar-item:hover,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-brand>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-primary .navbar-brand>a.navbar-item.is-active,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-brand>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-primary .navbar-brand .navbar-link:focus,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-brand .navbar-link:focus,html.theme--documenter-dark .navbar.is-primary .navbar-brand .navbar-link:hover,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-brand .navbar-link:hover,html.theme--documenter-dark .navbar.is-primary .navbar-brand .navbar-link.is-active,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-brand .navbar-link.is-active{background-color:#2f4d6d;color:#fff}html.theme--documenter-dark .navbar.is-primary .navbar-brand .navbar-link::after,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-brand .navbar-link::after{border-color:#fff}html.theme--documenter-dark .navbar.is-primary .navbar-burger,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-burger{color:#fff}@media screen and (min-width: 1056px){html.theme--documenter-dark .navbar.is-primary .navbar-start>.navbar-item,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-start>.navbar-item,html.theme--documenter-dark .navbar.is-primary .navbar-start .navbar-link,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-start .navbar-link,html.theme--documenter-dark .navbar.is-primary .navbar-end>.navbar-item,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-end>.navbar-item,html.theme--documenter-dark .navbar.is-primary .navbar-end .navbar-link,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-end .navbar-link{color:#fff}html.theme--documenter-dark .navbar.is-primary .navbar-start>a.navbar-item:focus,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-start>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-primary .navbar-start>a.navbar-item:hover,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-start>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-primary .navbar-start>a.navbar-item.is-active,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-start>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-primary .navbar-start .navbar-link:focus,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-start .navbar-link:focus,html.theme--documenter-dark .navbar.is-primary .navbar-start .navbar-link:hover,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-start .navbar-link:hover,html.theme--documenter-dark .navbar.is-primary .navbar-start .navbar-link.is-active,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-start .navbar-link.is-active,html.theme--documenter-dark .navbar.is-primary .navbar-end>a.navbar-item:focus,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-end>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-primary .navbar-end>a.navbar-item:hover,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-end>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-primary .navbar-end>a.navbar-item.is-active,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-end>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-primary .navbar-end .navbar-link:focus,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-end .navbar-link:focus,html.theme--documenter-dark .navbar.is-primary .navbar-end .navbar-link:hover,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-end .navbar-link:hover,html.theme--documenter-dark .navbar.is-primary .navbar-end .navbar-link.is-active,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-end .navbar-link.is-active{background-color:#2f4d6d;color:#fff}html.theme--documenter-dark .navbar.is-primary .navbar-start .navbar-link::after,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-start .navbar-link::after,html.theme--documenter-dark .navbar.is-primary .navbar-end .navbar-link::after,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-end .navbar-link::after{border-color:#fff}html.theme--documenter-dark .navbar.is-primary .navbar-item.has-dropdown:focus .navbar-link,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-item.has-dropdown:focus .navbar-link,html.theme--documenter-dark .navbar.is-primary .navbar-item.has-dropdown:hover .navbar-link,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-item.has-dropdown:hover .navbar-link,html.theme--documenter-dark .navbar.is-primary .navbar-item.has-dropdown.is-active .navbar-link,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-item.has-dropdown.is-active .navbar-link{background-color:#2f4d6d;color:#fff}html.theme--documenter-dark .navbar.is-primary .navbar-dropdown a.navbar-item.is-active,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-dropdown a.navbar-item.is-active{background-color:#375a7f;color:#fff}}html.theme--documenter-dark .navbar.is-link{background-color:#1abc9c;color:#fff}html.theme--documenter-dark .navbar.is-link .navbar-brand>.navbar-item,html.theme--documenter-dark .navbar.is-link .navbar-brand .navbar-link{color:#fff}html.theme--documenter-dark .navbar.is-link .navbar-brand>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-link .navbar-brand>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-link .navbar-brand>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-link .navbar-brand .navbar-link:focus,html.theme--documenter-dark .navbar.is-link .navbar-brand .navbar-link:hover,html.theme--documenter-dark .navbar.is-link .navbar-brand .navbar-link.is-active{background-color:#17a689;color:#fff}html.theme--documenter-dark .navbar.is-link .navbar-brand .navbar-link::after{border-color:#fff}html.theme--documenter-dark .navbar.is-link .navbar-burger{color:#fff}@media screen and (min-width: 1056px){html.theme--documenter-dark .navbar.is-link .navbar-start>.navbar-item,html.theme--documenter-dark .navbar.is-link .navbar-start .navbar-link,html.theme--documenter-dark .navbar.is-link .navbar-end>.navbar-item,html.theme--documenter-dark .navbar.is-link .navbar-end .navbar-link{color:#fff}html.theme--documenter-dark .navbar.is-link .navbar-start>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-link .navbar-start>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-link .navbar-start>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-link .navbar-start .navbar-link:focus,html.theme--documenter-dark .navbar.is-link .navbar-start .navbar-link:hover,html.theme--documenter-dark .navbar.is-link .navbar-start .navbar-link.is-active,html.theme--documenter-dark .navbar.is-link .navbar-end>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-link .navbar-end>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-link .navbar-end>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-link .navbar-end .navbar-link:focus,html.theme--documenter-dark .navbar.is-link .navbar-end .navbar-link:hover,html.theme--documenter-dark .navbar.is-link .navbar-end .navbar-link.is-active{background-color:#17a689;color:#fff}html.theme--documenter-dark .navbar.is-link .navbar-start .navbar-link::after,html.theme--documenter-dark .navbar.is-link .navbar-end .navbar-link::after{border-color:#fff}html.theme--documenter-dark .navbar.is-link .navbar-item.has-dropdown:focus .navbar-link,html.theme--documenter-dark .navbar.is-link .navbar-item.has-dropdown:hover .navbar-link,html.theme--documenter-dark .navbar.is-link .navbar-item.has-dropdown.is-active .navbar-link{background-color:#17a689;color:#fff}html.theme--documenter-dark .navbar.is-link .navbar-dropdown a.navbar-item.is-active{background-color:#1abc9c;color:#fff}}html.theme--documenter-dark .navbar.is-info{background-color:#024c7d;color:#fff}html.theme--documenter-dark .navbar.is-info .navbar-brand>.navbar-item,html.theme--documenter-dark .navbar.is-info .navbar-brand .navbar-link{color:#fff}html.theme--documenter-dark .navbar.is-info .navbar-brand>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-info .navbar-brand>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-info .navbar-brand>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-info .navbar-brand .navbar-link:focus,html.theme--documenter-dark .navbar.is-info .navbar-brand .navbar-link:hover,html.theme--documenter-dark .navbar.is-info .navbar-brand .navbar-link.is-active{background-color:#023d64;color:#fff}html.theme--documenter-dark .navbar.is-info .navbar-brand .navbar-link::after{border-color:#fff}html.theme--documenter-dark .navbar.is-info .navbar-burger{color:#fff}@media screen and (min-width: 1056px){html.theme--documenter-dark .navbar.is-info .navbar-start>.navbar-item,html.theme--documenter-dark .navbar.is-info .navbar-start .navbar-link,html.theme--documenter-dark .navbar.is-info .navbar-end>.navbar-item,html.theme--documenter-dark .navbar.is-info .navbar-end .navbar-link{color:#fff}html.theme--documenter-dark .navbar.is-info .navbar-start>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-info .navbar-start>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-info .navbar-start>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-info .navbar-start .navbar-link:focus,html.theme--documenter-dark .navbar.is-info .navbar-start .navbar-link:hover,html.theme--documenter-dark .navbar.is-info .navbar-start .navbar-link.is-active,html.theme--documenter-dark .navbar.is-info .navbar-end>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-info .navbar-end>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-info .navbar-end>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-info .navbar-end .navbar-link:focus,html.theme--documenter-dark .navbar.is-info .navbar-end .navbar-link:hover,html.theme--documenter-dark .navbar.is-info .navbar-end .navbar-link.is-active{background-color:#023d64;color:#fff}html.theme--documenter-dark .navbar.is-info .navbar-start .navbar-link::after,html.theme--documenter-dark .navbar.is-info .navbar-end .navbar-link::after{border-color:#fff}html.theme--documenter-dark .navbar.is-info .navbar-item.has-dropdown:focus .navbar-link,html.theme--documenter-dark .navbar.is-info .navbar-item.has-dropdown:hover .navbar-link,html.theme--documenter-dark .navbar.is-info .navbar-item.has-dropdown.is-active .navbar-link{background-color:#023d64;color:#fff}html.theme--documenter-dark .navbar.is-info .navbar-dropdown a.navbar-item.is-active{background-color:#024c7d;color:#fff}}html.theme--documenter-dark .navbar.is-success{background-color:#008438;color:#fff}html.theme--documenter-dark .navbar.is-success .navbar-brand>.navbar-item,html.theme--documenter-dark .navbar.is-success .navbar-brand .navbar-link{color:#fff}html.theme--documenter-dark .navbar.is-success .navbar-brand>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-success .navbar-brand>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-success .navbar-brand>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-success .navbar-brand .navbar-link:focus,html.theme--documenter-dark .navbar.is-success .navbar-brand .navbar-link:hover,html.theme--documenter-dark .navbar.is-success .navbar-brand .navbar-link.is-active{background-color:#006b2d;color:#fff}html.theme--documenter-dark .navbar.is-success .navbar-brand .navbar-link::after{border-color:#fff}html.theme--documenter-dark .navbar.is-success .navbar-burger{color:#fff}@media screen and (min-width: 1056px){html.theme--documenter-dark .navbar.is-success .navbar-start>.navbar-item,html.theme--documenter-dark .navbar.is-success .navbar-start .navbar-link,html.theme--documenter-dark .navbar.is-success .navbar-end>.navbar-item,html.theme--documenter-dark .navbar.is-success .navbar-end .navbar-link{color:#fff}html.theme--documenter-dark .navbar.is-success .navbar-start>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-success .navbar-start>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-success .navbar-start>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-success .navbar-start .navbar-link:focus,html.theme--documenter-dark .navbar.is-success .navbar-start .navbar-link:hover,html.theme--documenter-dark .navbar.is-success .navbar-start .navbar-link.is-active,html.theme--documenter-dark .navbar.is-success .navbar-end>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-success .navbar-end>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-success .navbar-end>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-success .navbar-end .navbar-link:focus,html.theme--documenter-dark .navbar.is-success .navbar-end .navbar-link:hover,html.theme--documenter-dark .navbar.is-success .navbar-end .navbar-link.is-active{background-color:#006b2d;color:#fff}html.theme--documenter-dark .navbar.is-success .navbar-start .navbar-link::after,html.theme--documenter-dark .navbar.is-success .navbar-end .navbar-link::after{border-color:#fff}html.theme--documenter-dark .navbar.is-success .navbar-item.has-dropdown:focus .navbar-link,html.theme--documenter-dark .navbar.is-success .navbar-item.has-dropdown:hover .navbar-link,html.theme--documenter-dark .navbar.is-success .navbar-item.has-dropdown.is-active .navbar-link{background-color:#006b2d;color:#fff}html.theme--documenter-dark .navbar.is-success .navbar-dropdown a.navbar-item.is-active{background-color:#008438;color:#fff}}html.theme--documenter-dark .navbar.is-warning{background-color:#ad8100;color:#fff}html.theme--documenter-dark .navbar.is-warning .navbar-brand>.navbar-item,html.theme--documenter-dark .navbar.is-warning .navbar-brand .navbar-link{color:#fff}html.theme--documenter-dark .navbar.is-warning .navbar-brand>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-warning .navbar-brand>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-warning .navbar-brand>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-warning .navbar-brand .navbar-link:focus,html.theme--documenter-dark .navbar.is-warning .navbar-brand .navbar-link:hover,html.theme--documenter-dark .navbar.is-warning .navbar-brand .navbar-link.is-active{background-color:#946e00;color:#fff}html.theme--documenter-dark .navbar.is-warning .navbar-brand .navbar-link::after{border-color:#fff}html.theme--documenter-dark .navbar.is-warning .navbar-burger{color:#fff}@media screen and (min-width: 1056px){html.theme--documenter-dark .navbar.is-warning .navbar-start>.navbar-item,html.theme--documenter-dark .navbar.is-warning .navbar-start .navbar-link,html.theme--documenter-dark .navbar.is-warning .navbar-end>.navbar-item,html.theme--documenter-dark .navbar.is-warning .navbar-end .navbar-link{color:#fff}html.theme--documenter-dark .navbar.is-warning .navbar-start>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-warning .navbar-start>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-warning .navbar-start>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-warning .navbar-start .navbar-link:focus,html.theme--documenter-dark .navbar.is-warning .navbar-start .navbar-link:hover,html.theme--documenter-dark .navbar.is-warning .navbar-start .navbar-link.is-active,html.theme--documenter-dark .navbar.is-warning .navbar-end>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-warning .navbar-end>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-warning .navbar-end>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-warning .navbar-end .navbar-link:focus,html.theme--documenter-dark .navbar.is-warning .navbar-end .navbar-link:hover,html.theme--documenter-dark .navbar.is-warning .navbar-end .navbar-link.is-active{background-color:#946e00;color:#fff}html.theme--documenter-dark .navbar.is-warning .navbar-start .navbar-link::after,html.theme--documenter-dark .navbar.is-warning .navbar-end .navbar-link::after{border-color:#fff}html.theme--documenter-dark .navbar.is-warning .navbar-item.has-dropdown:focus .navbar-link,html.theme--documenter-dark .navbar.is-warning .navbar-item.has-dropdown:hover .navbar-link,html.theme--documenter-dark .navbar.is-warning .navbar-item.has-dropdown.is-active .navbar-link{background-color:#946e00;color:#fff}html.theme--documenter-dark .navbar.is-warning .navbar-dropdown a.navbar-item.is-active{background-color:#ad8100;color:#fff}}html.theme--documenter-dark .navbar.is-danger{background-color:#9e1b0d;color:#fff}html.theme--documenter-dark .navbar.is-danger .navbar-brand>.navbar-item,html.theme--documenter-dark .navbar.is-danger .navbar-brand .navbar-link{color:#fff}html.theme--documenter-dark .navbar.is-danger .navbar-brand>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-danger .navbar-brand>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-danger .navbar-brand>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-danger .navbar-brand .navbar-link:focus,html.theme--documenter-dark .navbar.is-danger .navbar-brand .navbar-link:hover,html.theme--documenter-dark .navbar.is-danger .navbar-brand .navbar-link.is-active{background-color:#86170b;color:#fff}html.theme--documenter-dark .navbar.is-danger .navbar-brand .navbar-link::after{border-color:#fff}html.theme--documenter-dark .navbar.is-danger .navbar-burger{color:#fff}@media screen and (min-width: 1056px){html.theme--documenter-dark .navbar.is-danger .navbar-start>.navbar-item,html.theme--documenter-dark .navbar.is-danger .navbar-start .navbar-link,html.theme--documenter-dark .navbar.is-danger .navbar-end>.navbar-item,html.theme--documenter-dark .navbar.is-danger .navbar-end .navbar-link{color:#fff}html.theme--documenter-dark .navbar.is-danger .navbar-start>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-danger .navbar-start>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-danger .navbar-start>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-danger .navbar-start .navbar-link:focus,html.theme--documenter-dark .navbar.is-danger .navbar-start .navbar-link:hover,html.theme--documenter-dark .navbar.is-danger .navbar-start .navbar-link.is-active,html.theme--documenter-dark .navbar.is-danger .navbar-end>a.navbar-item:focus,html.theme--documenter-dark .navbar.is-danger .navbar-end>a.navbar-item:hover,html.theme--documenter-dark .navbar.is-danger .navbar-end>a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-danger .navbar-end .navbar-link:focus,html.theme--documenter-dark .navbar.is-danger .navbar-end .navbar-link:hover,html.theme--documenter-dark .navbar.is-danger .navbar-end .navbar-link.is-active{background-color:#86170b;color:#fff}html.theme--documenter-dark .navbar.is-danger .navbar-start .navbar-link::after,html.theme--documenter-dark .navbar.is-danger .navbar-end .navbar-link::after{border-color:#fff}html.theme--documenter-dark .navbar.is-danger .navbar-item.has-dropdown:focus .navbar-link,html.theme--documenter-dark .navbar.is-danger .navbar-item.has-dropdown:hover .navbar-link,html.theme--documenter-dark .navbar.is-danger .navbar-item.has-dropdown.is-active .navbar-link{background-color:#86170b;color:#fff}html.theme--documenter-dark .navbar.is-danger .navbar-dropdown a.navbar-item.is-active{background-color:#9e1b0d;color:#fff}}html.theme--documenter-dark .navbar>.container{align-items:stretch;display:flex;min-height:4rem;width:100%}html.theme--documenter-dark .navbar.has-shadow{box-shadow:0 2px 0 0 #282f2f}html.theme--documenter-dark .navbar.is-fixed-bottom,html.theme--documenter-dark .navbar.is-fixed-top{left:0;position:fixed;right:0;z-index:30}html.theme--documenter-dark .navbar.is-fixed-bottom{bottom:0}html.theme--documenter-dark .navbar.is-fixed-bottom.has-shadow{box-shadow:0 -2px 0 0 #282f2f}html.theme--documenter-dark .navbar.is-fixed-top{top:0}html.theme--documenter-dark html.has-navbar-fixed-top,html.theme--documenter-dark body.has-navbar-fixed-top{padding-top:4rem}html.theme--documenter-dark html.has-navbar-fixed-bottom,html.theme--documenter-dark body.has-navbar-fixed-bottom{padding-bottom:4rem}html.theme--documenter-dark .navbar-brand,html.theme--documenter-dark .navbar-tabs{align-items:stretch;display:flex;flex-shrink:0;min-height:4rem}html.theme--documenter-dark .navbar-brand a.navbar-item:focus,html.theme--documenter-dark .navbar-brand a.navbar-item:hover{background-color:transparent}html.theme--documenter-dark .navbar-tabs{-webkit-overflow-scrolling:touch;max-width:100vw;overflow-x:auto;overflow-y:hidden}html.theme--documenter-dark .navbar-burger{color:#fff;-moz-appearance:none;-webkit-appearance:none;appearance:none;background:none;border:none;cursor:pointer;display:block;height:4rem;position:relative;width:4rem;margin-left:auto}html.theme--documenter-dark .navbar-burger span{background-color:currentColor;display:block;height:1px;left:calc(50% - 8px);position:absolute;transform-origin:center;transition-duration:86ms;transition-property:background-color, opacity, transform;transition-timing-function:ease-out;width:16px}html.theme--documenter-dark .navbar-burger span:nth-child(1){top:calc(50% - 6px)}html.theme--documenter-dark .navbar-burger span:nth-child(2){top:calc(50% - 1px)}html.theme--documenter-dark .navbar-burger span:nth-child(3){top:calc(50% + 4px)}html.theme--documenter-dark .navbar-burger:hover{background-color:rgba(0,0,0,0.05)}html.theme--documenter-dark .navbar-burger.is-active span:nth-child(1){transform:translateY(5px) rotate(45deg)}html.theme--documenter-dark .navbar-burger.is-active span:nth-child(2){opacity:0}html.theme--documenter-dark .navbar-burger.is-active span:nth-child(3){transform:translateY(-5px) rotate(-45deg)}html.theme--documenter-dark .navbar-menu{display:none}html.theme--documenter-dark .navbar-item,html.theme--documenter-dark .navbar-link{color:#fff;display:block;line-height:1.5;padding:0.5rem 0.75rem;position:relative}html.theme--documenter-dark .navbar-item .icon:only-child,html.theme--documenter-dark .navbar-link .icon:only-child{margin-left:-0.25rem;margin-right:-0.25rem}html.theme--documenter-dark a.navbar-item,html.theme--documenter-dark .navbar-link{cursor:pointer}html.theme--documenter-dark a.navbar-item:focus,html.theme--documenter-dark a.navbar-item:focus-within,html.theme--documenter-dark a.navbar-item:hover,html.theme--documenter-dark a.navbar-item.is-active,html.theme--documenter-dark .navbar-link:focus,html.theme--documenter-dark .navbar-link:focus-within,html.theme--documenter-dark .navbar-link:hover,html.theme--documenter-dark .navbar-link.is-active{background-color:rgba(0,0,0,0);color:#1abc9c}html.theme--documenter-dark .navbar-item{flex-grow:0;flex-shrink:0}html.theme--documenter-dark .navbar-item img{max-height:1.75rem}html.theme--documenter-dark .navbar-item.has-dropdown{padding:0}html.theme--documenter-dark .navbar-item.is-expanded{flex-grow:1;flex-shrink:1}html.theme--documenter-dark .navbar-item.is-tab{border-bottom:1px solid transparent;min-height:4rem;padding-bottom:calc(0.5rem - 1px)}html.theme--documenter-dark .navbar-item.is-tab:focus,html.theme--documenter-dark .navbar-item.is-tab:hover{background-color:rgba(0,0,0,0);border-bottom-color:#1abc9c}html.theme--documenter-dark .navbar-item.is-tab.is-active{background-color:rgba(0,0,0,0);border-bottom-color:#1abc9c;border-bottom-style:solid;border-bottom-width:3px;color:#1abc9c;padding-bottom:calc(0.5rem - 3px)}html.theme--documenter-dark .navbar-content{flex-grow:1;flex-shrink:1}html.theme--documenter-dark .navbar-link:not(.is-arrowless){padding-right:2.5em}html.theme--documenter-dark .navbar-link:not(.is-arrowless)::after{border-color:#fff;margin-top:-0.375em;right:1.125em}html.theme--documenter-dark .navbar-dropdown{font-size:0.875rem;padding-bottom:0.5rem;padding-top:0.5rem}html.theme--documenter-dark .navbar-dropdown .navbar-item{padding-left:1.5rem;padding-right:1.5rem}html.theme--documenter-dark .navbar-divider{background-color:rgba(0,0,0,0.2);border:none;display:none;height:2px;margin:0.5rem 0}@media screen and (max-width: 1055px){html.theme--documenter-dark .navbar>.container{display:block}html.theme--documenter-dark .navbar-brand .navbar-item,html.theme--documenter-dark .navbar-tabs .navbar-item{align-items:center;display:flex}html.theme--documenter-dark .navbar-link::after{display:none}html.theme--documenter-dark .navbar-menu{background-color:#375a7f;box-shadow:0 8px 16px rgba(10,10,10,0.1);padding:0.5rem 0}html.theme--documenter-dark .navbar-menu.is-active{display:block}html.theme--documenter-dark .navbar.is-fixed-bottom-touch,html.theme--documenter-dark .navbar.is-fixed-top-touch{left:0;position:fixed;right:0;z-index:30}html.theme--documenter-dark .navbar.is-fixed-bottom-touch{bottom:0}html.theme--documenter-dark .navbar.is-fixed-bottom-touch.has-shadow{box-shadow:0 -2px 3px rgba(10,10,10,0.1)}html.theme--documenter-dark .navbar.is-fixed-top-touch{top:0}html.theme--documenter-dark .navbar.is-fixed-top .navbar-menu,html.theme--documenter-dark .navbar.is-fixed-top-touch .navbar-menu{-webkit-overflow-scrolling:touch;max-height:calc(100vh - 4rem);overflow:auto}html.theme--documenter-dark html.has-navbar-fixed-top-touch,html.theme--documenter-dark body.has-navbar-fixed-top-touch{padding-top:4rem}html.theme--documenter-dark html.has-navbar-fixed-bottom-touch,html.theme--documenter-dark body.has-navbar-fixed-bottom-touch{padding-bottom:4rem}}@media screen and (min-width: 1056px){html.theme--documenter-dark .navbar,html.theme--documenter-dark .navbar-menu,html.theme--documenter-dark .navbar-start,html.theme--documenter-dark .navbar-end{align-items:stretch;display:flex}html.theme--documenter-dark .navbar{min-height:4rem}html.theme--documenter-dark .navbar.is-spaced{padding:1rem 2rem}html.theme--documenter-dark .navbar.is-spaced .navbar-start,html.theme--documenter-dark .navbar.is-spaced .navbar-end{align-items:center}html.theme--documenter-dark .navbar.is-spaced a.navbar-item,html.theme--documenter-dark .navbar.is-spaced .navbar-link{border-radius:.4em}html.theme--documenter-dark .navbar.is-transparent a.navbar-item:focus,html.theme--documenter-dark .navbar.is-transparent a.navbar-item:hover,html.theme--documenter-dark .navbar.is-transparent a.navbar-item.is-active,html.theme--documenter-dark .navbar.is-transparent .navbar-link:focus,html.theme--documenter-dark .navbar.is-transparent .navbar-link:hover,html.theme--documenter-dark .navbar.is-transparent .navbar-link.is-active{background-color:transparent !important}html.theme--documenter-dark .navbar.is-transparent .navbar-item.has-dropdown.is-active .navbar-link,html.theme--documenter-dark .navbar.is-transparent .navbar-item.has-dropdown.is-hoverable:focus .navbar-link,html.theme--documenter-dark .navbar.is-transparent .navbar-item.has-dropdown.is-hoverable:focus-within .navbar-link,html.theme--documenter-dark .navbar.is-transparent .navbar-item.has-dropdown.is-hoverable:hover .navbar-link{background-color:transparent !important}html.theme--documenter-dark .navbar.is-transparent .navbar-dropdown a.navbar-item:focus,html.theme--documenter-dark .navbar.is-transparent .navbar-dropdown a.navbar-item:hover{background-color:rgba(0,0,0,0);color:#dbdee0}html.theme--documenter-dark .navbar.is-transparent .navbar-dropdown a.navbar-item.is-active{background-color:rgba(0,0,0,0);color:#1abc9c}html.theme--documenter-dark .navbar-burger{display:none}html.theme--documenter-dark .navbar-item,html.theme--documenter-dark .navbar-link{align-items:center;display:flex}html.theme--documenter-dark .navbar-item.has-dropdown{align-items:stretch}html.theme--documenter-dark .navbar-item.has-dropdown-up .navbar-link::after{transform:rotate(135deg) translate(0.25em, -0.25em)}html.theme--documenter-dark .navbar-item.has-dropdown-up .navbar-dropdown{border-bottom:1px solid rgba(0,0,0,0.2);border-radius:8px 8px 0 0;border-top:none;bottom:100%;box-shadow:0 -8px 8px rgba(10,10,10,0.1);top:auto}html.theme--documenter-dark .navbar-item.is-active .navbar-dropdown,html.theme--documenter-dark .navbar-item.is-hoverable:focus .navbar-dropdown,html.theme--documenter-dark .navbar-item.is-hoverable:focus-within .navbar-dropdown,html.theme--documenter-dark .navbar-item.is-hoverable:hover .navbar-dropdown{display:block}.navbar.is-spaced html.theme--documenter-dark .navbar-item.is-active .navbar-dropdown,html.theme--documenter-dark .navbar-item.is-active .navbar-dropdown.is-boxed,.navbar.is-spaced html.theme--documenter-dark .navbar-item.is-hoverable:focus .navbar-dropdown,html.theme--documenter-dark .navbar-item.is-hoverable:focus .navbar-dropdown.is-boxed,.navbar.is-spaced html.theme--documenter-dark .navbar-item.is-hoverable:focus-within .navbar-dropdown,html.theme--documenter-dark .navbar-item.is-hoverable:focus-within .navbar-dropdown.is-boxed,.navbar.is-spaced html.theme--documenter-dark .navbar-item.is-hoverable:hover .navbar-dropdown,html.theme--documenter-dark .navbar-item.is-hoverable:hover .navbar-dropdown.is-boxed{opacity:1;pointer-events:auto;transform:translateY(0)}html.theme--documenter-dark .navbar-menu{flex-grow:1;flex-shrink:0}html.theme--documenter-dark .navbar-start{justify-content:flex-start;margin-right:auto}html.theme--documenter-dark .navbar-end{justify-content:flex-end;margin-left:auto}html.theme--documenter-dark .navbar-dropdown{background-color:#375a7f;border-bottom-left-radius:8px;border-bottom-right-radius:8px;border-top:1px solid rgba(0,0,0,0.2);box-shadow:0 8px 8px rgba(10,10,10,0.1);display:none;font-size:0.875rem;left:0;min-width:100%;position:absolute;top:100%;z-index:20}html.theme--documenter-dark .navbar-dropdown .navbar-item{padding:0.375rem 1rem;white-space:nowrap}html.theme--documenter-dark .navbar-dropdown a.navbar-item{padding-right:3rem}html.theme--documenter-dark .navbar-dropdown a.navbar-item:focus,html.theme--documenter-dark .navbar-dropdown a.navbar-item:hover{background-color:rgba(0,0,0,0);color:#dbdee0}html.theme--documenter-dark .navbar-dropdown a.navbar-item.is-active{background-color:rgba(0,0,0,0);color:#1abc9c}.navbar.is-spaced html.theme--documenter-dark .navbar-dropdown,html.theme--documenter-dark .navbar-dropdown.is-boxed{border-radius:8px;border-top:none;box-shadow:0 8px 8px rgba(10,10,10,0.1), 0 0 0 1px rgba(10,10,10,0.1);display:block;opacity:0;pointer-events:none;top:calc(100% + (-4px));transform:translateY(-5px);transition-duration:86ms;transition-property:opacity, transform}html.theme--documenter-dark .navbar-dropdown.is-right{left:auto;right:0}html.theme--documenter-dark .navbar-divider{display:block}html.theme--documenter-dark .navbar>.container .navbar-brand,html.theme--documenter-dark .container>.navbar .navbar-brand{margin-left:-.75rem}html.theme--documenter-dark .navbar>.container .navbar-menu,html.theme--documenter-dark .container>.navbar .navbar-menu{margin-right:-.75rem}html.theme--documenter-dark .navbar.is-fixed-bottom-desktop,html.theme--documenter-dark .navbar.is-fixed-top-desktop{left:0;position:fixed;right:0;z-index:30}html.theme--documenter-dark .navbar.is-fixed-bottom-desktop{bottom:0}html.theme--documenter-dark .navbar.is-fixed-bottom-desktop.has-shadow{box-shadow:0 -2px 3px rgba(10,10,10,0.1)}html.theme--documenter-dark .navbar.is-fixed-top-desktop{top:0}html.theme--documenter-dark html.has-navbar-fixed-top-desktop,html.theme--documenter-dark body.has-navbar-fixed-top-desktop{padding-top:4rem}html.theme--documenter-dark html.has-navbar-fixed-bottom-desktop,html.theme--documenter-dark body.has-navbar-fixed-bottom-desktop{padding-bottom:4rem}html.theme--documenter-dark html.has-spaced-navbar-fixed-top,html.theme--documenter-dark body.has-spaced-navbar-fixed-top{padding-top:6rem}html.theme--documenter-dark html.has-spaced-navbar-fixed-bottom,html.theme--documenter-dark body.has-spaced-navbar-fixed-bottom{padding-bottom:6rem}html.theme--documenter-dark a.navbar-item.is-active,html.theme--documenter-dark .navbar-link.is-active{color:#1abc9c}html.theme--documenter-dark a.navbar-item.is-active:not(:focus):not(:hover),html.theme--documenter-dark .navbar-link.is-active:not(:focus):not(:hover){background-color:rgba(0,0,0,0)}html.theme--documenter-dark .navbar-item.has-dropdown:focus .navbar-link,html.theme--documenter-dark .navbar-item.has-dropdown:hover .navbar-link,html.theme--documenter-dark .navbar-item.has-dropdown.is-active .navbar-link{background-color:rgba(0,0,0,0)}}html.theme--documenter-dark .hero.is-fullheight-with-navbar{min-height:calc(100vh - 4rem)}html.theme--documenter-dark .pagination{font-size:1rem;margin:-.25rem}html.theme--documenter-dark .pagination.is-small,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.pagination{font-size:.75rem}html.theme--documenter-dark .pagination.is-medium{font-size:1.25rem}html.theme--documenter-dark .pagination.is-large{font-size:1.5rem}html.theme--documenter-dark .pagination.is-rounded .pagination-previous,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.pagination .pagination-previous,html.theme--documenter-dark .pagination.is-rounded .pagination-next,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.pagination .pagination-next{padding-left:1em;padding-right:1em;border-radius:9999px}html.theme--documenter-dark .pagination.is-rounded .pagination-link,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.pagination .pagination-link{border-radius:9999px}html.theme--documenter-dark .pagination,html.theme--documenter-dark .pagination-list{align-items:center;display:flex;justify-content:center;text-align:center}html.theme--documenter-dark .pagination-previous,html.theme--documenter-dark .pagination-next,html.theme--documenter-dark .pagination-link,html.theme--documenter-dark .pagination-ellipsis{font-size:1em;justify-content:center;margin:.25rem;padding-left:.5em;padding-right:.5em;text-align:center}html.theme--documenter-dark .pagination-previous,html.theme--documenter-dark .pagination-next,html.theme--documenter-dark .pagination-link{border-color:#5e6d6f;color:#1abc9c;min-width:2.5em}html.theme--documenter-dark .pagination-previous:hover,html.theme--documenter-dark .pagination-next:hover,html.theme--documenter-dark .pagination-link:hover{border-color:#8c9b9d;color:#1dd2af}html.theme--documenter-dark .pagination-previous:focus,html.theme--documenter-dark .pagination-next:focus,html.theme--documenter-dark .pagination-link:focus{border-color:#8c9b9d}html.theme--documenter-dark .pagination-previous:active,html.theme--documenter-dark .pagination-next:active,html.theme--documenter-dark .pagination-link:active{box-shadow:inset 0 1px 2px rgba(10,10,10,0.2)}html.theme--documenter-dark .pagination-previous[disabled],html.theme--documenter-dark .pagination-previous.is-disabled,html.theme--documenter-dark .pagination-next[disabled],html.theme--documenter-dark .pagination-next.is-disabled,html.theme--documenter-dark .pagination-link[disabled],html.theme--documenter-dark .pagination-link.is-disabled{background-color:#5e6d6f;border-color:#5e6d6f;box-shadow:none;color:#fff;opacity:0.5}html.theme--documenter-dark .pagination-previous,html.theme--documenter-dark .pagination-next{padding-left:.75em;padding-right:.75em;white-space:nowrap}html.theme--documenter-dark .pagination-link.is-current{background-color:#1abc9c;border-color:#1abc9c;color:#fff}html.theme--documenter-dark .pagination-ellipsis{color:#8c9b9d;pointer-events:none}html.theme--documenter-dark .pagination-list{flex-wrap:wrap}html.theme--documenter-dark .pagination-list li{list-style:none}@media screen and (max-width: 768px){html.theme--documenter-dark .pagination{flex-wrap:wrap}html.theme--documenter-dark .pagination-previous,html.theme--documenter-dark .pagination-next{flex-grow:1;flex-shrink:1}html.theme--documenter-dark .pagination-list li{flex-grow:1;flex-shrink:1}}@media screen and (min-width: 769px),print{html.theme--documenter-dark .pagination-list{flex-grow:1;flex-shrink:1;justify-content:flex-start;order:1}html.theme--documenter-dark .pagination-previous,html.theme--documenter-dark .pagination-next,html.theme--documenter-dark .pagination-link,html.theme--documenter-dark .pagination-ellipsis{margin-bottom:0;margin-top:0}html.theme--documenter-dark .pagination-previous{order:2}html.theme--documenter-dark .pagination-next{order:3}html.theme--documenter-dark .pagination{justify-content:space-between;margin-bottom:0;margin-top:0}html.theme--documenter-dark .pagination.is-centered .pagination-previous{order:1}html.theme--documenter-dark .pagination.is-centered .pagination-list{justify-content:center;order:2}html.theme--documenter-dark .pagination.is-centered .pagination-next{order:3}html.theme--documenter-dark .pagination.is-right .pagination-previous{order:1}html.theme--documenter-dark .pagination.is-right .pagination-next{order:2}html.theme--documenter-dark .pagination.is-right .pagination-list{justify-content:flex-end;order:3}}html.theme--documenter-dark .panel{border-radius:8px;box-shadow:#171717;font-size:1rem}html.theme--documenter-dark .panel:not(:last-child){margin-bottom:1.5rem}html.theme--documenter-dark .panel.is-white .panel-heading{background-color:#fff;color:#0a0a0a}html.theme--documenter-dark .panel.is-white .panel-tabs a.is-active{border-bottom-color:#fff}html.theme--documenter-dark .panel.is-white .panel-block.is-active .panel-icon{color:#fff}html.theme--documenter-dark .panel.is-black .panel-heading{background-color:#0a0a0a;color:#fff}html.theme--documenter-dark .panel.is-black .panel-tabs a.is-active{border-bottom-color:#0a0a0a}html.theme--documenter-dark .panel.is-black .panel-block.is-active .panel-icon{color:#0a0a0a}html.theme--documenter-dark .panel.is-light .panel-heading{background-color:#ecf0f1;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .panel.is-light .panel-tabs a.is-active{border-bottom-color:#ecf0f1}html.theme--documenter-dark .panel.is-light .panel-block.is-active .panel-icon{color:#ecf0f1}html.theme--documenter-dark .panel.is-dark .panel-heading,html.theme--documenter-dark .content kbd.panel .panel-heading{background-color:#282f2f;color:#fff}html.theme--documenter-dark .panel.is-dark .panel-tabs a.is-active,html.theme--documenter-dark .content kbd.panel .panel-tabs a.is-active{border-bottom-color:#282f2f}html.theme--documenter-dark .panel.is-dark .panel-block.is-active .panel-icon,html.theme--documenter-dark .content kbd.panel .panel-block.is-active .panel-icon{color:#282f2f}html.theme--documenter-dark .panel.is-primary .panel-heading,html.theme--documenter-dark .docstring>section>a.panel.docs-sourcelink .panel-heading{background-color:#375a7f;color:#fff}html.theme--documenter-dark .panel.is-primary .panel-tabs a.is-active,html.theme--documenter-dark .docstring>section>a.panel.docs-sourcelink .panel-tabs a.is-active{border-bottom-color:#375a7f}html.theme--documenter-dark .panel.is-primary .panel-block.is-active .panel-icon,html.theme--documenter-dark .docstring>section>a.panel.docs-sourcelink .panel-block.is-active .panel-icon{color:#375a7f}html.theme--documenter-dark .panel.is-link .panel-heading{background-color:#1abc9c;color:#fff}html.theme--documenter-dark .panel.is-link .panel-tabs a.is-active{border-bottom-color:#1abc9c}html.theme--documenter-dark .panel.is-link .panel-block.is-active .panel-icon{color:#1abc9c}html.theme--documenter-dark .panel.is-info .panel-heading{background-color:#024c7d;color:#fff}html.theme--documenter-dark .panel.is-info .panel-tabs a.is-active{border-bottom-color:#024c7d}html.theme--documenter-dark .panel.is-info .panel-block.is-active .panel-icon{color:#024c7d}html.theme--documenter-dark .panel.is-success .panel-heading{background-color:#008438;color:#fff}html.theme--documenter-dark .panel.is-success .panel-tabs a.is-active{border-bottom-color:#008438}html.theme--documenter-dark .panel.is-success .panel-block.is-active .panel-icon{color:#008438}html.theme--documenter-dark .panel.is-warning .panel-heading{background-color:#ad8100;color:#fff}html.theme--documenter-dark .panel.is-warning .panel-tabs a.is-active{border-bottom-color:#ad8100}html.theme--documenter-dark .panel.is-warning .panel-block.is-active .panel-icon{color:#ad8100}html.theme--documenter-dark .panel.is-danger .panel-heading{background-color:#9e1b0d;color:#fff}html.theme--documenter-dark .panel.is-danger .panel-tabs a.is-active{border-bottom-color:#9e1b0d}html.theme--documenter-dark .panel.is-danger .panel-block.is-active .panel-icon{color:#9e1b0d}html.theme--documenter-dark .panel-tabs:not(:last-child),html.theme--documenter-dark .panel-block:not(:last-child){border-bottom:1px solid #ededed}html.theme--documenter-dark .panel-heading{background-color:#343c3d;border-radius:8px 8px 0 0;color:#f2f2f2;font-size:1.25em;font-weight:700;line-height:1.25;padding:0.75em 1em}html.theme--documenter-dark .panel-tabs{align-items:flex-end;display:flex;font-size:.875em;justify-content:center}html.theme--documenter-dark .panel-tabs a{border-bottom:1px solid #5e6d6f;margin-bottom:-1px;padding:0.5em}html.theme--documenter-dark .panel-tabs a.is-active{border-bottom-color:#343c3d;color:#17a689}html.theme--documenter-dark .panel-list a{color:#fff}html.theme--documenter-dark .panel-list a:hover{color:#1abc9c}html.theme--documenter-dark .panel-block{align-items:center;color:#f2f2f2;display:flex;justify-content:flex-start;padding:0.5em 0.75em}html.theme--documenter-dark .panel-block input[type="checkbox"]{margin-right:.75em}html.theme--documenter-dark .panel-block>.control{flex-grow:1;flex-shrink:1;width:100%}html.theme--documenter-dark .panel-block.is-wrapped{flex-wrap:wrap}html.theme--documenter-dark .panel-block.is-active{border-left-color:#1abc9c;color:#17a689}html.theme--documenter-dark .panel-block.is-active .panel-icon{color:#1abc9c}html.theme--documenter-dark .panel-block:last-child{border-bottom-left-radius:8px;border-bottom-right-radius:8px}html.theme--documenter-dark a.panel-block,html.theme--documenter-dark label.panel-block{cursor:pointer}html.theme--documenter-dark a.panel-block:hover,html.theme--documenter-dark label.panel-block:hover{background-color:#282f2f}html.theme--documenter-dark .panel-icon{display:inline-block;font-size:14px;height:1em;line-height:1em;text-align:center;vertical-align:top;width:1em;color:#fff;margin-right:.75em}html.theme--documenter-dark .panel-icon .fa{font-size:inherit;line-height:inherit}html.theme--documenter-dark .tabs{-webkit-overflow-scrolling:touch;align-items:stretch;display:flex;font-size:1rem;justify-content:space-between;overflow:hidden;overflow-x:auto;white-space:nowrap}html.theme--documenter-dark .tabs a{align-items:center;border-bottom-color:#5e6d6f;border-bottom-style:solid;border-bottom-width:1px;color:#fff;display:flex;justify-content:center;margin-bottom:-1px;padding:0.5em 1em;vertical-align:top}html.theme--documenter-dark .tabs a:hover{border-bottom-color:#f2f2f2;color:#f2f2f2}html.theme--documenter-dark .tabs li{display:block}html.theme--documenter-dark .tabs li.is-active a{border-bottom-color:#1abc9c;color:#1abc9c}html.theme--documenter-dark .tabs ul{align-items:center;border-bottom-color:#5e6d6f;border-bottom-style:solid;border-bottom-width:1px;display:flex;flex-grow:1;flex-shrink:0;justify-content:flex-start}html.theme--documenter-dark .tabs ul.is-left{padding-right:0.75em}html.theme--documenter-dark .tabs ul.is-center{flex:none;justify-content:center;padding-left:0.75em;padding-right:0.75em}html.theme--documenter-dark .tabs ul.is-right{justify-content:flex-end;padding-left:0.75em}html.theme--documenter-dark .tabs .icon:first-child{margin-right:.5em}html.theme--documenter-dark .tabs .icon:last-child{margin-left:.5em}html.theme--documenter-dark .tabs.is-centered ul{justify-content:center}html.theme--documenter-dark .tabs.is-right ul{justify-content:flex-end}html.theme--documenter-dark .tabs.is-boxed a{border:1px solid transparent;border-radius:.4em .4em 0 0}html.theme--documenter-dark .tabs.is-boxed a:hover{background-color:#282f2f;border-bottom-color:#5e6d6f}html.theme--documenter-dark .tabs.is-boxed li.is-active a{background-color:#fff;border-color:#5e6d6f;border-bottom-color:rgba(0,0,0,0) !important}html.theme--documenter-dark .tabs.is-fullwidth li{flex-grow:1;flex-shrink:0}html.theme--documenter-dark .tabs.is-toggle a{border-color:#5e6d6f;border-style:solid;border-width:1px;margin-bottom:0;position:relative}html.theme--documenter-dark .tabs.is-toggle a:hover{background-color:#282f2f;border-color:#8c9b9d;z-index:2}html.theme--documenter-dark .tabs.is-toggle li+li{margin-left:-1px}html.theme--documenter-dark .tabs.is-toggle li:first-child a{border-top-left-radius:.4em;border-bottom-left-radius:.4em}html.theme--documenter-dark .tabs.is-toggle li:last-child a{border-top-right-radius:.4em;border-bottom-right-radius:.4em}html.theme--documenter-dark .tabs.is-toggle li.is-active a{background-color:#1abc9c;border-color:#1abc9c;color:#fff;z-index:1}html.theme--documenter-dark .tabs.is-toggle ul{border-bottom:none}html.theme--documenter-dark .tabs.is-toggle.is-toggle-rounded li:first-child a{border-bottom-left-radius:9999px;border-top-left-radius:9999px;padding-left:1.25em}html.theme--documenter-dark .tabs.is-toggle.is-toggle-rounded li:last-child a{border-bottom-right-radius:9999px;border-top-right-radius:9999px;padding-right:1.25em}html.theme--documenter-dark .tabs.is-small,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.tabs{font-size:.75rem}html.theme--documenter-dark .tabs.is-medium{font-size:1.25rem}html.theme--documenter-dark .tabs.is-large{font-size:1.5rem}html.theme--documenter-dark .column{display:block;flex-basis:0;flex-grow:1;flex-shrink:1;padding:.75rem}.columns.is-mobile>html.theme--documenter-dark .column.is-narrow{flex:none;width:unset}.columns.is-mobile>html.theme--documenter-dark .column.is-full{flex:none;width:100%}.columns.is-mobile>html.theme--documenter-dark .column.is-three-quarters{flex:none;width:75%}.columns.is-mobile>html.theme--documenter-dark .column.is-two-thirds{flex:none;width:66.6666%}.columns.is-mobile>html.theme--documenter-dark .column.is-half{flex:none;width:50%}.columns.is-mobile>html.theme--documenter-dark .column.is-one-third{flex:none;width:33.3333%}.columns.is-mobile>html.theme--documenter-dark .column.is-one-quarter{flex:none;width:25%}.columns.is-mobile>html.theme--documenter-dark .column.is-one-fifth{flex:none;width:20%}.columns.is-mobile>html.theme--documenter-dark .column.is-two-fifths{flex:none;width:40%}.columns.is-mobile>html.theme--documenter-dark .column.is-three-fifths{flex:none;width:60%}.columns.is-mobile>html.theme--documenter-dark .column.is-four-fifths{flex:none;width:80%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-three-quarters{margin-left:75%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-two-thirds{margin-left:66.6666%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-half{margin-left:50%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-one-third{margin-left:33.3333%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-one-quarter{margin-left:25%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-one-fifth{margin-left:20%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-two-fifths{margin-left:40%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-three-fifths{margin-left:60%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-four-fifths{margin-left:80%}.columns.is-mobile>html.theme--documenter-dark .column.is-0{flex:none;width:0%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-0{margin-left:0%}.columns.is-mobile>html.theme--documenter-dark .column.is-1{flex:none;width:8.33333337%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-1{margin-left:8.33333337%}.columns.is-mobile>html.theme--documenter-dark .column.is-2{flex:none;width:16.66666674%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-2{margin-left:16.66666674%}.columns.is-mobile>html.theme--documenter-dark .column.is-3{flex:none;width:25%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-3{margin-left:25%}.columns.is-mobile>html.theme--documenter-dark .column.is-4{flex:none;width:33.33333337%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-4{margin-left:33.33333337%}.columns.is-mobile>html.theme--documenter-dark .column.is-5{flex:none;width:41.66666674%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-5{margin-left:41.66666674%}.columns.is-mobile>html.theme--documenter-dark .column.is-6{flex:none;width:50%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-6{margin-left:50%}.columns.is-mobile>html.theme--documenter-dark .column.is-7{flex:none;width:58.33333337%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-7{margin-left:58.33333337%}.columns.is-mobile>html.theme--documenter-dark .column.is-8{flex:none;width:66.66666674%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-8{margin-left:66.66666674%}.columns.is-mobile>html.theme--documenter-dark .column.is-9{flex:none;width:75%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-9{margin-left:75%}.columns.is-mobile>html.theme--documenter-dark .column.is-10{flex:none;width:83.33333337%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-10{margin-left:83.33333337%}.columns.is-mobile>html.theme--documenter-dark .column.is-11{flex:none;width:91.66666674%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-11{margin-left:91.66666674%}.columns.is-mobile>html.theme--documenter-dark .column.is-12{flex:none;width:100%}.columns.is-mobile>html.theme--documenter-dark .column.is-offset-12{margin-left:100%}@media screen and (max-width: 768px){html.theme--documenter-dark .column.is-narrow-mobile{flex:none;width:unset}html.theme--documenter-dark .column.is-full-mobile{flex:none;width:100%}html.theme--documenter-dark .column.is-three-quarters-mobile{flex:none;width:75%}html.theme--documenter-dark .column.is-two-thirds-mobile{flex:none;width:66.6666%}html.theme--documenter-dark .column.is-half-mobile{flex:none;width:50%}html.theme--documenter-dark .column.is-one-third-mobile{flex:none;width:33.3333%}html.theme--documenter-dark .column.is-one-quarter-mobile{flex:none;width:25%}html.theme--documenter-dark .column.is-one-fifth-mobile{flex:none;width:20%}html.theme--documenter-dark .column.is-two-fifths-mobile{flex:none;width:40%}html.theme--documenter-dark .column.is-three-fifths-mobile{flex:none;width:60%}html.theme--documenter-dark .column.is-four-fifths-mobile{flex:none;width:80%}html.theme--documenter-dark .column.is-offset-three-quarters-mobile{margin-left:75%}html.theme--documenter-dark .column.is-offset-two-thirds-mobile{margin-left:66.6666%}html.theme--documenter-dark .column.is-offset-half-mobile{margin-left:50%}html.theme--documenter-dark .column.is-offset-one-third-mobile{margin-left:33.3333%}html.theme--documenter-dark .column.is-offset-one-quarter-mobile{margin-left:25%}html.theme--documenter-dark .column.is-offset-one-fifth-mobile{margin-left:20%}html.theme--documenter-dark .column.is-offset-two-fifths-mobile{margin-left:40%}html.theme--documenter-dark .column.is-offset-three-fifths-mobile{margin-left:60%}html.theme--documenter-dark .column.is-offset-four-fifths-mobile{margin-left:80%}html.theme--documenter-dark .column.is-0-mobile{flex:none;width:0%}html.theme--documenter-dark .column.is-offset-0-mobile{margin-left:0%}html.theme--documenter-dark .column.is-1-mobile{flex:none;width:8.33333337%}html.theme--documenter-dark .column.is-offset-1-mobile{margin-left:8.33333337%}html.theme--documenter-dark .column.is-2-mobile{flex:none;width:16.66666674%}html.theme--documenter-dark .column.is-offset-2-mobile{margin-left:16.66666674%}html.theme--documenter-dark .column.is-3-mobile{flex:none;width:25%}html.theme--documenter-dark .column.is-offset-3-mobile{margin-left:25%}html.theme--documenter-dark .column.is-4-mobile{flex:none;width:33.33333337%}html.theme--documenter-dark .column.is-offset-4-mobile{margin-left:33.33333337%}html.theme--documenter-dark .column.is-5-mobile{flex:none;width:41.66666674%}html.theme--documenter-dark .column.is-offset-5-mobile{margin-left:41.66666674%}html.theme--documenter-dark .column.is-6-mobile{flex:none;width:50%}html.theme--documenter-dark .column.is-offset-6-mobile{margin-left:50%}html.theme--documenter-dark .column.is-7-mobile{flex:none;width:58.33333337%}html.theme--documenter-dark .column.is-offset-7-mobile{margin-left:58.33333337%}html.theme--documenter-dark .column.is-8-mobile{flex:none;width:66.66666674%}html.theme--documenter-dark .column.is-offset-8-mobile{margin-left:66.66666674%}html.theme--documenter-dark .column.is-9-mobile{flex:none;width:75%}html.theme--documenter-dark .column.is-offset-9-mobile{margin-left:75%}html.theme--documenter-dark .column.is-10-mobile{flex:none;width:83.33333337%}html.theme--documenter-dark .column.is-offset-10-mobile{margin-left:83.33333337%}html.theme--documenter-dark .column.is-11-mobile{flex:none;width:91.66666674%}html.theme--documenter-dark .column.is-offset-11-mobile{margin-left:91.66666674%}html.theme--documenter-dark .column.is-12-mobile{flex:none;width:100%}html.theme--documenter-dark .column.is-offset-12-mobile{margin-left:100%}}@media screen and (min-width: 769px),print{html.theme--documenter-dark .column.is-narrow,html.theme--documenter-dark .column.is-narrow-tablet{flex:none;width:unset}html.theme--documenter-dark .column.is-full,html.theme--documenter-dark .column.is-full-tablet{flex:none;width:100%}html.theme--documenter-dark .column.is-three-quarters,html.theme--documenter-dark .column.is-three-quarters-tablet{flex:none;width:75%}html.theme--documenter-dark .column.is-two-thirds,html.theme--documenter-dark .column.is-two-thirds-tablet{flex:none;width:66.6666%}html.theme--documenter-dark .column.is-half,html.theme--documenter-dark .column.is-half-tablet{flex:none;width:50%}html.theme--documenter-dark .column.is-one-third,html.theme--documenter-dark .column.is-one-third-tablet{flex:none;width:33.3333%}html.theme--documenter-dark .column.is-one-quarter,html.theme--documenter-dark .column.is-one-quarter-tablet{flex:none;width:25%}html.theme--documenter-dark .column.is-one-fifth,html.theme--documenter-dark .column.is-one-fifth-tablet{flex:none;width:20%}html.theme--documenter-dark .column.is-two-fifths,html.theme--documenter-dark .column.is-two-fifths-tablet{flex:none;width:40%}html.theme--documenter-dark .column.is-three-fifths,html.theme--documenter-dark .column.is-three-fifths-tablet{flex:none;width:60%}html.theme--documenter-dark .column.is-four-fifths,html.theme--documenter-dark .column.is-four-fifths-tablet{flex:none;width:80%}html.theme--documenter-dark .column.is-offset-three-quarters,html.theme--documenter-dark .column.is-offset-three-quarters-tablet{margin-left:75%}html.theme--documenter-dark .column.is-offset-two-thirds,html.theme--documenter-dark .column.is-offset-two-thirds-tablet{margin-left:66.6666%}html.theme--documenter-dark .column.is-offset-half,html.theme--documenter-dark .column.is-offset-half-tablet{margin-left:50%}html.theme--documenter-dark .column.is-offset-one-third,html.theme--documenter-dark .column.is-offset-one-third-tablet{margin-left:33.3333%}html.theme--documenter-dark .column.is-offset-one-quarter,html.theme--documenter-dark .column.is-offset-one-quarter-tablet{margin-left:25%}html.theme--documenter-dark .column.is-offset-one-fifth,html.theme--documenter-dark .column.is-offset-one-fifth-tablet{margin-left:20%}html.theme--documenter-dark .column.is-offset-two-fifths,html.theme--documenter-dark .column.is-offset-two-fifths-tablet{margin-left:40%}html.theme--documenter-dark .column.is-offset-three-fifths,html.theme--documenter-dark .column.is-offset-three-fifths-tablet{margin-left:60%}html.theme--documenter-dark .column.is-offset-four-fifths,html.theme--documenter-dark .column.is-offset-four-fifths-tablet{margin-left:80%}html.theme--documenter-dark .column.is-0,html.theme--documenter-dark .column.is-0-tablet{flex:none;width:0%}html.theme--documenter-dark .column.is-offset-0,html.theme--documenter-dark .column.is-offset-0-tablet{margin-left:0%}html.theme--documenter-dark .column.is-1,html.theme--documenter-dark .column.is-1-tablet{flex:none;width:8.33333337%}html.theme--documenter-dark .column.is-offset-1,html.theme--documenter-dark .column.is-offset-1-tablet{margin-left:8.33333337%}html.theme--documenter-dark .column.is-2,html.theme--documenter-dark .column.is-2-tablet{flex:none;width:16.66666674%}html.theme--documenter-dark .column.is-offset-2,html.theme--documenter-dark .column.is-offset-2-tablet{margin-left:16.66666674%}html.theme--documenter-dark .column.is-3,html.theme--documenter-dark .column.is-3-tablet{flex:none;width:25%}html.theme--documenter-dark .column.is-offset-3,html.theme--documenter-dark .column.is-offset-3-tablet{margin-left:25%}html.theme--documenter-dark .column.is-4,html.theme--documenter-dark .column.is-4-tablet{flex:none;width:33.33333337%}html.theme--documenter-dark .column.is-offset-4,html.theme--documenter-dark .column.is-offset-4-tablet{margin-left:33.33333337%}html.theme--documenter-dark .column.is-5,html.theme--documenter-dark .column.is-5-tablet{flex:none;width:41.66666674%}html.theme--documenter-dark .column.is-offset-5,html.theme--documenter-dark .column.is-offset-5-tablet{margin-left:41.66666674%}html.theme--documenter-dark .column.is-6,html.theme--documenter-dark .column.is-6-tablet{flex:none;width:50%}html.theme--documenter-dark .column.is-offset-6,html.theme--documenter-dark .column.is-offset-6-tablet{margin-left:50%}html.theme--documenter-dark .column.is-7,html.theme--documenter-dark .column.is-7-tablet{flex:none;width:58.33333337%}html.theme--documenter-dark .column.is-offset-7,html.theme--documenter-dark .column.is-offset-7-tablet{margin-left:58.33333337%}html.theme--documenter-dark .column.is-8,html.theme--documenter-dark .column.is-8-tablet{flex:none;width:66.66666674%}html.theme--documenter-dark .column.is-offset-8,html.theme--documenter-dark .column.is-offset-8-tablet{margin-left:66.66666674%}html.theme--documenter-dark .column.is-9,html.theme--documenter-dark .column.is-9-tablet{flex:none;width:75%}html.theme--documenter-dark .column.is-offset-9,html.theme--documenter-dark .column.is-offset-9-tablet{margin-left:75%}html.theme--documenter-dark .column.is-10,html.theme--documenter-dark .column.is-10-tablet{flex:none;width:83.33333337%}html.theme--documenter-dark .column.is-offset-10,html.theme--documenter-dark .column.is-offset-10-tablet{margin-left:83.33333337%}html.theme--documenter-dark .column.is-11,html.theme--documenter-dark .column.is-11-tablet{flex:none;width:91.66666674%}html.theme--documenter-dark .column.is-offset-11,html.theme--documenter-dark .column.is-offset-11-tablet{margin-left:91.66666674%}html.theme--documenter-dark .column.is-12,html.theme--documenter-dark .column.is-12-tablet{flex:none;width:100%}html.theme--documenter-dark .column.is-offset-12,html.theme--documenter-dark .column.is-offset-12-tablet{margin-left:100%}}@media screen and (max-width: 1055px){html.theme--documenter-dark .column.is-narrow-touch{flex:none;width:unset}html.theme--documenter-dark .column.is-full-touch{flex:none;width:100%}html.theme--documenter-dark .column.is-three-quarters-touch{flex:none;width:75%}html.theme--documenter-dark .column.is-two-thirds-touch{flex:none;width:66.6666%}html.theme--documenter-dark .column.is-half-touch{flex:none;width:50%}html.theme--documenter-dark .column.is-one-third-touch{flex:none;width:33.3333%}html.theme--documenter-dark .column.is-one-quarter-touch{flex:none;width:25%}html.theme--documenter-dark .column.is-one-fifth-touch{flex:none;width:20%}html.theme--documenter-dark .column.is-two-fifths-touch{flex:none;width:40%}html.theme--documenter-dark .column.is-three-fifths-touch{flex:none;width:60%}html.theme--documenter-dark .column.is-four-fifths-touch{flex:none;width:80%}html.theme--documenter-dark .column.is-offset-three-quarters-touch{margin-left:75%}html.theme--documenter-dark .column.is-offset-two-thirds-touch{margin-left:66.6666%}html.theme--documenter-dark .column.is-offset-half-touch{margin-left:50%}html.theme--documenter-dark .column.is-offset-one-third-touch{margin-left:33.3333%}html.theme--documenter-dark .column.is-offset-one-quarter-touch{margin-left:25%}html.theme--documenter-dark .column.is-offset-one-fifth-touch{margin-left:20%}html.theme--documenter-dark .column.is-offset-two-fifths-touch{margin-left:40%}html.theme--documenter-dark .column.is-offset-three-fifths-touch{margin-left:60%}html.theme--documenter-dark .column.is-offset-four-fifths-touch{margin-left:80%}html.theme--documenter-dark .column.is-0-touch{flex:none;width:0%}html.theme--documenter-dark .column.is-offset-0-touch{margin-left:0%}html.theme--documenter-dark .column.is-1-touch{flex:none;width:8.33333337%}html.theme--documenter-dark .column.is-offset-1-touch{margin-left:8.33333337%}html.theme--documenter-dark .column.is-2-touch{flex:none;width:16.66666674%}html.theme--documenter-dark .column.is-offset-2-touch{margin-left:16.66666674%}html.theme--documenter-dark .column.is-3-touch{flex:none;width:25%}html.theme--documenter-dark .column.is-offset-3-touch{margin-left:25%}html.theme--documenter-dark .column.is-4-touch{flex:none;width:33.33333337%}html.theme--documenter-dark .column.is-offset-4-touch{margin-left:33.33333337%}html.theme--documenter-dark .column.is-5-touch{flex:none;width:41.66666674%}html.theme--documenter-dark .column.is-offset-5-touch{margin-left:41.66666674%}html.theme--documenter-dark .column.is-6-touch{flex:none;width:50%}html.theme--documenter-dark .column.is-offset-6-touch{margin-left:50%}html.theme--documenter-dark .column.is-7-touch{flex:none;width:58.33333337%}html.theme--documenter-dark .column.is-offset-7-touch{margin-left:58.33333337%}html.theme--documenter-dark .column.is-8-touch{flex:none;width:66.66666674%}html.theme--documenter-dark .column.is-offset-8-touch{margin-left:66.66666674%}html.theme--documenter-dark .column.is-9-touch{flex:none;width:75%}html.theme--documenter-dark .column.is-offset-9-touch{margin-left:75%}html.theme--documenter-dark .column.is-10-touch{flex:none;width:83.33333337%}html.theme--documenter-dark .column.is-offset-10-touch{margin-left:83.33333337%}html.theme--documenter-dark .column.is-11-touch{flex:none;width:91.66666674%}html.theme--documenter-dark .column.is-offset-11-touch{margin-left:91.66666674%}html.theme--documenter-dark .column.is-12-touch{flex:none;width:100%}html.theme--documenter-dark .column.is-offset-12-touch{margin-left:100%}}@media screen and (min-width: 1056px){html.theme--documenter-dark .column.is-narrow-desktop{flex:none;width:unset}html.theme--documenter-dark .column.is-full-desktop{flex:none;width:100%}html.theme--documenter-dark .column.is-three-quarters-desktop{flex:none;width:75%}html.theme--documenter-dark .column.is-two-thirds-desktop{flex:none;width:66.6666%}html.theme--documenter-dark .column.is-half-desktop{flex:none;width:50%}html.theme--documenter-dark .column.is-one-third-desktop{flex:none;width:33.3333%}html.theme--documenter-dark .column.is-one-quarter-desktop{flex:none;width:25%}html.theme--documenter-dark .column.is-one-fifth-desktop{flex:none;width:20%}html.theme--documenter-dark .column.is-two-fifths-desktop{flex:none;width:40%}html.theme--documenter-dark .column.is-three-fifths-desktop{flex:none;width:60%}html.theme--documenter-dark .column.is-four-fifths-desktop{flex:none;width:80%}html.theme--documenter-dark .column.is-offset-three-quarters-desktop{margin-left:75%}html.theme--documenter-dark .column.is-offset-two-thirds-desktop{margin-left:66.6666%}html.theme--documenter-dark .column.is-offset-half-desktop{margin-left:50%}html.theme--documenter-dark .column.is-offset-one-third-desktop{margin-left:33.3333%}html.theme--documenter-dark .column.is-offset-one-quarter-desktop{margin-left:25%}html.theme--documenter-dark .column.is-offset-one-fifth-desktop{margin-left:20%}html.theme--documenter-dark .column.is-offset-two-fifths-desktop{margin-left:40%}html.theme--documenter-dark .column.is-offset-three-fifths-desktop{margin-left:60%}html.theme--documenter-dark .column.is-offset-four-fifths-desktop{margin-left:80%}html.theme--documenter-dark .column.is-0-desktop{flex:none;width:0%}html.theme--documenter-dark .column.is-offset-0-desktop{margin-left:0%}html.theme--documenter-dark .column.is-1-desktop{flex:none;width:8.33333337%}html.theme--documenter-dark .column.is-offset-1-desktop{margin-left:8.33333337%}html.theme--documenter-dark .column.is-2-desktop{flex:none;width:16.66666674%}html.theme--documenter-dark .column.is-offset-2-desktop{margin-left:16.66666674%}html.theme--documenter-dark .column.is-3-desktop{flex:none;width:25%}html.theme--documenter-dark .column.is-offset-3-desktop{margin-left:25%}html.theme--documenter-dark .column.is-4-desktop{flex:none;width:33.33333337%}html.theme--documenter-dark .column.is-offset-4-desktop{margin-left:33.33333337%}html.theme--documenter-dark .column.is-5-desktop{flex:none;width:41.66666674%}html.theme--documenter-dark .column.is-offset-5-desktop{margin-left:41.66666674%}html.theme--documenter-dark .column.is-6-desktop{flex:none;width:50%}html.theme--documenter-dark .column.is-offset-6-desktop{margin-left:50%}html.theme--documenter-dark .column.is-7-desktop{flex:none;width:58.33333337%}html.theme--documenter-dark .column.is-offset-7-desktop{margin-left:58.33333337%}html.theme--documenter-dark .column.is-8-desktop{flex:none;width:66.66666674%}html.theme--documenter-dark .column.is-offset-8-desktop{margin-left:66.66666674%}html.theme--documenter-dark .column.is-9-desktop{flex:none;width:75%}html.theme--documenter-dark .column.is-offset-9-desktop{margin-left:75%}html.theme--documenter-dark .column.is-10-desktop{flex:none;width:83.33333337%}html.theme--documenter-dark .column.is-offset-10-desktop{margin-left:83.33333337%}html.theme--documenter-dark .column.is-11-desktop{flex:none;width:91.66666674%}html.theme--documenter-dark .column.is-offset-11-desktop{margin-left:91.66666674%}html.theme--documenter-dark .column.is-12-desktop{flex:none;width:100%}html.theme--documenter-dark .column.is-offset-12-desktop{margin-left:100%}}@media screen and (min-width: 1216px){html.theme--documenter-dark .column.is-narrow-widescreen{flex:none;width:unset}html.theme--documenter-dark .column.is-full-widescreen{flex:none;width:100%}html.theme--documenter-dark .column.is-three-quarters-widescreen{flex:none;width:75%}html.theme--documenter-dark .column.is-two-thirds-widescreen{flex:none;width:66.6666%}html.theme--documenter-dark .column.is-half-widescreen{flex:none;width:50%}html.theme--documenter-dark .column.is-one-third-widescreen{flex:none;width:33.3333%}html.theme--documenter-dark .column.is-one-quarter-widescreen{flex:none;width:25%}html.theme--documenter-dark .column.is-one-fifth-widescreen{flex:none;width:20%}html.theme--documenter-dark .column.is-two-fifths-widescreen{flex:none;width:40%}html.theme--documenter-dark .column.is-three-fifths-widescreen{flex:none;width:60%}html.theme--documenter-dark .column.is-four-fifths-widescreen{flex:none;width:80%}html.theme--documenter-dark .column.is-offset-three-quarters-widescreen{margin-left:75%}html.theme--documenter-dark .column.is-offset-two-thirds-widescreen{margin-left:66.6666%}html.theme--documenter-dark .column.is-offset-half-widescreen{margin-left:50%}html.theme--documenter-dark .column.is-offset-one-third-widescreen{margin-left:33.3333%}html.theme--documenter-dark .column.is-offset-one-quarter-widescreen{margin-left:25%}html.theme--documenter-dark .column.is-offset-one-fifth-widescreen{margin-left:20%}html.theme--documenter-dark .column.is-offset-two-fifths-widescreen{margin-left:40%}html.theme--documenter-dark .column.is-offset-three-fifths-widescreen{margin-left:60%}html.theme--documenter-dark .column.is-offset-four-fifths-widescreen{margin-left:80%}html.theme--documenter-dark .column.is-0-widescreen{flex:none;width:0%}html.theme--documenter-dark .column.is-offset-0-widescreen{margin-left:0%}html.theme--documenter-dark .column.is-1-widescreen{flex:none;width:8.33333337%}html.theme--documenter-dark .column.is-offset-1-widescreen{margin-left:8.33333337%}html.theme--documenter-dark .column.is-2-widescreen{flex:none;width:16.66666674%}html.theme--documenter-dark .column.is-offset-2-widescreen{margin-left:16.66666674%}html.theme--documenter-dark .column.is-3-widescreen{flex:none;width:25%}html.theme--documenter-dark .column.is-offset-3-widescreen{margin-left:25%}html.theme--documenter-dark .column.is-4-widescreen{flex:none;width:33.33333337%}html.theme--documenter-dark .column.is-offset-4-widescreen{margin-left:33.33333337%}html.theme--documenter-dark .column.is-5-widescreen{flex:none;width:41.66666674%}html.theme--documenter-dark .column.is-offset-5-widescreen{margin-left:41.66666674%}html.theme--documenter-dark .column.is-6-widescreen{flex:none;width:50%}html.theme--documenter-dark .column.is-offset-6-widescreen{margin-left:50%}html.theme--documenter-dark .column.is-7-widescreen{flex:none;width:58.33333337%}html.theme--documenter-dark .column.is-offset-7-widescreen{margin-left:58.33333337%}html.theme--documenter-dark .column.is-8-widescreen{flex:none;width:66.66666674%}html.theme--documenter-dark .column.is-offset-8-widescreen{margin-left:66.66666674%}html.theme--documenter-dark .column.is-9-widescreen{flex:none;width:75%}html.theme--documenter-dark .column.is-offset-9-widescreen{margin-left:75%}html.theme--documenter-dark .column.is-10-widescreen{flex:none;width:83.33333337%}html.theme--documenter-dark .column.is-offset-10-widescreen{margin-left:83.33333337%}html.theme--documenter-dark .column.is-11-widescreen{flex:none;width:91.66666674%}html.theme--documenter-dark .column.is-offset-11-widescreen{margin-left:91.66666674%}html.theme--documenter-dark .column.is-12-widescreen{flex:none;width:100%}html.theme--documenter-dark .column.is-offset-12-widescreen{margin-left:100%}}@media screen and (min-width: 1408px){html.theme--documenter-dark .column.is-narrow-fullhd{flex:none;width:unset}html.theme--documenter-dark .column.is-full-fullhd{flex:none;width:100%}html.theme--documenter-dark .column.is-three-quarters-fullhd{flex:none;width:75%}html.theme--documenter-dark .column.is-two-thirds-fullhd{flex:none;width:66.6666%}html.theme--documenter-dark .column.is-half-fullhd{flex:none;width:50%}html.theme--documenter-dark .column.is-one-third-fullhd{flex:none;width:33.3333%}html.theme--documenter-dark .column.is-one-quarter-fullhd{flex:none;width:25%}html.theme--documenter-dark .column.is-one-fifth-fullhd{flex:none;width:20%}html.theme--documenter-dark .column.is-two-fifths-fullhd{flex:none;width:40%}html.theme--documenter-dark .column.is-three-fifths-fullhd{flex:none;width:60%}html.theme--documenter-dark .column.is-four-fifths-fullhd{flex:none;width:80%}html.theme--documenter-dark .column.is-offset-three-quarters-fullhd{margin-left:75%}html.theme--documenter-dark .column.is-offset-two-thirds-fullhd{margin-left:66.6666%}html.theme--documenter-dark .column.is-offset-half-fullhd{margin-left:50%}html.theme--documenter-dark .column.is-offset-one-third-fullhd{margin-left:33.3333%}html.theme--documenter-dark .column.is-offset-one-quarter-fullhd{margin-left:25%}html.theme--documenter-dark .column.is-offset-one-fifth-fullhd{margin-left:20%}html.theme--documenter-dark .column.is-offset-two-fifths-fullhd{margin-left:40%}html.theme--documenter-dark .column.is-offset-three-fifths-fullhd{margin-left:60%}html.theme--documenter-dark .column.is-offset-four-fifths-fullhd{margin-left:80%}html.theme--documenter-dark .column.is-0-fullhd{flex:none;width:0%}html.theme--documenter-dark .column.is-offset-0-fullhd{margin-left:0%}html.theme--documenter-dark .column.is-1-fullhd{flex:none;width:8.33333337%}html.theme--documenter-dark .column.is-offset-1-fullhd{margin-left:8.33333337%}html.theme--documenter-dark .column.is-2-fullhd{flex:none;width:16.66666674%}html.theme--documenter-dark .column.is-offset-2-fullhd{margin-left:16.66666674%}html.theme--documenter-dark .column.is-3-fullhd{flex:none;width:25%}html.theme--documenter-dark .column.is-offset-3-fullhd{margin-left:25%}html.theme--documenter-dark .column.is-4-fullhd{flex:none;width:33.33333337%}html.theme--documenter-dark .column.is-offset-4-fullhd{margin-left:33.33333337%}html.theme--documenter-dark .column.is-5-fullhd{flex:none;width:41.66666674%}html.theme--documenter-dark .column.is-offset-5-fullhd{margin-left:41.66666674%}html.theme--documenter-dark .column.is-6-fullhd{flex:none;width:50%}html.theme--documenter-dark .column.is-offset-6-fullhd{margin-left:50%}html.theme--documenter-dark .column.is-7-fullhd{flex:none;width:58.33333337%}html.theme--documenter-dark .column.is-offset-7-fullhd{margin-left:58.33333337%}html.theme--documenter-dark .column.is-8-fullhd{flex:none;width:66.66666674%}html.theme--documenter-dark .column.is-offset-8-fullhd{margin-left:66.66666674%}html.theme--documenter-dark .column.is-9-fullhd{flex:none;width:75%}html.theme--documenter-dark .column.is-offset-9-fullhd{margin-left:75%}html.theme--documenter-dark .column.is-10-fullhd{flex:none;width:83.33333337%}html.theme--documenter-dark .column.is-offset-10-fullhd{margin-left:83.33333337%}html.theme--documenter-dark .column.is-11-fullhd{flex:none;width:91.66666674%}html.theme--documenter-dark .column.is-offset-11-fullhd{margin-left:91.66666674%}html.theme--documenter-dark .column.is-12-fullhd{flex:none;width:100%}html.theme--documenter-dark .column.is-offset-12-fullhd{margin-left:100%}}html.theme--documenter-dark .columns{margin-left:-.75rem;margin-right:-.75rem;margin-top:-.75rem}html.theme--documenter-dark .columns:last-child{margin-bottom:-.75rem}html.theme--documenter-dark .columns:not(:last-child){margin-bottom:calc(1.5rem - .75rem)}html.theme--documenter-dark .columns.is-centered{justify-content:center}html.theme--documenter-dark .columns.is-gapless{margin-left:0;margin-right:0;margin-top:0}html.theme--documenter-dark .columns.is-gapless>.column{margin:0;padding:0 !important}html.theme--documenter-dark .columns.is-gapless:not(:last-child){margin-bottom:1.5rem}html.theme--documenter-dark .columns.is-gapless:last-child{margin-bottom:0}html.theme--documenter-dark .columns.is-mobile{display:flex}html.theme--documenter-dark .columns.is-multiline{flex-wrap:wrap}html.theme--documenter-dark .columns.is-vcentered{align-items:center}@media screen and (min-width: 769px),print{html.theme--documenter-dark .columns:not(.is-desktop){display:flex}}@media screen and (min-width: 1056px){html.theme--documenter-dark .columns.is-desktop{display:flex}}html.theme--documenter-dark .columns.is-variable{--columnGap: 0.75rem;margin-left:calc(-1 * var(--columnGap));margin-right:calc(-1 * var(--columnGap))}html.theme--documenter-dark .columns.is-variable>.column{padding-left:var(--columnGap);padding-right:var(--columnGap)}html.theme--documenter-dark .columns.is-variable.is-0{--columnGap: 0rem}@media screen and (max-width: 768px){html.theme--documenter-dark .columns.is-variable.is-0-mobile{--columnGap: 0rem}}@media screen and (min-width: 769px),print{html.theme--documenter-dark .columns.is-variable.is-0-tablet{--columnGap: 0rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--documenter-dark .columns.is-variable.is-0-tablet-only{--columnGap: 0rem}}@media screen and (max-width: 1055px){html.theme--documenter-dark .columns.is-variable.is-0-touch{--columnGap: 0rem}}@media screen and (min-width: 1056px){html.theme--documenter-dark .columns.is-variable.is-0-desktop{--columnGap: 0rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--documenter-dark .columns.is-variable.is-0-desktop-only{--columnGap: 0rem}}@media screen and (min-width: 1216px){html.theme--documenter-dark .columns.is-variable.is-0-widescreen{--columnGap: 0rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--documenter-dark .columns.is-variable.is-0-widescreen-only{--columnGap: 0rem}}@media screen and (min-width: 1408px){html.theme--documenter-dark .columns.is-variable.is-0-fullhd{--columnGap: 0rem}}html.theme--documenter-dark .columns.is-variable.is-1{--columnGap: .25rem}@media screen and (max-width: 768px){html.theme--documenter-dark .columns.is-variable.is-1-mobile{--columnGap: .25rem}}@media screen and (min-width: 769px),print{html.theme--documenter-dark .columns.is-variable.is-1-tablet{--columnGap: .25rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--documenter-dark .columns.is-variable.is-1-tablet-only{--columnGap: .25rem}}@media screen and (max-width: 1055px){html.theme--documenter-dark .columns.is-variable.is-1-touch{--columnGap: .25rem}}@media screen and (min-width: 1056px){html.theme--documenter-dark .columns.is-variable.is-1-desktop{--columnGap: .25rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--documenter-dark .columns.is-variable.is-1-desktop-only{--columnGap: .25rem}}@media screen and (min-width: 1216px){html.theme--documenter-dark .columns.is-variable.is-1-widescreen{--columnGap: .25rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--documenter-dark .columns.is-variable.is-1-widescreen-only{--columnGap: .25rem}}@media screen and (min-width: 1408px){html.theme--documenter-dark .columns.is-variable.is-1-fullhd{--columnGap: .25rem}}html.theme--documenter-dark .columns.is-variable.is-2{--columnGap: .5rem}@media screen and (max-width: 768px){html.theme--documenter-dark .columns.is-variable.is-2-mobile{--columnGap: .5rem}}@media screen and (min-width: 769px),print{html.theme--documenter-dark .columns.is-variable.is-2-tablet{--columnGap: .5rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--documenter-dark .columns.is-variable.is-2-tablet-only{--columnGap: .5rem}}@media screen and (max-width: 1055px){html.theme--documenter-dark .columns.is-variable.is-2-touch{--columnGap: .5rem}}@media screen and (min-width: 1056px){html.theme--documenter-dark .columns.is-variable.is-2-desktop{--columnGap: .5rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--documenter-dark .columns.is-variable.is-2-desktop-only{--columnGap: .5rem}}@media screen and (min-width: 1216px){html.theme--documenter-dark .columns.is-variable.is-2-widescreen{--columnGap: .5rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--documenter-dark .columns.is-variable.is-2-widescreen-only{--columnGap: .5rem}}@media screen and (min-width: 1408px){html.theme--documenter-dark .columns.is-variable.is-2-fullhd{--columnGap: .5rem}}html.theme--documenter-dark .columns.is-variable.is-3{--columnGap: .75rem}@media screen and (max-width: 768px){html.theme--documenter-dark .columns.is-variable.is-3-mobile{--columnGap: .75rem}}@media screen and (min-width: 769px),print{html.theme--documenter-dark .columns.is-variable.is-3-tablet{--columnGap: .75rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--documenter-dark .columns.is-variable.is-3-tablet-only{--columnGap: .75rem}}@media screen and (max-width: 1055px){html.theme--documenter-dark .columns.is-variable.is-3-touch{--columnGap: .75rem}}@media screen and (min-width: 1056px){html.theme--documenter-dark .columns.is-variable.is-3-desktop{--columnGap: .75rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--documenter-dark .columns.is-variable.is-3-desktop-only{--columnGap: .75rem}}@media screen and (min-width: 1216px){html.theme--documenter-dark .columns.is-variable.is-3-widescreen{--columnGap: .75rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--documenter-dark .columns.is-variable.is-3-widescreen-only{--columnGap: .75rem}}@media screen and (min-width: 1408px){html.theme--documenter-dark .columns.is-variable.is-3-fullhd{--columnGap: .75rem}}html.theme--documenter-dark .columns.is-variable.is-4{--columnGap: 1rem}@media screen and (max-width: 768px){html.theme--documenter-dark .columns.is-variable.is-4-mobile{--columnGap: 1rem}}@media screen and (min-width: 769px),print{html.theme--documenter-dark .columns.is-variable.is-4-tablet{--columnGap: 1rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--documenter-dark .columns.is-variable.is-4-tablet-only{--columnGap: 1rem}}@media screen and (max-width: 1055px){html.theme--documenter-dark .columns.is-variable.is-4-touch{--columnGap: 1rem}}@media screen and (min-width: 1056px){html.theme--documenter-dark .columns.is-variable.is-4-desktop{--columnGap: 1rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--documenter-dark .columns.is-variable.is-4-desktop-only{--columnGap: 1rem}}@media screen and (min-width: 1216px){html.theme--documenter-dark .columns.is-variable.is-4-widescreen{--columnGap: 1rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--documenter-dark .columns.is-variable.is-4-widescreen-only{--columnGap: 1rem}}@media screen and (min-width: 1408px){html.theme--documenter-dark .columns.is-variable.is-4-fullhd{--columnGap: 1rem}}html.theme--documenter-dark .columns.is-variable.is-5{--columnGap: 1.25rem}@media screen and (max-width: 768px){html.theme--documenter-dark .columns.is-variable.is-5-mobile{--columnGap: 1.25rem}}@media screen and (min-width: 769px),print{html.theme--documenter-dark .columns.is-variable.is-5-tablet{--columnGap: 1.25rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--documenter-dark .columns.is-variable.is-5-tablet-only{--columnGap: 1.25rem}}@media screen and (max-width: 1055px){html.theme--documenter-dark .columns.is-variable.is-5-touch{--columnGap: 1.25rem}}@media screen and (min-width: 1056px){html.theme--documenter-dark .columns.is-variable.is-5-desktop{--columnGap: 1.25rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--documenter-dark .columns.is-variable.is-5-desktop-only{--columnGap: 1.25rem}}@media screen and (min-width: 1216px){html.theme--documenter-dark .columns.is-variable.is-5-widescreen{--columnGap: 1.25rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--documenter-dark .columns.is-variable.is-5-widescreen-only{--columnGap: 1.25rem}}@media screen and (min-width: 1408px){html.theme--documenter-dark .columns.is-variable.is-5-fullhd{--columnGap: 1.25rem}}html.theme--documenter-dark .columns.is-variable.is-6{--columnGap: 1.5rem}@media screen and (max-width: 768px){html.theme--documenter-dark .columns.is-variable.is-6-mobile{--columnGap: 1.5rem}}@media screen and (min-width: 769px),print{html.theme--documenter-dark .columns.is-variable.is-6-tablet{--columnGap: 1.5rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--documenter-dark .columns.is-variable.is-6-tablet-only{--columnGap: 1.5rem}}@media screen and (max-width: 1055px){html.theme--documenter-dark .columns.is-variable.is-6-touch{--columnGap: 1.5rem}}@media screen and (min-width: 1056px){html.theme--documenter-dark .columns.is-variable.is-6-desktop{--columnGap: 1.5rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--documenter-dark .columns.is-variable.is-6-desktop-only{--columnGap: 1.5rem}}@media screen and (min-width: 1216px){html.theme--documenter-dark .columns.is-variable.is-6-widescreen{--columnGap: 1.5rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--documenter-dark .columns.is-variable.is-6-widescreen-only{--columnGap: 1.5rem}}@media screen and (min-width: 1408px){html.theme--documenter-dark .columns.is-variable.is-6-fullhd{--columnGap: 1.5rem}}html.theme--documenter-dark .columns.is-variable.is-7{--columnGap: 1.75rem}@media screen and (max-width: 768px){html.theme--documenter-dark .columns.is-variable.is-7-mobile{--columnGap: 1.75rem}}@media screen and (min-width: 769px),print{html.theme--documenter-dark .columns.is-variable.is-7-tablet{--columnGap: 1.75rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--documenter-dark .columns.is-variable.is-7-tablet-only{--columnGap: 1.75rem}}@media screen and (max-width: 1055px){html.theme--documenter-dark .columns.is-variable.is-7-touch{--columnGap: 1.75rem}}@media screen and (min-width: 1056px){html.theme--documenter-dark .columns.is-variable.is-7-desktop{--columnGap: 1.75rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--documenter-dark .columns.is-variable.is-7-desktop-only{--columnGap: 1.75rem}}@media screen and (min-width: 1216px){html.theme--documenter-dark .columns.is-variable.is-7-widescreen{--columnGap: 1.75rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--documenter-dark .columns.is-variable.is-7-widescreen-only{--columnGap: 1.75rem}}@media screen and (min-width: 1408px){html.theme--documenter-dark .columns.is-variable.is-7-fullhd{--columnGap: 1.75rem}}html.theme--documenter-dark .columns.is-variable.is-8{--columnGap: 2rem}@media screen and (max-width: 768px){html.theme--documenter-dark .columns.is-variable.is-8-mobile{--columnGap: 2rem}}@media screen and (min-width: 769px),print{html.theme--documenter-dark .columns.is-variable.is-8-tablet{--columnGap: 2rem}}@media screen and (min-width: 769px) and (max-width: 1055px){html.theme--documenter-dark .columns.is-variable.is-8-tablet-only{--columnGap: 2rem}}@media screen and (max-width: 1055px){html.theme--documenter-dark .columns.is-variable.is-8-touch{--columnGap: 2rem}}@media screen and (min-width: 1056px){html.theme--documenter-dark .columns.is-variable.is-8-desktop{--columnGap: 2rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){html.theme--documenter-dark .columns.is-variable.is-8-desktop-only{--columnGap: 2rem}}@media screen and (min-width: 1216px){html.theme--documenter-dark .columns.is-variable.is-8-widescreen{--columnGap: 2rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){html.theme--documenter-dark .columns.is-variable.is-8-widescreen-only{--columnGap: 2rem}}@media screen and (min-width: 1408px){html.theme--documenter-dark .columns.is-variable.is-8-fullhd{--columnGap: 2rem}}html.theme--documenter-dark .tile{align-items:stretch;display:block;flex-basis:0;flex-grow:1;flex-shrink:1;min-height:min-content}html.theme--documenter-dark .tile.is-ancestor{margin-left:-.75rem;margin-right:-.75rem;margin-top:-.75rem}html.theme--documenter-dark .tile.is-ancestor:last-child{margin-bottom:-.75rem}html.theme--documenter-dark .tile.is-ancestor:not(:last-child){margin-bottom:.75rem}html.theme--documenter-dark .tile.is-child{margin:0 !important}html.theme--documenter-dark .tile.is-parent{padding:.75rem}html.theme--documenter-dark .tile.is-vertical{flex-direction:column}html.theme--documenter-dark .tile.is-vertical>.tile.is-child:not(:last-child){margin-bottom:1.5rem !important}@media screen and (min-width: 769px),print{html.theme--documenter-dark .tile:not(.is-child){display:flex}html.theme--documenter-dark .tile.is-1{flex:none;width:8.33333337%}html.theme--documenter-dark .tile.is-2{flex:none;width:16.66666674%}html.theme--documenter-dark .tile.is-3{flex:none;width:25%}html.theme--documenter-dark .tile.is-4{flex:none;width:33.33333337%}html.theme--documenter-dark .tile.is-5{flex:none;width:41.66666674%}html.theme--documenter-dark .tile.is-6{flex:none;width:50%}html.theme--documenter-dark .tile.is-7{flex:none;width:58.33333337%}html.theme--documenter-dark .tile.is-8{flex:none;width:66.66666674%}html.theme--documenter-dark .tile.is-9{flex:none;width:75%}html.theme--documenter-dark .tile.is-10{flex:none;width:83.33333337%}html.theme--documenter-dark .tile.is-11{flex:none;width:91.66666674%}html.theme--documenter-dark .tile.is-12{flex:none;width:100%}}html.theme--documenter-dark .hero{align-items:stretch;display:flex;flex-direction:column;justify-content:space-between}html.theme--documenter-dark .hero .navbar{background:none}html.theme--documenter-dark .hero .tabs ul{border-bottom:none}html.theme--documenter-dark .hero.is-white{background-color:#fff;color:#0a0a0a}html.theme--documenter-dark .hero.is-white a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--documenter-dark .hero.is-white strong{color:inherit}html.theme--documenter-dark .hero.is-white .title{color:#0a0a0a}html.theme--documenter-dark .hero.is-white .subtitle{color:rgba(10,10,10,0.9)}html.theme--documenter-dark .hero.is-white .subtitle a:not(.button),html.theme--documenter-dark .hero.is-white .subtitle strong{color:#0a0a0a}@media screen and (max-width: 1055px){html.theme--documenter-dark .hero.is-white .navbar-menu{background-color:#fff}}html.theme--documenter-dark .hero.is-white .navbar-item,html.theme--documenter-dark .hero.is-white .navbar-link{color:rgba(10,10,10,0.7)}html.theme--documenter-dark .hero.is-white a.navbar-item:hover,html.theme--documenter-dark .hero.is-white a.navbar-item.is-active,html.theme--documenter-dark .hero.is-white .navbar-link:hover,html.theme--documenter-dark .hero.is-white .navbar-link.is-active{background-color:#f2f2f2;color:#0a0a0a}html.theme--documenter-dark .hero.is-white .tabs a{color:#0a0a0a;opacity:0.9}html.theme--documenter-dark .hero.is-white .tabs a:hover{opacity:1}html.theme--documenter-dark .hero.is-white .tabs li.is-active a{color:#fff !important;opacity:1}html.theme--documenter-dark .hero.is-white .tabs.is-boxed a,html.theme--documenter-dark .hero.is-white .tabs.is-toggle a{color:#0a0a0a}html.theme--documenter-dark .hero.is-white .tabs.is-boxed a:hover,html.theme--documenter-dark .hero.is-white .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--documenter-dark .hero.is-white .tabs.is-boxed li.is-active a,html.theme--documenter-dark .hero.is-white .tabs.is-boxed li.is-active a:hover,html.theme--documenter-dark .hero.is-white .tabs.is-toggle li.is-active a,html.theme--documenter-dark .hero.is-white .tabs.is-toggle li.is-active a:hover{background-color:#0a0a0a;border-color:#0a0a0a;color:#fff}html.theme--documenter-dark .hero.is-white.is-bold{background-image:linear-gradient(141deg, #e8e3e4 0%, #fff 71%, #fff 100%)}@media screen and (max-width: 768px){html.theme--documenter-dark .hero.is-white.is-bold .navbar-menu{background-image:linear-gradient(141deg, #e8e3e4 0%, #fff 71%, #fff 100%)}}html.theme--documenter-dark .hero.is-black{background-color:#0a0a0a;color:#fff}html.theme--documenter-dark .hero.is-black a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--documenter-dark .hero.is-black strong{color:inherit}html.theme--documenter-dark .hero.is-black .title{color:#fff}html.theme--documenter-dark .hero.is-black .subtitle{color:rgba(255,255,255,0.9)}html.theme--documenter-dark .hero.is-black .subtitle a:not(.button),html.theme--documenter-dark .hero.is-black .subtitle strong{color:#fff}@media screen and (max-width: 1055px){html.theme--documenter-dark .hero.is-black .navbar-menu{background-color:#0a0a0a}}html.theme--documenter-dark .hero.is-black .navbar-item,html.theme--documenter-dark .hero.is-black .navbar-link{color:rgba(255,255,255,0.7)}html.theme--documenter-dark .hero.is-black a.navbar-item:hover,html.theme--documenter-dark .hero.is-black a.navbar-item.is-active,html.theme--documenter-dark .hero.is-black .navbar-link:hover,html.theme--documenter-dark .hero.is-black .navbar-link.is-active{background-color:#000;color:#fff}html.theme--documenter-dark .hero.is-black .tabs a{color:#fff;opacity:0.9}html.theme--documenter-dark .hero.is-black .tabs a:hover{opacity:1}html.theme--documenter-dark .hero.is-black .tabs li.is-active a{color:#0a0a0a !important;opacity:1}html.theme--documenter-dark .hero.is-black .tabs.is-boxed a,html.theme--documenter-dark .hero.is-black .tabs.is-toggle a{color:#fff}html.theme--documenter-dark .hero.is-black .tabs.is-boxed a:hover,html.theme--documenter-dark .hero.is-black .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--documenter-dark .hero.is-black .tabs.is-boxed li.is-active a,html.theme--documenter-dark .hero.is-black .tabs.is-boxed li.is-active a:hover,html.theme--documenter-dark .hero.is-black .tabs.is-toggle li.is-active a,html.theme--documenter-dark .hero.is-black .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#0a0a0a}html.theme--documenter-dark .hero.is-black.is-bold{background-image:linear-gradient(141deg, #000 0%, #0a0a0a 71%, #181616 100%)}@media screen and (max-width: 768px){html.theme--documenter-dark .hero.is-black.is-bold .navbar-menu{background-image:linear-gradient(141deg, #000 0%, #0a0a0a 71%, #181616 100%)}}html.theme--documenter-dark .hero.is-light{background-color:#ecf0f1;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .hero.is-light a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--documenter-dark .hero.is-light strong{color:inherit}html.theme--documenter-dark .hero.is-light .title{color:rgba(0,0,0,0.7)}html.theme--documenter-dark .hero.is-light .subtitle{color:rgba(0,0,0,0.9)}html.theme--documenter-dark .hero.is-light .subtitle a:not(.button),html.theme--documenter-dark .hero.is-light .subtitle strong{color:rgba(0,0,0,0.7)}@media screen and (max-width: 1055px){html.theme--documenter-dark .hero.is-light .navbar-menu{background-color:#ecf0f1}}html.theme--documenter-dark .hero.is-light .navbar-item,html.theme--documenter-dark .hero.is-light .navbar-link{color:rgba(0,0,0,0.7)}html.theme--documenter-dark .hero.is-light a.navbar-item:hover,html.theme--documenter-dark .hero.is-light a.navbar-item.is-active,html.theme--documenter-dark .hero.is-light .navbar-link:hover,html.theme--documenter-dark .hero.is-light .navbar-link.is-active{background-color:#dde4e6;color:rgba(0,0,0,0.7)}html.theme--documenter-dark .hero.is-light .tabs a{color:rgba(0,0,0,0.7);opacity:0.9}html.theme--documenter-dark .hero.is-light .tabs a:hover{opacity:1}html.theme--documenter-dark .hero.is-light .tabs li.is-active a{color:#ecf0f1 !important;opacity:1}html.theme--documenter-dark .hero.is-light .tabs.is-boxed a,html.theme--documenter-dark .hero.is-light .tabs.is-toggle a{color:rgba(0,0,0,0.7)}html.theme--documenter-dark .hero.is-light .tabs.is-boxed a:hover,html.theme--documenter-dark .hero.is-light .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--documenter-dark .hero.is-light .tabs.is-boxed li.is-active a,html.theme--documenter-dark .hero.is-light .tabs.is-boxed li.is-active a:hover,html.theme--documenter-dark .hero.is-light .tabs.is-toggle li.is-active a,html.theme--documenter-dark .hero.is-light .tabs.is-toggle li.is-active a:hover{background-color:rgba(0,0,0,0.7);border-color:rgba(0,0,0,0.7);color:#ecf0f1}html.theme--documenter-dark .hero.is-light.is-bold{background-image:linear-gradient(141deg, #cadfe0 0%, #ecf0f1 71%, #fafbfc 100%)}@media screen and (max-width: 768px){html.theme--documenter-dark .hero.is-light.is-bold .navbar-menu{background-image:linear-gradient(141deg, #cadfe0 0%, #ecf0f1 71%, #fafbfc 100%)}}html.theme--documenter-dark .hero.is-dark,html.theme--documenter-dark .content kbd.hero{background-color:#282f2f;color:#fff}html.theme--documenter-dark .hero.is-dark a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--documenter-dark .content kbd.hero a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--documenter-dark .hero.is-dark strong,html.theme--documenter-dark .content kbd.hero strong{color:inherit}html.theme--documenter-dark .hero.is-dark .title,html.theme--documenter-dark .content kbd.hero .title{color:#fff}html.theme--documenter-dark .hero.is-dark .subtitle,html.theme--documenter-dark .content kbd.hero .subtitle{color:rgba(255,255,255,0.9)}html.theme--documenter-dark .hero.is-dark .subtitle a:not(.button),html.theme--documenter-dark .content kbd.hero .subtitle a:not(.button),html.theme--documenter-dark .hero.is-dark .subtitle strong,html.theme--documenter-dark .content kbd.hero .subtitle strong{color:#fff}@media screen and (max-width: 1055px){html.theme--documenter-dark .hero.is-dark .navbar-menu,html.theme--documenter-dark .content kbd.hero .navbar-menu{background-color:#282f2f}}html.theme--documenter-dark .hero.is-dark .navbar-item,html.theme--documenter-dark .content kbd.hero .navbar-item,html.theme--documenter-dark .hero.is-dark .navbar-link,html.theme--documenter-dark .content kbd.hero .navbar-link{color:rgba(255,255,255,0.7)}html.theme--documenter-dark .hero.is-dark a.navbar-item:hover,html.theme--documenter-dark .content kbd.hero a.navbar-item:hover,html.theme--documenter-dark .hero.is-dark a.navbar-item.is-active,html.theme--documenter-dark .content kbd.hero a.navbar-item.is-active,html.theme--documenter-dark .hero.is-dark .navbar-link:hover,html.theme--documenter-dark .content kbd.hero .navbar-link:hover,html.theme--documenter-dark .hero.is-dark .navbar-link.is-active,html.theme--documenter-dark .content kbd.hero .navbar-link.is-active{background-color:#1d2122;color:#fff}html.theme--documenter-dark .hero.is-dark .tabs a,html.theme--documenter-dark .content kbd.hero .tabs a{color:#fff;opacity:0.9}html.theme--documenter-dark .hero.is-dark .tabs a:hover,html.theme--documenter-dark .content kbd.hero .tabs a:hover{opacity:1}html.theme--documenter-dark .hero.is-dark .tabs li.is-active a,html.theme--documenter-dark .content kbd.hero .tabs li.is-active a{color:#282f2f !important;opacity:1}html.theme--documenter-dark .hero.is-dark .tabs.is-boxed a,html.theme--documenter-dark .content kbd.hero .tabs.is-boxed a,html.theme--documenter-dark .hero.is-dark .tabs.is-toggle a,html.theme--documenter-dark .content kbd.hero .tabs.is-toggle a{color:#fff}html.theme--documenter-dark .hero.is-dark .tabs.is-boxed a:hover,html.theme--documenter-dark .content kbd.hero .tabs.is-boxed a:hover,html.theme--documenter-dark .hero.is-dark .tabs.is-toggle a:hover,html.theme--documenter-dark .content kbd.hero .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--documenter-dark .hero.is-dark .tabs.is-boxed li.is-active a,html.theme--documenter-dark .content kbd.hero .tabs.is-boxed li.is-active a,html.theme--documenter-dark .hero.is-dark .tabs.is-boxed li.is-active a:hover,html.theme--documenter-dark .hero.is-dark .tabs.is-toggle li.is-active a,html.theme--documenter-dark .content kbd.hero .tabs.is-toggle li.is-active a,html.theme--documenter-dark .hero.is-dark .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#282f2f}html.theme--documenter-dark .hero.is-dark.is-bold,html.theme--documenter-dark .content kbd.hero.is-bold{background-image:linear-gradient(141deg, #0f1615 0%, #282f2f 71%, #313c40 100%)}@media screen and (max-width: 768px){html.theme--documenter-dark .hero.is-dark.is-bold .navbar-menu,html.theme--documenter-dark .content kbd.hero.is-bold .navbar-menu{background-image:linear-gradient(141deg, #0f1615 0%, #282f2f 71%, #313c40 100%)}}html.theme--documenter-dark .hero.is-primary,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink{background-color:#375a7f;color:#fff}html.theme--documenter-dark .hero.is-primary a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--documenter-dark .hero.is-primary strong,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink strong{color:inherit}html.theme--documenter-dark .hero.is-primary .title,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .title{color:#fff}html.theme--documenter-dark .hero.is-primary .subtitle,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .subtitle{color:rgba(255,255,255,0.9)}html.theme--documenter-dark .hero.is-primary .subtitle a:not(.button),html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .subtitle a:not(.button),html.theme--documenter-dark .hero.is-primary .subtitle strong,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .subtitle strong{color:#fff}@media screen and (max-width: 1055px){html.theme--documenter-dark .hero.is-primary .navbar-menu,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .navbar-menu{background-color:#375a7f}}html.theme--documenter-dark .hero.is-primary .navbar-item,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .navbar-item,html.theme--documenter-dark .hero.is-primary .navbar-link,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .navbar-link{color:rgba(255,255,255,0.7)}html.theme--documenter-dark .hero.is-primary a.navbar-item:hover,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink a.navbar-item:hover,html.theme--documenter-dark .hero.is-primary a.navbar-item.is-active,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink a.navbar-item.is-active,html.theme--documenter-dark .hero.is-primary .navbar-link:hover,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .navbar-link:hover,html.theme--documenter-dark .hero.is-primary .navbar-link.is-active,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .navbar-link.is-active{background-color:#2f4d6d;color:#fff}html.theme--documenter-dark .hero.is-primary .tabs a,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .tabs a{color:#fff;opacity:0.9}html.theme--documenter-dark .hero.is-primary .tabs a:hover,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .tabs a:hover{opacity:1}html.theme--documenter-dark .hero.is-primary .tabs li.is-active a,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .tabs li.is-active a{color:#375a7f !important;opacity:1}html.theme--documenter-dark .hero.is-primary .tabs.is-boxed a,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .tabs.is-boxed a,html.theme--documenter-dark .hero.is-primary .tabs.is-toggle a,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .tabs.is-toggle a{color:#fff}html.theme--documenter-dark .hero.is-primary .tabs.is-boxed a:hover,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .tabs.is-boxed a:hover,html.theme--documenter-dark .hero.is-primary .tabs.is-toggle a:hover,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--documenter-dark .hero.is-primary .tabs.is-boxed li.is-active a,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .tabs.is-boxed li.is-active a,html.theme--documenter-dark .hero.is-primary .tabs.is-boxed li.is-active a:hover,html.theme--documenter-dark .hero.is-primary .tabs.is-toggle li.is-active a,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .tabs.is-toggle li.is-active a,html.theme--documenter-dark .hero.is-primary .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#375a7f}html.theme--documenter-dark .hero.is-primary.is-bold,html.theme--documenter-dark .docstring>section>a.hero.is-bold.docs-sourcelink{background-image:linear-gradient(141deg, #214b62 0%, #375a7f 71%, #3a5796 100%)}@media screen and (max-width: 768px){html.theme--documenter-dark .hero.is-primary.is-bold .navbar-menu,html.theme--documenter-dark .docstring>section>a.hero.is-bold.docs-sourcelink .navbar-menu{background-image:linear-gradient(141deg, #214b62 0%, #375a7f 71%, #3a5796 100%)}}html.theme--documenter-dark .hero.is-link{background-color:#1abc9c;color:#fff}html.theme--documenter-dark .hero.is-link a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--documenter-dark .hero.is-link strong{color:inherit}html.theme--documenter-dark .hero.is-link .title{color:#fff}html.theme--documenter-dark .hero.is-link .subtitle{color:rgba(255,255,255,0.9)}html.theme--documenter-dark .hero.is-link .subtitle a:not(.button),html.theme--documenter-dark .hero.is-link .subtitle strong{color:#fff}@media screen and (max-width: 1055px){html.theme--documenter-dark .hero.is-link .navbar-menu{background-color:#1abc9c}}html.theme--documenter-dark .hero.is-link .navbar-item,html.theme--documenter-dark .hero.is-link .navbar-link{color:rgba(255,255,255,0.7)}html.theme--documenter-dark .hero.is-link a.navbar-item:hover,html.theme--documenter-dark .hero.is-link a.navbar-item.is-active,html.theme--documenter-dark .hero.is-link .navbar-link:hover,html.theme--documenter-dark .hero.is-link .navbar-link.is-active{background-color:#17a689;color:#fff}html.theme--documenter-dark .hero.is-link .tabs a{color:#fff;opacity:0.9}html.theme--documenter-dark .hero.is-link .tabs a:hover{opacity:1}html.theme--documenter-dark .hero.is-link .tabs li.is-active a{color:#1abc9c !important;opacity:1}html.theme--documenter-dark .hero.is-link .tabs.is-boxed a,html.theme--documenter-dark .hero.is-link .tabs.is-toggle a{color:#fff}html.theme--documenter-dark .hero.is-link .tabs.is-boxed a:hover,html.theme--documenter-dark .hero.is-link .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--documenter-dark .hero.is-link .tabs.is-boxed li.is-active a,html.theme--documenter-dark .hero.is-link .tabs.is-boxed li.is-active a:hover,html.theme--documenter-dark .hero.is-link .tabs.is-toggle li.is-active a,html.theme--documenter-dark .hero.is-link .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#1abc9c}html.theme--documenter-dark .hero.is-link.is-bold{background-image:linear-gradient(141deg, #0c9764 0%, #1abc9c 71%, #17d8d2 100%)}@media screen and (max-width: 768px){html.theme--documenter-dark .hero.is-link.is-bold .navbar-menu{background-image:linear-gradient(141deg, #0c9764 0%, #1abc9c 71%, #17d8d2 100%)}}html.theme--documenter-dark .hero.is-info{background-color:#024c7d;color:#fff}html.theme--documenter-dark .hero.is-info a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--documenter-dark .hero.is-info strong{color:inherit}html.theme--documenter-dark .hero.is-info .title{color:#fff}html.theme--documenter-dark .hero.is-info .subtitle{color:rgba(255,255,255,0.9)}html.theme--documenter-dark .hero.is-info .subtitle a:not(.button),html.theme--documenter-dark .hero.is-info .subtitle strong{color:#fff}@media screen and (max-width: 1055px){html.theme--documenter-dark .hero.is-info .navbar-menu{background-color:#024c7d}}html.theme--documenter-dark .hero.is-info .navbar-item,html.theme--documenter-dark .hero.is-info .navbar-link{color:rgba(255,255,255,0.7)}html.theme--documenter-dark .hero.is-info a.navbar-item:hover,html.theme--documenter-dark .hero.is-info a.navbar-item.is-active,html.theme--documenter-dark .hero.is-info .navbar-link:hover,html.theme--documenter-dark .hero.is-info .navbar-link.is-active{background-color:#023d64;color:#fff}html.theme--documenter-dark .hero.is-info .tabs a{color:#fff;opacity:0.9}html.theme--documenter-dark .hero.is-info .tabs a:hover{opacity:1}html.theme--documenter-dark .hero.is-info .tabs li.is-active a{color:#024c7d !important;opacity:1}html.theme--documenter-dark .hero.is-info .tabs.is-boxed a,html.theme--documenter-dark .hero.is-info .tabs.is-toggle a{color:#fff}html.theme--documenter-dark .hero.is-info .tabs.is-boxed a:hover,html.theme--documenter-dark .hero.is-info .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--documenter-dark .hero.is-info .tabs.is-boxed li.is-active a,html.theme--documenter-dark .hero.is-info .tabs.is-boxed li.is-active a:hover,html.theme--documenter-dark .hero.is-info .tabs.is-toggle li.is-active a,html.theme--documenter-dark .hero.is-info .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#024c7d}html.theme--documenter-dark .hero.is-info.is-bold{background-image:linear-gradient(141deg, #003a4c 0%, #024c7d 71%, #004299 100%)}@media screen and (max-width: 768px){html.theme--documenter-dark .hero.is-info.is-bold .navbar-menu{background-image:linear-gradient(141deg, #003a4c 0%, #024c7d 71%, #004299 100%)}}html.theme--documenter-dark .hero.is-success{background-color:#008438;color:#fff}html.theme--documenter-dark .hero.is-success a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--documenter-dark .hero.is-success strong{color:inherit}html.theme--documenter-dark .hero.is-success .title{color:#fff}html.theme--documenter-dark .hero.is-success .subtitle{color:rgba(255,255,255,0.9)}html.theme--documenter-dark .hero.is-success .subtitle a:not(.button),html.theme--documenter-dark .hero.is-success .subtitle strong{color:#fff}@media screen and (max-width: 1055px){html.theme--documenter-dark .hero.is-success .navbar-menu{background-color:#008438}}html.theme--documenter-dark .hero.is-success .navbar-item,html.theme--documenter-dark .hero.is-success .navbar-link{color:rgba(255,255,255,0.7)}html.theme--documenter-dark .hero.is-success a.navbar-item:hover,html.theme--documenter-dark .hero.is-success a.navbar-item.is-active,html.theme--documenter-dark .hero.is-success .navbar-link:hover,html.theme--documenter-dark .hero.is-success .navbar-link.is-active{background-color:#006b2d;color:#fff}html.theme--documenter-dark .hero.is-success .tabs a{color:#fff;opacity:0.9}html.theme--documenter-dark .hero.is-success .tabs a:hover{opacity:1}html.theme--documenter-dark .hero.is-success .tabs li.is-active a{color:#008438 !important;opacity:1}html.theme--documenter-dark .hero.is-success .tabs.is-boxed a,html.theme--documenter-dark .hero.is-success .tabs.is-toggle a{color:#fff}html.theme--documenter-dark .hero.is-success .tabs.is-boxed a:hover,html.theme--documenter-dark .hero.is-success .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--documenter-dark .hero.is-success .tabs.is-boxed li.is-active a,html.theme--documenter-dark .hero.is-success .tabs.is-boxed li.is-active a:hover,html.theme--documenter-dark .hero.is-success .tabs.is-toggle li.is-active a,html.theme--documenter-dark .hero.is-success .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#008438}html.theme--documenter-dark .hero.is-success.is-bold{background-image:linear-gradient(141deg, #005115 0%, #008438 71%, #009e5d 100%)}@media screen and (max-width: 768px){html.theme--documenter-dark .hero.is-success.is-bold .navbar-menu{background-image:linear-gradient(141deg, #005115 0%, #008438 71%, #009e5d 100%)}}html.theme--documenter-dark .hero.is-warning{background-color:#ad8100;color:#fff}html.theme--documenter-dark .hero.is-warning a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--documenter-dark .hero.is-warning strong{color:inherit}html.theme--documenter-dark .hero.is-warning .title{color:#fff}html.theme--documenter-dark .hero.is-warning .subtitle{color:rgba(255,255,255,0.9)}html.theme--documenter-dark .hero.is-warning .subtitle a:not(.button),html.theme--documenter-dark .hero.is-warning .subtitle strong{color:#fff}@media screen and (max-width: 1055px){html.theme--documenter-dark .hero.is-warning .navbar-menu{background-color:#ad8100}}html.theme--documenter-dark .hero.is-warning .navbar-item,html.theme--documenter-dark .hero.is-warning .navbar-link{color:rgba(255,255,255,0.7)}html.theme--documenter-dark .hero.is-warning a.navbar-item:hover,html.theme--documenter-dark .hero.is-warning a.navbar-item.is-active,html.theme--documenter-dark .hero.is-warning .navbar-link:hover,html.theme--documenter-dark .hero.is-warning .navbar-link.is-active{background-color:#946e00;color:#fff}html.theme--documenter-dark .hero.is-warning .tabs a{color:#fff;opacity:0.9}html.theme--documenter-dark .hero.is-warning .tabs a:hover{opacity:1}html.theme--documenter-dark .hero.is-warning .tabs li.is-active a{color:#ad8100 !important;opacity:1}html.theme--documenter-dark .hero.is-warning .tabs.is-boxed a,html.theme--documenter-dark .hero.is-warning .tabs.is-toggle a{color:#fff}html.theme--documenter-dark .hero.is-warning .tabs.is-boxed a:hover,html.theme--documenter-dark .hero.is-warning .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--documenter-dark .hero.is-warning .tabs.is-boxed li.is-active a,html.theme--documenter-dark .hero.is-warning .tabs.is-boxed li.is-active a:hover,html.theme--documenter-dark .hero.is-warning .tabs.is-toggle li.is-active a,html.theme--documenter-dark .hero.is-warning .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#ad8100}html.theme--documenter-dark .hero.is-warning.is-bold{background-image:linear-gradient(141deg, #7a4700 0%, #ad8100 71%, #c7b500 100%)}@media screen and (max-width: 768px){html.theme--documenter-dark .hero.is-warning.is-bold .navbar-menu{background-image:linear-gradient(141deg, #7a4700 0%, #ad8100 71%, #c7b500 100%)}}html.theme--documenter-dark .hero.is-danger{background-color:#9e1b0d;color:#fff}html.theme--documenter-dark .hero.is-danger a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),html.theme--documenter-dark .hero.is-danger strong{color:inherit}html.theme--documenter-dark .hero.is-danger .title{color:#fff}html.theme--documenter-dark .hero.is-danger .subtitle{color:rgba(255,255,255,0.9)}html.theme--documenter-dark .hero.is-danger .subtitle a:not(.button),html.theme--documenter-dark .hero.is-danger .subtitle strong{color:#fff}@media screen and (max-width: 1055px){html.theme--documenter-dark .hero.is-danger .navbar-menu{background-color:#9e1b0d}}html.theme--documenter-dark .hero.is-danger .navbar-item,html.theme--documenter-dark .hero.is-danger .navbar-link{color:rgba(255,255,255,0.7)}html.theme--documenter-dark .hero.is-danger a.navbar-item:hover,html.theme--documenter-dark .hero.is-danger a.navbar-item.is-active,html.theme--documenter-dark .hero.is-danger .navbar-link:hover,html.theme--documenter-dark .hero.is-danger .navbar-link.is-active{background-color:#86170b;color:#fff}html.theme--documenter-dark .hero.is-danger .tabs a{color:#fff;opacity:0.9}html.theme--documenter-dark .hero.is-danger .tabs a:hover{opacity:1}html.theme--documenter-dark .hero.is-danger .tabs li.is-active a{color:#9e1b0d !important;opacity:1}html.theme--documenter-dark .hero.is-danger .tabs.is-boxed a,html.theme--documenter-dark .hero.is-danger .tabs.is-toggle a{color:#fff}html.theme--documenter-dark .hero.is-danger .tabs.is-boxed a:hover,html.theme--documenter-dark .hero.is-danger .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}html.theme--documenter-dark .hero.is-danger .tabs.is-boxed li.is-active a,html.theme--documenter-dark .hero.is-danger .tabs.is-boxed li.is-active a:hover,html.theme--documenter-dark .hero.is-danger .tabs.is-toggle li.is-active a,html.theme--documenter-dark .hero.is-danger .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#9e1b0d}html.theme--documenter-dark .hero.is-danger.is-bold{background-image:linear-gradient(141deg, #75030b 0%, #9e1b0d 71%, #ba380a 100%)}@media screen and (max-width: 768px){html.theme--documenter-dark .hero.is-danger.is-bold .navbar-menu{background-image:linear-gradient(141deg, #75030b 0%, #9e1b0d 71%, #ba380a 100%)}}html.theme--documenter-dark .hero.is-small .hero-body,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.hero .hero-body{padding:1.5rem}@media screen and (min-width: 769px),print{html.theme--documenter-dark .hero.is-medium .hero-body{padding:9rem 4.5rem}}@media screen and (min-width: 769px),print{html.theme--documenter-dark .hero.is-large .hero-body{padding:18rem 6rem}}html.theme--documenter-dark .hero.is-halfheight .hero-body,html.theme--documenter-dark .hero.is-fullheight .hero-body,html.theme--documenter-dark .hero.is-fullheight-with-navbar .hero-body{align-items:center;display:flex}html.theme--documenter-dark .hero.is-halfheight .hero-body>.container,html.theme--documenter-dark .hero.is-fullheight .hero-body>.container,html.theme--documenter-dark .hero.is-fullheight-with-navbar .hero-body>.container{flex-grow:1;flex-shrink:1}html.theme--documenter-dark .hero.is-halfheight{min-height:50vh}html.theme--documenter-dark .hero.is-fullheight{min-height:100vh}html.theme--documenter-dark .hero-video{overflow:hidden}html.theme--documenter-dark .hero-video video{left:50%;min-height:100%;min-width:100%;position:absolute;top:50%;transform:translate3d(-50%, -50%, 0)}html.theme--documenter-dark .hero-video.is-transparent{opacity:0.3}@media screen and (max-width: 768px){html.theme--documenter-dark .hero-video{display:none}}html.theme--documenter-dark .hero-buttons{margin-top:1.5rem}@media screen and (max-width: 768px){html.theme--documenter-dark .hero-buttons .button{display:flex}html.theme--documenter-dark .hero-buttons .button:not(:last-child){margin-bottom:0.75rem}}@media screen and (min-width: 769px),print{html.theme--documenter-dark .hero-buttons{display:flex;justify-content:center}html.theme--documenter-dark .hero-buttons .button:not(:last-child){margin-right:1.5rem}}html.theme--documenter-dark .hero-head,html.theme--documenter-dark .hero-foot{flex-grow:0;flex-shrink:0}html.theme--documenter-dark .hero-body{flex-grow:1;flex-shrink:0;padding:3rem 1.5rem}@media screen and (min-width: 769px),print{html.theme--documenter-dark .hero-body{padding:3rem 3rem}}html.theme--documenter-dark .section{padding:3rem 1.5rem}@media screen and (min-width: 1056px){html.theme--documenter-dark .section{padding:3rem 3rem}html.theme--documenter-dark .section.is-medium{padding:9rem 4.5rem}html.theme--documenter-dark .section.is-large{padding:18rem 6rem}}html.theme--documenter-dark .footer{background-color:#282f2f;padding:3rem 1.5rem 6rem}html.theme--documenter-dark hr{height:1px}html.theme--documenter-dark h6{text-transform:uppercase;letter-spacing:0.5px}html.theme--documenter-dark .hero{background-color:#343c3d}html.theme--documenter-dark a{transition:all 200ms ease}html.theme--documenter-dark .button{transition:all 200ms ease;border-width:1px;color:#fff}html.theme--documenter-dark .button.is-active,html.theme--documenter-dark .button.is-focused,html.theme--documenter-dark .button:active,html.theme--documenter-dark .button:focus{box-shadow:0 0 0 2px rgba(140,155,157,0.5)}html.theme--documenter-dark .button.is-white.is-hovered,html.theme--documenter-dark .button.is-white:hover{background-color:#fff}html.theme--documenter-dark .button.is-white.is-active,html.theme--documenter-dark .button.is-white.is-focused,html.theme--documenter-dark .button.is-white:active,html.theme--documenter-dark .button.is-white:focus{border-color:#fff;box-shadow:0 0 0 2px rgba(255,255,255,0.5)}html.theme--documenter-dark .button.is-black.is-hovered,html.theme--documenter-dark .button.is-black:hover{background-color:#1d1d1d}html.theme--documenter-dark .button.is-black.is-active,html.theme--documenter-dark .button.is-black.is-focused,html.theme--documenter-dark .button.is-black:active,html.theme--documenter-dark .button.is-black:focus{border-color:#0a0a0a;box-shadow:0 0 0 2px rgba(10,10,10,0.5)}html.theme--documenter-dark .button.is-light.is-hovered,html.theme--documenter-dark .button.is-light:hover{background-color:#fff}html.theme--documenter-dark .button.is-light.is-active,html.theme--documenter-dark .button.is-light.is-focused,html.theme--documenter-dark .button.is-light:active,html.theme--documenter-dark .button.is-light:focus{border-color:#ecf0f1;box-shadow:0 0 0 2px rgba(236,240,241,0.5)}html.theme--documenter-dark .button.is-dark.is-hovered,html.theme--documenter-dark .content kbd.button.is-hovered,html.theme--documenter-dark .button.is-dark:hover,html.theme--documenter-dark .content kbd.button:hover{background-color:#3a4344}html.theme--documenter-dark .button.is-dark.is-active,html.theme--documenter-dark .content kbd.button.is-active,html.theme--documenter-dark .button.is-dark.is-focused,html.theme--documenter-dark .content kbd.button.is-focused,html.theme--documenter-dark .button.is-dark:active,html.theme--documenter-dark .content kbd.button:active,html.theme--documenter-dark .button.is-dark:focus,html.theme--documenter-dark .content kbd.button:focus{border-color:#282f2f;box-shadow:0 0 0 2px rgba(40,47,47,0.5)}html.theme--documenter-dark .button.is-primary.is-hovered,html.theme--documenter-dark .docstring>section>a.button.is-hovered.docs-sourcelink,html.theme--documenter-dark .button.is-primary:hover,html.theme--documenter-dark .docstring>section>a.button.docs-sourcelink:hover{background-color:#436d9a}html.theme--documenter-dark .button.is-primary.is-active,html.theme--documenter-dark .docstring>section>a.button.is-active.docs-sourcelink,html.theme--documenter-dark .button.is-primary.is-focused,html.theme--documenter-dark .docstring>section>a.button.is-focused.docs-sourcelink,html.theme--documenter-dark .button.is-primary:active,html.theme--documenter-dark .docstring>section>a.button.docs-sourcelink:active,html.theme--documenter-dark .button.is-primary:focus,html.theme--documenter-dark .docstring>section>a.button.docs-sourcelink:focus{border-color:#375a7f;box-shadow:0 0 0 2px rgba(55,90,127,0.5)}html.theme--documenter-dark .button.is-link.is-hovered,html.theme--documenter-dark .button.is-link:hover{background-color:#1fdeb8}html.theme--documenter-dark .button.is-link.is-active,html.theme--documenter-dark .button.is-link.is-focused,html.theme--documenter-dark .button.is-link:active,html.theme--documenter-dark .button.is-link:focus{border-color:#1abc9c;box-shadow:0 0 0 2px rgba(26,188,156,0.5)}html.theme--documenter-dark .button.is-info.is-hovered,html.theme--documenter-dark .button.is-info:hover{background-color:#0363a3}html.theme--documenter-dark .button.is-info.is-active,html.theme--documenter-dark .button.is-info.is-focused,html.theme--documenter-dark .button.is-info:active,html.theme--documenter-dark .button.is-info:focus{border-color:#024c7d;box-shadow:0 0 0 2px rgba(2,76,125,0.5)}html.theme--documenter-dark .button.is-success.is-hovered,html.theme--documenter-dark .button.is-success:hover{background-color:#00aa48}html.theme--documenter-dark .button.is-success.is-active,html.theme--documenter-dark .button.is-success.is-focused,html.theme--documenter-dark .button.is-success:active,html.theme--documenter-dark .button.is-success:focus{border-color:#008438;box-shadow:0 0 0 2px rgba(0,132,56,0.5)}html.theme--documenter-dark .button.is-warning.is-hovered,html.theme--documenter-dark .button.is-warning:hover{background-color:#d39e00}html.theme--documenter-dark .button.is-warning.is-active,html.theme--documenter-dark .button.is-warning.is-focused,html.theme--documenter-dark .button.is-warning:active,html.theme--documenter-dark .button.is-warning:focus{border-color:#ad8100;box-shadow:0 0 0 2px rgba(173,129,0,0.5)}html.theme--documenter-dark .button.is-danger.is-hovered,html.theme--documenter-dark .button.is-danger:hover{background-color:#c12110}html.theme--documenter-dark .button.is-danger.is-active,html.theme--documenter-dark .button.is-danger.is-focused,html.theme--documenter-dark .button.is-danger:active,html.theme--documenter-dark .button.is-danger:focus{border-color:#9e1b0d;box-shadow:0 0 0 2px rgba(158,27,13,0.5)}html.theme--documenter-dark .label{color:#dbdee0}html.theme--documenter-dark .button,html.theme--documenter-dark .control.has-icons-left .icon,html.theme--documenter-dark .control.has-icons-right .icon,html.theme--documenter-dark .input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input,html.theme--documenter-dark .pagination-ellipsis,html.theme--documenter-dark .pagination-link,html.theme--documenter-dark .pagination-next,html.theme--documenter-dark .pagination-previous,html.theme--documenter-dark .select,html.theme--documenter-dark .select select,html.theme--documenter-dark .textarea{height:2.5em}html.theme--documenter-dark .input,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input,html.theme--documenter-dark .textarea{transition:all 200ms ease;box-shadow:none;border-width:1px;padding-left:1em;padding-right:1em}html.theme--documenter-dark .select:after,html.theme--documenter-dark .select select{border-width:1px}html.theme--documenter-dark .control.has-addons .button,html.theme--documenter-dark .control.has-addons .input,html.theme--documenter-dark .control.has-addons #documenter .docs-sidebar form.docs-search>input,html.theme--documenter-dark #documenter .docs-sidebar .control.has-addons form.docs-search>input,html.theme--documenter-dark .control.has-addons .select{margin-right:-1px}html.theme--documenter-dark .notification{background-color:#343c3d}html.theme--documenter-dark .card{box-shadow:none;border:1px solid #343c3d;background-color:#282f2f;border-radius:.4em}html.theme--documenter-dark .card .card-image img{border-radius:.4em .4em 0 0}html.theme--documenter-dark .card .card-header{box-shadow:none;background-color:rgba(18,18,18,0.2);border-radius:.4em .4em 0 0}html.theme--documenter-dark .card .card-footer{background-color:rgba(18,18,18,0.2)}html.theme--documenter-dark .card .card-footer,html.theme--documenter-dark .card .card-footer-item{border-width:1px;border-color:#343c3d}html.theme--documenter-dark .notification.is-white a:not(.button){color:#0a0a0a;text-decoration:underline}html.theme--documenter-dark .notification.is-black a:not(.button){color:#fff;text-decoration:underline}html.theme--documenter-dark .notification.is-light a:not(.button){color:rgba(0,0,0,0.7);text-decoration:underline}html.theme--documenter-dark .notification.is-dark a:not(.button),html.theme--documenter-dark .content kbd.notification a:not(.button){color:#fff;text-decoration:underline}html.theme--documenter-dark .notification.is-primary a:not(.button),html.theme--documenter-dark .docstring>section>a.notification.docs-sourcelink a:not(.button){color:#fff;text-decoration:underline}html.theme--documenter-dark .notification.is-link a:not(.button){color:#fff;text-decoration:underline}html.theme--documenter-dark .notification.is-info a:not(.button){color:#fff;text-decoration:underline}html.theme--documenter-dark .notification.is-success a:not(.button){color:#fff;text-decoration:underline}html.theme--documenter-dark .notification.is-warning a:not(.button){color:#fff;text-decoration:underline}html.theme--documenter-dark .notification.is-danger a:not(.button){color:#fff;text-decoration:underline}html.theme--documenter-dark .tag,html.theme--documenter-dark .content kbd,html.theme--documenter-dark .docstring>section>a.docs-sourcelink{border-radius:.4em}html.theme--documenter-dark .menu-list a{transition:all 300ms ease}html.theme--documenter-dark .modal-card-body{background-color:#282f2f}html.theme--documenter-dark .modal-card-foot,html.theme--documenter-dark .modal-card-head{border-color:#343c3d}html.theme--documenter-dark .message-header{font-weight:700;background-color:#343c3d;color:#fff}html.theme--documenter-dark .message-body{border-width:1px;border-color:#343c3d}html.theme--documenter-dark .navbar{border-radius:.4em}html.theme--documenter-dark .navbar.is-transparent{background:none}html.theme--documenter-dark .navbar.is-primary .navbar-dropdown a.navbar-item.is-active,html.theme--documenter-dark .docstring>section>a.navbar.docs-sourcelink .navbar-dropdown a.navbar-item.is-active{background-color:#1abc9c}@media screen and (max-width: 1055px){html.theme--documenter-dark .navbar .navbar-menu{background-color:#375a7f;border-radius:0 0 .4em .4em}}html.theme--documenter-dark .hero .navbar,html.theme--documenter-dark body>.navbar{border-radius:0}html.theme--documenter-dark .pagination-link,html.theme--documenter-dark .pagination-next,html.theme--documenter-dark .pagination-previous{border-width:1px}html.theme--documenter-dark .panel-block,html.theme--documenter-dark .panel-heading,html.theme--documenter-dark .panel-tabs{border-width:1px}html.theme--documenter-dark .panel-block:first-child,html.theme--documenter-dark .panel-heading:first-child,html.theme--documenter-dark .panel-tabs:first-child{border-top-width:1px}html.theme--documenter-dark .panel-heading{font-weight:700}html.theme--documenter-dark .panel-tabs a{border-width:1px;margin-bottom:-1px}html.theme--documenter-dark .panel-tabs a.is-active{border-bottom-color:#17a689}html.theme--documenter-dark .panel-block:hover{color:#1dd2af}html.theme--documenter-dark .panel-block:hover .panel-icon{color:#1dd2af}html.theme--documenter-dark .panel-block.is-active .panel-icon{color:#17a689}html.theme--documenter-dark .tabs a{border-bottom-width:1px;margin-bottom:-1px}html.theme--documenter-dark .tabs ul{border-bottom-width:1px}html.theme--documenter-dark .tabs.is-boxed a{border-width:1px}html.theme--documenter-dark .tabs.is-boxed li.is-active a{background-color:#1f2424}html.theme--documenter-dark .tabs.is-toggle li a{border-width:1px;margin-bottom:0}html.theme--documenter-dark .tabs.is-toggle li+li{margin-left:-1px}html.theme--documenter-dark .hero.is-white .navbar .navbar-dropdown .navbar-item:hover{background-color:rgba(0,0,0,0)}html.theme--documenter-dark .hero.is-black .navbar .navbar-dropdown .navbar-item:hover{background-color:rgba(0,0,0,0)}html.theme--documenter-dark .hero.is-light .navbar .navbar-dropdown .navbar-item:hover{background-color:rgba(0,0,0,0)}html.theme--documenter-dark .hero.is-dark .navbar .navbar-dropdown .navbar-item:hover,html.theme--documenter-dark .content kbd.hero .navbar .navbar-dropdown .navbar-item:hover{background-color:rgba(0,0,0,0)}html.theme--documenter-dark .hero.is-primary .navbar .navbar-dropdown .navbar-item:hover,html.theme--documenter-dark .docstring>section>a.hero.docs-sourcelink .navbar .navbar-dropdown .navbar-item:hover{background-color:rgba(0,0,0,0)}html.theme--documenter-dark .hero.is-link .navbar .navbar-dropdown .navbar-item:hover{background-color:rgba(0,0,0,0)}html.theme--documenter-dark .hero.is-info .navbar .navbar-dropdown .navbar-item:hover{background-color:rgba(0,0,0,0)}html.theme--documenter-dark .hero.is-success .navbar .navbar-dropdown .navbar-item:hover{background-color:rgba(0,0,0,0)}html.theme--documenter-dark .hero.is-warning .navbar .navbar-dropdown .navbar-item:hover{background-color:rgba(0,0,0,0)}html.theme--documenter-dark .hero.is-danger .navbar .navbar-dropdown .navbar-item:hover{background-color:rgba(0,0,0,0)}html.theme--documenter-dark h1 .docs-heading-anchor,html.theme--documenter-dark h1 .docs-heading-anchor:hover,html.theme--documenter-dark h1 .docs-heading-anchor:visited,html.theme--documenter-dark h2 .docs-heading-anchor,html.theme--documenter-dark h2 .docs-heading-anchor:hover,html.theme--documenter-dark h2 .docs-heading-anchor:visited,html.theme--documenter-dark h3 .docs-heading-anchor,html.theme--documenter-dark h3 .docs-heading-anchor:hover,html.theme--documenter-dark h3 .docs-heading-anchor:visited,html.theme--documenter-dark h4 .docs-heading-anchor,html.theme--documenter-dark h4 .docs-heading-anchor:hover,html.theme--documenter-dark h4 .docs-heading-anchor:visited,html.theme--documenter-dark h5 .docs-heading-anchor,html.theme--documenter-dark h5 .docs-heading-anchor:hover,html.theme--documenter-dark h5 .docs-heading-anchor:visited,html.theme--documenter-dark h6 .docs-heading-anchor,html.theme--documenter-dark h6 .docs-heading-anchor:hover,html.theme--documenter-dark h6 .docs-heading-anchor:visited{color:#f2f2f2}html.theme--documenter-dark h1 .docs-heading-anchor-permalink,html.theme--documenter-dark h2 .docs-heading-anchor-permalink,html.theme--documenter-dark h3 .docs-heading-anchor-permalink,html.theme--documenter-dark h4 .docs-heading-anchor-permalink,html.theme--documenter-dark h5 .docs-heading-anchor-permalink,html.theme--documenter-dark h6 .docs-heading-anchor-permalink{visibility:hidden;vertical-align:middle;margin-left:0.5em;font-size:0.7rem}html.theme--documenter-dark h1 .docs-heading-anchor-permalink::before,html.theme--documenter-dark h2 .docs-heading-anchor-permalink::before,html.theme--documenter-dark h3 .docs-heading-anchor-permalink::before,html.theme--documenter-dark h4 .docs-heading-anchor-permalink::before,html.theme--documenter-dark h5 .docs-heading-anchor-permalink::before,html.theme--documenter-dark h6 .docs-heading-anchor-permalink::before{font-family:"Font Awesome 6 Free";font-weight:900;content:"\f0c1"}html.theme--documenter-dark h1:hover .docs-heading-anchor-permalink,html.theme--documenter-dark h2:hover .docs-heading-anchor-permalink,html.theme--documenter-dark h3:hover .docs-heading-anchor-permalink,html.theme--documenter-dark h4:hover .docs-heading-anchor-permalink,html.theme--documenter-dark h5:hover .docs-heading-anchor-permalink,html.theme--documenter-dark h6:hover .docs-heading-anchor-permalink{visibility:visible}html.theme--documenter-dark .docs-light-only{display:none !important}html.theme--documenter-dark pre{position:relative;overflow:hidden}html.theme--documenter-dark pre code,html.theme--documenter-dark pre code.hljs{padding:0 .75rem !important;overflow:auto;display:block}html.theme--documenter-dark pre code:first-of-type,html.theme--documenter-dark pre code.hljs:first-of-type{padding-top:0.5rem !important}html.theme--documenter-dark pre code:last-of-type,html.theme--documenter-dark pre code.hljs:last-of-type{padding-bottom:0.5rem !important}html.theme--documenter-dark pre .copy-button{opacity:0.2;transition:opacity 0.2s;position:absolute;right:0em;top:0em;padding:0.5em;width:2.5em;height:2.5em;background:transparent;border:none;font-family:"Font Awesome 6 Free";color:#fff;cursor:pointer;text-align:center}html.theme--documenter-dark pre .copy-button:focus,html.theme--documenter-dark pre .copy-button:hover{opacity:1;background:rgba(255,255,255,0.1);color:#1abc9c}html.theme--documenter-dark pre .copy-button.success{color:#259a12;opacity:1}html.theme--documenter-dark pre .copy-button.error{color:#cb3c33;opacity:1}html.theme--documenter-dark pre:hover .copy-button{opacity:1}html.theme--documenter-dark .admonition{background-color:#282f2f;border-style:solid;border-width:1px;border-color:#5e6d6f;border-radius:.4em;font-size:1rem}html.theme--documenter-dark .admonition strong{color:currentColor}html.theme--documenter-dark .admonition.is-small,html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input.admonition{font-size:.75rem}html.theme--documenter-dark .admonition.is-medium{font-size:1.25rem}html.theme--documenter-dark .admonition.is-large{font-size:1.5rem}html.theme--documenter-dark .admonition.is-default{background-color:#282f2f;border-color:#5e6d6f}html.theme--documenter-dark .admonition.is-default>.admonition-header{background-color:#5e6d6f;color:#fff}html.theme--documenter-dark .admonition.is-default>.admonition-body{color:#fff}html.theme--documenter-dark .admonition.is-info{background-color:#282f2f;border-color:#024c7d}html.theme--documenter-dark .admonition.is-info>.admonition-header{background-color:#024c7d;color:#fff}html.theme--documenter-dark .admonition.is-info>.admonition-body{color:#fff}html.theme--documenter-dark .admonition.is-success{background-color:#282f2f;border-color:#008438}html.theme--documenter-dark .admonition.is-success>.admonition-header{background-color:#008438;color:#fff}html.theme--documenter-dark .admonition.is-success>.admonition-body{color:#fff}html.theme--documenter-dark .admonition.is-warning{background-color:#282f2f;border-color:#ad8100}html.theme--documenter-dark .admonition.is-warning>.admonition-header{background-color:#ad8100;color:#fff}html.theme--documenter-dark .admonition.is-warning>.admonition-body{color:#fff}html.theme--documenter-dark .admonition.is-danger{background-color:#282f2f;border-color:#9e1b0d}html.theme--documenter-dark .admonition.is-danger>.admonition-header{background-color:#9e1b0d;color:#fff}html.theme--documenter-dark .admonition.is-danger>.admonition-body{color:#fff}html.theme--documenter-dark .admonition.is-compat{background-color:#282f2f;border-color:#137886}html.theme--documenter-dark .admonition.is-compat>.admonition-header{background-color:#137886;color:#fff}html.theme--documenter-dark .admonition.is-compat>.admonition-body{color:#fff}html.theme--documenter-dark .admonition-header{color:#fff;background-color:#5e6d6f;align-items:center;font-weight:700;justify-content:space-between;line-height:1.25;padding:0.5rem .75rem;position:relative}html.theme--documenter-dark .admonition-header:before{font-family:"Font Awesome 6 Free";font-weight:900;margin-right:.75rem;content:"\f06a"}html.theme--documenter-dark details.admonition.is-details>.admonition-header{list-style:none}html.theme--documenter-dark details.admonition.is-details>.admonition-header:before{font-family:"Font Awesome 6 Free";font-weight:900;content:"\f055"}html.theme--documenter-dark details.admonition.is-details[open]>.admonition-header:before{font-family:"Font Awesome 6 Free";font-weight:900;content:"\f056"}html.theme--documenter-dark .admonition-body{color:#fff;padding:0.5rem .75rem}html.theme--documenter-dark .admonition-body pre{background-color:#282f2f}html.theme--documenter-dark .admonition-body code{background-color:rgba(255,255,255,0.05)}html.theme--documenter-dark .docstring{margin-bottom:1em;background-color:rgba(0,0,0,0);border:1px solid #5e6d6f;box-shadow:none;max-width:100%}html.theme--documenter-dark .docstring>header{cursor:pointer;display:flex;flex-grow:1;align-items:stretch;padding:0.5rem .75rem;background-color:#282f2f;box-shadow:0 0.125em 0.25em rgba(10,10,10,0.1);box-shadow:none;border-bottom:1px solid #5e6d6f;overflow:auto}html.theme--documenter-dark .docstring>header code{background-color:transparent}html.theme--documenter-dark .docstring>header .docstring-article-toggle-button{min-width:1.1rem;padding:0.2rem 0.2rem 0.2rem 0}html.theme--documenter-dark .docstring>header .docstring-binding{margin-right:0.3em}html.theme--documenter-dark .docstring>header .docstring-category{margin-left:0.3em}html.theme--documenter-dark .docstring>section{position:relative;padding:.75rem .75rem;border-bottom:1px solid #5e6d6f}html.theme--documenter-dark .docstring>section:last-child{border-bottom:none}html.theme--documenter-dark .docstring>section>a.docs-sourcelink{transition:opacity 0.3s;opacity:0;position:absolute;right:.375rem;bottom:.375rem}html.theme--documenter-dark .docstring>section>a.docs-sourcelink:focus{opacity:1 !important}html.theme--documenter-dark .docstring:hover>section>a.docs-sourcelink{opacity:0.2}html.theme--documenter-dark .docstring:focus-within>section>a.docs-sourcelink{opacity:0.2}html.theme--documenter-dark .docstring>section:hover a.docs-sourcelink{opacity:1}html.theme--documenter-dark .documenter-example-output{background-color:#1f2424}html.theme--documenter-dark .outdated-warning-overlay{position:fixed;top:0;left:0;right:0;box-shadow:0 0 10px rgba(0,0,0,0.3);z-index:999;background-color:#282f2f;color:#fff;border-bottom:3px solid #9e1b0d;padding:10px 35px;text-align:center;font-size:15px}html.theme--documenter-dark .outdated-warning-overlay .outdated-warning-closer{position:absolute;top:calc(50% - 10px);right:18px;cursor:pointer;width:12px}html.theme--documenter-dark .outdated-warning-overlay a{color:#1abc9c}html.theme--documenter-dark .outdated-warning-overlay a:hover{color:#1dd2af}html.theme--documenter-dark .content pre{border:1px solid #5e6d6f}html.theme--documenter-dark .content code{font-weight:inherit}html.theme--documenter-dark .content a code{color:#1abc9c}html.theme--documenter-dark .content h1 code,html.theme--documenter-dark .content h2 code,html.theme--documenter-dark .content h3 code,html.theme--documenter-dark .content h4 code,html.theme--documenter-dark .content h5 code,html.theme--documenter-dark .content h6 code{color:#f2f2f2}html.theme--documenter-dark .content table{display:block;width:initial;max-width:100%;overflow-x:auto}html.theme--documenter-dark .content blockquote>ul:first-child,html.theme--documenter-dark .content blockquote>ol:first-child,html.theme--documenter-dark .content .admonition-body>ul:first-child,html.theme--documenter-dark .content .admonition-body>ol:first-child{margin-top:0}html.theme--documenter-dark pre,html.theme--documenter-dark code{font-variant-ligatures:no-contextual}html.theme--documenter-dark .breadcrumb a.is-disabled{cursor:default;pointer-events:none}html.theme--documenter-dark .breadcrumb a.is-disabled,html.theme--documenter-dark .breadcrumb a.is-disabled:hover{color:#f2f2f2}html.theme--documenter-dark .hljs{background:initial !important}html.theme--documenter-dark .katex .katex-mathml{top:0;right:0}html.theme--documenter-dark .katex-display,html.theme--documenter-dark mjx-container,html.theme--documenter-dark .MathJax_Display{margin:0.5em 0 !important}html.theme--documenter-dark html{-moz-osx-font-smoothing:auto;-webkit-font-smoothing:auto}html.theme--documenter-dark li.no-marker{list-style:none}html.theme--documenter-dark #documenter .docs-main>article{overflow-wrap:break-word}html.theme--documenter-dark #documenter .docs-main>article .math-container{overflow-x:auto;overflow-y:hidden}@media screen and (min-width: 1056px){html.theme--documenter-dark #documenter .docs-main{max-width:52rem;margin-left:20rem;padding-right:1rem}}@media screen and (max-width: 1055px){html.theme--documenter-dark #documenter .docs-main{width:100%}html.theme--documenter-dark #documenter .docs-main>article{max-width:52rem;margin-left:auto;margin-right:auto;margin-bottom:1rem;padding:0 1rem}html.theme--documenter-dark #documenter .docs-main>header,html.theme--documenter-dark #documenter .docs-main>nav{max-width:100%;width:100%;margin:0}}html.theme--documenter-dark #documenter .docs-main header.docs-navbar{background-color:#1f2424;border-bottom:1px solid #5e6d6f;z-index:2;min-height:4rem;margin-bottom:1rem;display:flex}html.theme--documenter-dark #documenter .docs-main header.docs-navbar .breadcrumb{flex-grow:1;overflow-x:hidden}html.theme--documenter-dark #documenter .docs-main header.docs-navbar .docs-sidebar-button{display:block;font-size:1.5rem;padding-bottom:0.1rem;margin-right:1rem}html.theme--documenter-dark #documenter .docs-main header.docs-navbar .docs-right{display:flex;white-space:nowrap;gap:1rem;align-items:center}html.theme--documenter-dark #documenter .docs-main header.docs-navbar .docs-right .docs-icon,html.theme--documenter-dark #documenter .docs-main header.docs-navbar .docs-right .docs-label{display:inline-block}html.theme--documenter-dark #documenter .docs-main header.docs-navbar .docs-right .docs-label{padding:0;margin-left:0.3em}@media screen and (max-width: 1055px){html.theme--documenter-dark #documenter .docs-main header.docs-navbar .docs-right .docs-navbar-link{margin-left:0.4rem;margin-right:0.4rem}}html.theme--documenter-dark #documenter .docs-main header.docs-navbar>*{margin:auto 0}@media screen and (max-width: 1055px){html.theme--documenter-dark #documenter .docs-main header.docs-navbar{position:sticky;top:0;padding:0 1rem;transition-property:top, box-shadow;-webkit-transition-property:top, box-shadow;transition-duration:0.3s;-webkit-transition-duration:0.3s}html.theme--documenter-dark #documenter .docs-main header.docs-navbar.headroom--not-top{box-shadow:.2rem 0rem .4rem #171717;transition-duration:0.7s;-webkit-transition-duration:0.7s}html.theme--documenter-dark #documenter .docs-main header.docs-navbar.headroom--unpinned.headroom--not-top.headroom--not-bottom{top:-4.5rem;transition-duration:0.7s;-webkit-transition-duration:0.7s}}html.theme--documenter-dark #documenter .docs-main section.footnotes{border-top:1px solid #5e6d6f}html.theme--documenter-dark #documenter .docs-main section.footnotes li .tag:first-child,html.theme--documenter-dark #documenter .docs-main section.footnotes li .docstring>section>a.docs-sourcelink:first-child,html.theme--documenter-dark #documenter .docs-main section.footnotes li .content kbd:first-child,html.theme--documenter-dark .content #documenter .docs-main section.footnotes li kbd:first-child{margin-right:1em;margin-bottom:0.4em}html.theme--documenter-dark #documenter .docs-main .docs-footer{display:flex;flex-wrap:wrap;margin-left:0;margin-right:0;border-top:1px solid #5e6d6f;padding-top:1rem;padding-bottom:1rem}@media screen and (max-width: 1055px){html.theme--documenter-dark #documenter .docs-main .docs-footer{padding-left:1rem;padding-right:1rem}}html.theme--documenter-dark #documenter .docs-main .docs-footer .docs-footer-nextpage,html.theme--documenter-dark #documenter .docs-main .docs-footer .docs-footer-prevpage{flex-grow:1}html.theme--documenter-dark #documenter .docs-main .docs-footer .docs-footer-nextpage{text-align:right}html.theme--documenter-dark #documenter .docs-main .docs-footer .flexbox-break{flex-basis:100%;height:0}html.theme--documenter-dark #documenter .docs-main .docs-footer .footer-message{font-size:0.8em;margin:0.5em auto 0 auto;text-align:center}html.theme--documenter-dark #documenter .docs-sidebar{display:flex;flex-direction:column;color:#fff;background-color:#282f2f;border-right:1px solid #5e6d6f;padding:0;flex:0 0 18rem;z-index:5;font-size:1rem;position:fixed;left:-18rem;width:18rem;height:100%;transition:left 0.3s}html.theme--documenter-dark #documenter .docs-sidebar.visible{left:0;box-shadow:.4rem 0rem .8rem #171717}@media screen and (min-width: 1056px){html.theme--documenter-dark #documenter .docs-sidebar.visible{box-shadow:none}}@media screen and (min-width: 1056px){html.theme--documenter-dark #documenter .docs-sidebar{left:0;top:0}}html.theme--documenter-dark #documenter .docs-sidebar .docs-logo{margin-top:1rem;padding:0 1rem}html.theme--documenter-dark #documenter .docs-sidebar .docs-logo>img{max-height:6rem;margin:auto}html.theme--documenter-dark #documenter .docs-sidebar .docs-package-name{flex-shrink:0;font-size:1.5rem;font-weight:700;text-align:center;white-space:nowrap;overflow:hidden;padding:0.5rem 0}html.theme--documenter-dark #documenter .docs-sidebar .docs-package-name .docs-autofit{max-width:16.2rem}html.theme--documenter-dark #documenter .docs-sidebar .docs-package-name a,html.theme--documenter-dark #documenter .docs-sidebar .docs-package-name a:hover{color:#fff}html.theme--documenter-dark #documenter .docs-sidebar .docs-version-selector{border-top:1px solid #5e6d6f;display:none;padding:0.5rem}html.theme--documenter-dark #documenter .docs-sidebar .docs-version-selector.visible{display:flex}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu{flex-grow:1;user-select:none;border-top:1px solid #5e6d6f;padding-bottom:1.5rem}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu>li>.tocitem{font-weight:bold}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu>li li{font-size:.95rem;margin-left:1em;border-left:1px solid #5e6d6f}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu input.collapse-toggle{display:none}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu ul.collapsed{display:none}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu input:checked~ul.collapsed{display:block}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu label.tocitem{display:flex}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu label.tocitem .docs-label{flex-grow:2}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu label.tocitem .docs-chevron{display:inline-block;font-style:normal;font-variant:normal;text-rendering:auto;line-height:1;font-size:.75rem;margin-left:1rem;margin-top:auto;margin-bottom:auto}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu label.tocitem .docs-chevron::before{font-family:"Font Awesome 6 Free";font-weight:900;content:"\f054"}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu input:checked~label.tocitem .docs-chevron::before{content:"\f078"}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu .tocitem{display:block;padding:0.5rem 0.5rem}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu .tocitem,html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu .tocitem:hover{color:#fff;background:#282f2f}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu a.tocitem:hover,html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu label.tocitem:hover{color:#fff;background-color:#32393a}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu li.is-active{border-top:1px solid #5e6d6f;border-bottom:1px solid #5e6d6f;background-color:#1f2424}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu li.is-active .tocitem,html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu li.is-active .tocitem:hover{background-color:#1f2424;color:#fff}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu li.is-active ul.internal .tocitem:hover{background-color:#32393a;color:#fff}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu>li.is-active:first-child{border-top:none}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu ul.internal{margin:0 0.5rem 0.5rem;border-top:1px solid #5e6d6f}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu ul.internal li{font-size:.85rem;border-left:none;margin-left:0;margin-top:0.5rem}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu ul.internal .tocitem{width:100%;padding:0}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu ul.internal .tocitem::before{content:"⚬";margin-right:0.4em}html.theme--documenter-dark #documenter .docs-sidebar form.docs-search{margin:auto;margin-top:0.5rem;margin-bottom:0.5rem}html.theme--documenter-dark #documenter .docs-sidebar form.docs-search>input{width:14.4rem}html.theme--documenter-dark #documenter .docs-sidebar #documenter-search-query{color:#868c98;width:14.4rem;box-shadow:inset 0 1px 2px rgba(10,10,10,0.1)}@media screen and (min-width: 1056px){html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu{overflow-y:auto;-webkit-overflow-scroll:touch}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu::-webkit-scrollbar{width:.3rem;background:none}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu::-webkit-scrollbar-thumb{border-radius:5px 0px 0px 5px;background:#3b4445}html.theme--documenter-dark #documenter .docs-sidebar ul.docs-menu::-webkit-scrollbar-thumb:hover{background:#4e5a5c}}@media screen and (max-width: 1055px){html.theme--documenter-dark #documenter .docs-sidebar{overflow-y:auto;-webkit-overflow-scroll:touch}html.theme--documenter-dark #documenter .docs-sidebar::-webkit-scrollbar{width:.3rem;background:none}html.theme--documenter-dark #documenter .docs-sidebar::-webkit-scrollbar-thumb{border-radius:5px 0px 0px 5px;background:#3b4445}html.theme--documenter-dark #documenter .docs-sidebar::-webkit-scrollbar-thumb:hover{background:#4e5a5c}}html.theme--documenter-dark kbd.search-modal-key-hints{border-radius:0.25rem;border:1px solid rgba(245,245,245,0.6);box-shadow:0 2px 0 1px rgba(245,245,245,0.6);cursor:default;font-size:0.9rem;line-height:1.5;min-width:0.75rem;text-align:center;padding:0.1rem 0.3rem;position:relative;top:-1px}html.theme--documenter-dark .search-min-width-50{min-width:50%}html.theme--documenter-dark .search-min-height-100{min-height:100%}html.theme--documenter-dark .search-modal-card-body{max-height:calc(100vh - 15rem)}html.theme--documenter-dark .search-result-link{border-radius:0.7em;transition:all 300ms}html.theme--documenter-dark .search-result-link:hover,html.theme--documenter-dark .search-result-link:focus{background-color:rgba(0,128,128,0.1)}html.theme--documenter-dark .search-result-link .property-search-result-badge,html.theme--documenter-dark .search-result-link .search-filter{transition:all 300ms}html.theme--documenter-dark .property-search-result-badge,html.theme--documenter-dark .search-filter{padding:0.15em 0.5em;font-size:0.8em;font-style:italic;text-transform:none !important;line-height:1.5;color:#f5f5f5;background-color:rgba(51,65,85,0.501961);border-radius:0.6rem}html.theme--documenter-dark .search-result-link:hover .property-search-result-badge,html.theme--documenter-dark .search-result-link:hover .search-filter,html.theme--documenter-dark .search-result-link:focus .property-search-result-badge,html.theme--documenter-dark .search-result-link:focus .search-filter{color:#333;background-color:#f1f5f9}html.theme--documenter-dark .search-filter{color:#333;background-color:#f5f5f5;transition:all 300ms}html.theme--documenter-dark .search-filter:hover,html.theme--documenter-dark .search-filter:focus{color:#333}html.theme--documenter-dark .search-filter-selected{color:#f5f5f5;background-color:rgba(139,0,139,0.5)}html.theme--documenter-dark .search-filter-selected:hover,html.theme--documenter-dark .search-filter-selected:focus{color:#f5f5f5}html.theme--documenter-dark .search-result-highlight{background-color:#ffdd57;color:black}html.theme--documenter-dark .search-divider{border-bottom:1px solid #5e6d6f}html.theme--documenter-dark .search-result-title{width:85%;color:#f5f5f5}html.theme--documenter-dark .search-result-code-title{font-size:0.875rem;font-family:"JuliaMono","SFMono-Regular","Menlo","Consolas","Liberation Mono","DejaVu Sans Mono",monospace}html.theme--documenter-dark #search-modal .modal-card-body::-webkit-scrollbar,html.theme--documenter-dark #search-modal .filter-tabs::-webkit-scrollbar{height:10px;width:10px;background-color:transparent}html.theme--documenter-dark #search-modal .modal-card-body::-webkit-scrollbar-thumb,html.theme--documenter-dark #search-modal .filter-tabs::-webkit-scrollbar-thumb{background-color:gray;border-radius:1rem}html.theme--documenter-dark #search-modal .modal-card-body::-webkit-scrollbar-track,html.theme--documenter-dark #search-modal .filter-tabs::-webkit-scrollbar-track{-webkit-box-shadow:inset 0 0 6px rgba(0,0,0,0.6);background-color:transparent}html.theme--documenter-dark .w-100{width:100%}html.theme--documenter-dark .gap-2{gap:0.5rem}html.theme--documenter-dark .gap-4{gap:1rem}html.theme--documenter-dark .gap-8{gap:2rem}html.theme--documenter-dark{background-color:#1f2424;font-size:16px;min-width:300px;overflow-x:auto;overflow-y:scroll;text-rendering:optimizeLegibility;text-size-adjust:100%}html.theme--documenter-dark .ansi span.sgr1{font-weight:bolder}html.theme--documenter-dark .ansi span.sgr2{font-weight:lighter}html.theme--documenter-dark .ansi span.sgr3{font-style:italic}html.theme--documenter-dark .ansi span.sgr4{text-decoration:underline}html.theme--documenter-dark .ansi span.sgr7{color:#1f2424;background-color:#fff}html.theme--documenter-dark .ansi span.sgr8{color:transparent}html.theme--documenter-dark .ansi span.sgr8 span{color:transparent}html.theme--documenter-dark .ansi span.sgr9{text-decoration:line-through}html.theme--documenter-dark .ansi span.sgr30{color:#242424}html.theme--documenter-dark .ansi span.sgr31{color:#f6705f}html.theme--documenter-dark .ansi span.sgr32{color:#4fb43a}html.theme--documenter-dark .ansi span.sgr33{color:#f4c72f}html.theme--documenter-dark .ansi span.sgr34{color:#7587f0}html.theme--documenter-dark .ansi span.sgr35{color:#bc89d3}html.theme--documenter-dark .ansi span.sgr36{color:#49b6ca}html.theme--documenter-dark .ansi span.sgr37{color:#b3bdbe}html.theme--documenter-dark .ansi span.sgr40{background-color:#242424}html.theme--documenter-dark .ansi span.sgr41{background-color:#f6705f}html.theme--documenter-dark .ansi span.sgr42{background-color:#4fb43a}html.theme--documenter-dark .ansi span.sgr43{background-color:#f4c72f}html.theme--documenter-dark .ansi span.sgr44{background-color:#7587f0}html.theme--documenter-dark .ansi span.sgr45{background-color:#bc89d3}html.theme--documenter-dark .ansi span.sgr46{background-color:#49b6ca}html.theme--documenter-dark .ansi span.sgr47{background-color:#b3bdbe}html.theme--documenter-dark .ansi span.sgr90{color:#92a0a2}html.theme--documenter-dark .ansi span.sgr91{color:#ff8674}html.theme--documenter-dark .ansi span.sgr92{color:#79d462}html.theme--documenter-dark .ansi span.sgr93{color:#ffe76b}html.theme--documenter-dark .ansi span.sgr94{color:#8a98ff}html.theme--documenter-dark .ansi span.sgr95{color:#d2a4e6}html.theme--documenter-dark .ansi span.sgr96{color:#6bc8db}html.theme--documenter-dark .ansi span.sgr97{color:#ecf0f1}html.theme--documenter-dark .ansi span.sgr100{background-color:#92a0a2}html.theme--documenter-dark .ansi span.sgr101{background-color:#ff8674}html.theme--documenter-dark .ansi span.sgr102{background-color:#79d462}html.theme--documenter-dark .ansi span.sgr103{background-color:#ffe76b}html.theme--documenter-dark .ansi span.sgr104{background-color:#8a98ff}html.theme--documenter-dark .ansi span.sgr105{background-color:#d2a4e6}html.theme--documenter-dark .ansi span.sgr106{background-color:#6bc8db}html.theme--documenter-dark .ansi span.sgr107{background-color:#ecf0f1}html.theme--documenter-dark code.language-julia-repl>span.hljs-meta{color:#4fb43a;font-weight:bolder}html.theme--documenter-dark .hljs{background:#2b2b2b;color:#f8f8f2}html.theme--documenter-dark .hljs-comment,html.theme--documenter-dark .hljs-quote{color:#d4d0ab}html.theme--documenter-dark .hljs-variable,html.theme--documenter-dark .hljs-template-variable,html.theme--documenter-dark .hljs-tag,html.theme--documenter-dark .hljs-name,html.theme--documenter-dark .hljs-selector-id,html.theme--documenter-dark .hljs-selector-class,html.theme--documenter-dark .hljs-regexp,html.theme--documenter-dark .hljs-deletion{color:#ffa07a}html.theme--documenter-dark .hljs-number,html.theme--documenter-dark .hljs-built_in,html.theme--documenter-dark .hljs-literal,html.theme--documenter-dark .hljs-type,html.theme--documenter-dark .hljs-params,html.theme--documenter-dark .hljs-meta,html.theme--documenter-dark .hljs-link{color:#f5ab35}html.theme--documenter-dark .hljs-attribute{color:#ffd700}html.theme--documenter-dark .hljs-string,html.theme--documenter-dark .hljs-symbol,html.theme--documenter-dark .hljs-bullet,html.theme--documenter-dark .hljs-addition{color:#abe338}html.theme--documenter-dark .hljs-title,html.theme--documenter-dark .hljs-section{color:#00e0e0}html.theme--documenter-dark .hljs-keyword,html.theme--documenter-dark .hljs-selector-tag{color:#dcc6e0}html.theme--documenter-dark .hljs-emphasis{font-style:italic}html.theme--documenter-dark .hljs-strong{font-weight:bold}@media screen and (-ms-high-contrast: active){html.theme--documenter-dark .hljs-addition,html.theme--documenter-dark .hljs-attribute,html.theme--documenter-dark .hljs-built_in,html.theme--documenter-dark .hljs-bullet,html.theme--documenter-dark .hljs-comment,html.theme--documenter-dark .hljs-link,html.theme--documenter-dark .hljs-literal,html.theme--documenter-dark .hljs-meta,html.theme--documenter-dark .hljs-number,html.theme--documenter-dark .hljs-params,html.theme--documenter-dark .hljs-string,html.theme--documenter-dark .hljs-symbol,html.theme--documenter-dark .hljs-type,html.theme--documenter-dark .hljs-quote{color:highlight}html.theme--documenter-dark .hljs-keyword,html.theme--documenter-dark .hljs-selector-tag{font-weight:bold}}html.theme--documenter-dark .hljs-subst{color:#f8f8f2}html.theme--documenter-dark .search-result-link{border-radius:0.7em;transition:all 300ms}html.theme--documenter-dark .search-result-link:hover,html.theme--documenter-dark .search-result-link:focus{background-color:rgba(0,128,128,0.1)}html.theme--documenter-dark .search-result-link .property-search-result-badge,html.theme--documenter-dark .search-result-link .search-filter{transition:all 300ms}html.theme--documenter-dark .search-result-link:hover .property-search-result-badge,html.theme--documenter-dark .search-result-link:hover .search-filter,html.theme--documenter-dark .search-result-link:focus .property-search-result-badge,html.theme--documenter-dark .search-result-link:focus .search-filter{color:#333 !important;background-color:#f1f5f9 !important}html.theme--documenter-dark .search-result-title{color:whitesmoke}html.theme--documenter-dark .search-result-highlight{background-color:greenyellow;color:black}html.theme--documenter-dark .search-divider{border-bottom:1px solid #5e6d6f50}html.theme--documenter-dark .w-100{width:100%}html.theme--documenter-dark .gap-2{gap:0.5rem}html.theme--documenter-dark .gap-4{gap:1rem} diff --git a/v0.18.15/assets/themes/documenter-light.css b/v0.18.15/assets/themes/documenter-light.css new file mode 100644 index 0000000000..2f168c77b4 --- /dev/null +++ b/v0.18.15/assets/themes/documenter-light.css @@ -0,0 +1,9 @@ +.pagination-previous,.pagination-next,.pagination-link,.pagination-ellipsis,.file-cta,.file-name,.select select,.textarea,.input,#documenter .docs-sidebar form.docs-search>input,.button{-moz-appearance:none;-webkit-appearance:none;align-items:center;border:1px solid transparent;border-radius:4px;box-shadow:none;display:inline-flex;font-size:1rem;height:2.5em;justify-content:flex-start;line-height:1.5;padding-bottom:calc(0.5em - 1px);padding-left:calc(0.75em - 1px);padding-right:calc(0.75em - 1px);padding-top:calc(0.5em - 1px);position:relative;vertical-align:top}.pagination-previous:focus,.pagination-next:focus,.pagination-link:focus,.pagination-ellipsis:focus,.file-cta:focus,.file-name:focus,.select select:focus,.textarea:focus,.input:focus,#documenter .docs-sidebar form.docs-search>input:focus,.button:focus,.is-focused.pagination-previous,.is-focused.pagination-next,.is-focused.pagination-link,.is-focused.pagination-ellipsis,.is-focused.file-cta,.is-focused.file-name,.select select.is-focused,.is-focused.textarea,.is-focused.input,#documenter .docs-sidebar form.docs-search>input.is-focused,.is-focused.button,.pagination-previous:active,.pagination-next:active,.pagination-link:active,.pagination-ellipsis:active,.file-cta:active,.file-name:active,.select select:active,.textarea:active,.input:active,#documenter .docs-sidebar form.docs-search>input:active,.button:active,.is-active.pagination-previous,.is-active.pagination-next,.is-active.pagination-link,.is-active.pagination-ellipsis,.is-active.file-cta,.is-active.file-name,.select select.is-active,.is-active.textarea,.is-active.input,#documenter .docs-sidebar form.docs-search>input.is-active,.is-active.button{outline:none}.pagination-previous[disabled],.pagination-next[disabled],.pagination-link[disabled],.pagination-ellipsis[disabled],.file-cta[disabled],.file-name[disabled],.select select[disabled],.textarea[disabled],.input[disabled],#documenter .docs-sidebar form.docs-search>input[disabled],.button[disabled],fieldset[disabled] .pagination-previous,fieldset[disabled] .pagination-next,fieldset[disabled] .pagination-link,fieldset[disabled] .pagination-ellipsis,fieldset[disabled] .file-cta,fieldset[disabled] .file-name,fieldset[disabled] .select select,.select fieldset[disabled] select,fieldset[disabled] .textarea,fieldset[disabled] .input,fieldset[disabled] #documenter .docs-sidebar form.docs-search>input,#documenter .docs-sidebar fieldset[disabled] form.docs-search>input,fieldset[disabled] .button{cursor:not-allowed}.tabs,.pagination-previous,.pagination-next,.pagination-link,.pagination-ellipsis,.breadcrumb,.file,.button,.is-unselectable{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.navbar-link:not(.is-arrowless)::after,.select:not(.is-multiple):not(.is-loading)::after{border:3px solid rgba(0,0,0,0);border-radius:2px;border-right:0;border-top:0;content:" ";display:block;height:0.625em;margin-top:-0.4375em;pointer-events:none;position:absolute;top:50%;transform:rotate(-45deg);transform-origin:center;width:0.625em}.admonition:not(:last-child),.tabs:not(:last-child),.pagination:not(:last-child),.message:not(:last-child),.level:not(:last-child),.breadcrumb:not(:last-child),.block:not(:last-child),.title:not(:last-child),.subtitle:not(:last-child),.table-container:not(:last-child),.table:not(:last-child),.progress:not(:last-child),.notification:not(:last-child),.content:not(:last-child),.box:not(:last-child){margin-bottom:1.5rem}.modal-close,.delete{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-moz-appearance:none;-webkit-appearance:none;background-color:rgba(10,10,10,0.2);border:none;border-radius:9999px;cursor:pointer;pointer-events:auto;display:inline-block;flex-grow:0;flex-shrink:0;font-size:0;height:20px;max-height:20px;max-width:20px;min-height:20px;min-width:20px;outline:none;position:relative;vertical-align:top;width:20px}.modal-close::before,.delete::before,.modal-close::after,.delete::after{background-color:#fff;content:"";display:block;left:50%;position:absolute;top:50%;transform:translateX(-50%) translateY(-50%) rotate(45deg);transform-origin:center center}.modal-close::before,.delete::before{height:2px;width:50%}.modal-close::after,.delete::after{height:50%;width:2px}.modal-close:hover,.delete:hover,.modal-close:focus,.delete:focus{background-color:rgba(10,10,10,0.3)}.modal-close:active,.delete:active{background-color:rgba(10,10,10,0.4)}.is-small.modal-close,#documenter .docs-sidebar form.docs-search>input.modal-close,.is-small.delete,#documenter .docs-sidebar form.docs-search>input.delete{height:16px;max-height:16px;max-width:16px;min-height:16px;min-width:16px;width:16px}.is-medium.modal-close,.is-medium.delete{height:24px;max-height:24px;max-width:24px;min-height:24px;min-width:24px;width:24px}.is-large.modal-close,.is-large.delete{height:32px;max-height:32px;max-width:32px;min-height:32px;min-width:32px;width:32px}.control.is-loading::after,.select.is-loading::after,.loader,.button.is-loading::after{animation:spinAround 500ms infinite linear;border:2px solid #dbdbdb;border-radius:9999px;border-right-color:transparent;border-top-color:transparent;content:"";display:block;height:1em;position:relative;width:1em}.hero-video,.modal-background,.modal,.image.is-square img,#documenter .docs-sidebar .docs-logo>img.is-square img,.image.is-square .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-square .has-ratio,.image.is-1by1 img,#documenter .docs-sidebar .docs-logo>img.is-1by1 img,.image.is-1by1 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-1by1 .has-ratio,.image.is-5by4 img,#documenter .docs-sidebar .docs-logo>img.is-5by4 img,.image.is-5by4 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-5by4 .has-ratio,.image.is-4by3 img,#documenter .docs-sidebar .docs-logo>img.is-4by3 img,.image.is-4by3 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-4by3 .has-ratio,.image.is-3by2 img,#documenter .docs-sidebar .docs-logo>img.is-3by2 img,.image.is-3by2 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-3by2 .has-ratio,.image.is-5by3 img,#documenter .docs-sidebar .docs-logo>img.is-5by3 img,.image.is-5by3 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-5by3 .has-ratio,.image.is-16by9 img,#documenter .docs-sidebar .docs-logo>img.is-16by9 img,.image.is-16by9 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-16by9 .has-ratio,.image.is-2by1 img,#documenter .docs-sidebar .docs-logo>img.is-2by1 img,.image.is-2by1 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-2by1 .has-ratio,.image.is-3by1 img,#documenter .docs-sidebar .docs-logo>img.is-3by1 img,.image.is-3by1 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-3by1 .has-ratio,.image.is-4by5 img,#documenter .docs-sidebar .docs-logo>img.is-4by5 img,.image.is-4by5 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-4by5 .has-ratio,.image.is-3by4 img,#documenter .docs-sidebar .docs-logo>img.is-3by4 img,.image.is-3by4 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-3by4 .has-ratio,.image.is-2by3 img,#documenter .docs-sidebar .docs-logo>img.is-2by3 img,.image.is-2by3 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-2by3 .has-ratio,.image.is-3by5 img,#documenter .docs-sidebar .docs-logo>img.is-3by5 img,.image.is-3by5 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-3by5 .has-ratio,.image.is-9by16 img,#documenter .docs-sidebar .docs-logo>img.is-9by16 img,.image.is-9by16 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-9by16 .has-ratio,.image.is-1by2 img,#documenter .docs-sidebar .docs-logo>img.is-1by2 img,.image.is-1by2 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-1by2 .has-ratio,.image.is-1by3 img,#documenter .docs-sidebar .docs-logo>img.is-1by3 img,.image.is-1by3 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-1by3 .has-ratio,.is-overlay{bottom:0;left:0;position:absolute;right:0;top:0}.navbar-burger{-moz-appearance:none;-webkit-appearance:none;appearance:none;background:none;border:none;color:currentColor;font-family:inherit;font-size:1em;margin:0;padding:0}.has-text-white{color:#fff !important}a.has-text-white:hover,a.has-text-white:focus{color:#e6e6e6 !important}.has-background-white{background-color:#fff !important}.has-text-black{color:#0a0a0a !important}a.has-text-black:hover,a.has-text-black:focus{color:#000 !important}.has-background-black{background-color:#0a0a0a !important}.has-text-light{color:#f5f5f5 !important}a.has-text-light:hover,a.has-text-light:focus{color:#dbdbdb !important}.has-background-light{background-color:#f5f5f5 !important}.has-text-dark{color:#363636 !important}a.has-text-dark:hover,a.has-text-dark:focus{color:#1c1c1c !important}.has-background-dark{background-color:#363636 !important}.has-text-primary{color:#4eb5de !important}a.has-text-primary:hover,a.has-text-primary:focus{color:#27a1d2 !important}.has-background-primary{background-color:#4eb5de !important}.has-text-primary-light{color:#eef8fc !important}a.has-text-primary-light:hover,a.has-text-primary-light:focus{color:#c3e6f4 !important}.has-background-primary-light{background-color:#eef8fc !important}.has-text-primary-dark{color:#1a6d8e !important}a.has-text-primary-dark:hover,a.has-text-primary-dark:focus{color:#228eb9 !important}.has-background-primary-dark{background-color:#1a6d8e !important}.has-text-link{color:#2e63b8 !important}a.has-text-link:hover,a.has-text-link:focus{color:#244d8f !important}.has-background-link{background-color:#2e63b8 !important}.has-text-link-light{color:#eff3fb !important}a.has-text-link-light:hover,a.has-text-link-light:focus{color:#c6d6f1 !important}.has-background-link-light{background-color:#eff3fb !important}.has-text-link-dark{color:#3169c4 !important}a.has-text-link-dark:hover,a.has-text-link-dark:focus{color:#5485d4 !important}.has-background-link-dark{background-color:#3169c4 !important}.has-text-info{color:#209cee !important}a.has-text-info:hover,a.has-text-info:focus{color:#1081cb !important}.has-background-info{background-color:#209cee !important}.has-text-info-light{color:#ecf7fe !important}a.has-text-info-light:hover,a.has-text-info-light:focus{color:#bde2fa !important}.has-background-info-light{background-color:#ecf7fe !important}.has-text-info-dark{color:#0e72b4 !important}a.has-text-info-dark:hover,a.has-text-info-dark:focus{color:#1190e3 !important}.has-background-info-dark{background-color:#0e72b4 !important}.has-text-success{color:#22c35b !important}a.has-text-success:hover,a.has-text-success:focus{color:#1a9847 !important}.has-background-success{background-color:#22c35b !important}.has-text-success-light{color:#eefcf3 !important}a.has-text-success-light:hover,a.has-text-success-light:focus{color:#c2f4d4 !important}.has-background-success-light{background-color:#eefcf3 !important}.has-text-success-dark{color:#198f43 !important}a.has-text-success-dark:hover,a.has-text-success-dark:focus{color:#21bb57 !important}.has-background-success-dark{background-color:#198f43 !important}.has-text-warning{color:#ffdd57 !important}a.has-text-warning:hover,a.has-text-warning:focus{color:#ffd324 !important}.has-background-warning{background-color:#ffdd57 !important}.has-text-warning-light{color:#fffbeb !important}a.has-text-warning-light:hover,a.has-text-warning-light:focus{color:#fff1b8 !important}.has-background-warning-light{background-color:#fffbeb !important}.has-text-warning-dark{color:#947600 !important}a.has-text-warning-dark:hover,a.has-text-warning-dark:focus{color:#c79f00 !important}.has-background-warning-dark{background-color:#947600 !important}.has-text-danger{color:#da0b00 !important}a.has-text-danger:hover,a.has-text-danger:focus{color:#a70800 !important}.has-background-danger{background-color:#da0b00 !important}.has-text-danger-light{color:#ffeceb !important}a.has-text-danger-light:hover,a.has-text-danger-light:focus{color:#ffbbb8 !important}.has-background-danger-light{background-color:#ffeceb !important}.has-text-danger-dark{color:#f50c00 !important}a.has-text-danger-dark:hover,a.has-text-danger-dark:focus{color:#ff3429 !important}.has-background-danger-dark{background-color:#f50c00 !important}.has-text-black-bis{color:#121212 !important}.has-background-black-bis{background-color:#121212 !important}.has-text-black-ter{color:#242424 !important}.has-background-black-ter{background-color:#242424 !important}.has-text-grey-darker{color:#363636 !important}.has-background-grey-darker{background-color:#363636 !important}.has-text-grey-dark{color:#4a4a4a !important}.has-background-grey-dark{background-color:#4a4a4a !important}.has-text-grey{color:#6b6b6b !important}.has-background-grey{background-color:#6b6b6b !important}.has-text-grey-light{color:#b5b5b5 !important}.has-background-grey-light{background-color:#b5b5b5 !important}.has-text-grey-lighter{color:#dbdbdb !important}.has-background-grey-lighter{background-color:#dbdbdb !important}.has-text-white-ter{color:#f5f5f5 !important}.has-background-white-ter{background-color:#f5f5f5 !important}.has-text-white-bis{color:#fafafa !important}.has-background-white-bis{background-color:#fafafa !important}.is-flex-direction-row{flex-direction:row !important}.is-flex-direction-row-reverse{flex-direction:row-reverse !important}.is-flex-direction-column{flex-direction:column !important}.is-flex-direction-column-reverse{flex-direction:column-reverse !important}.is-flex-wrap-nowrap{flex-wrap:nowrap !important}.is-flex-wrap-wrap{flex-wrap:wrap !important}.is-flex-wrap-wrap-reverse{flex-wrap:wrap-reverse !important}.is-justify-content-flex-start{justify-content:flex-start !important}.is-justify-content-flex-end{justify-content:flex-end !important}.is-justify-content-center{justify-content:center !important}.is-justify-content-space-between{justify-content:space-between !important}.is-justify-content-space-around{justify-content:space-around !important}.is-justify-content-space-evenly{justify-content:space-evenly !important}.is-justify-content-start{justify-content:start !important}.is-justify-content-end{justify-content:end !important}.is-justify-content-left{justify-content:left !important}.is-justify-content-right{justify-content:right !important}.is-align-content-flex-start{align-content:flex-start !important}.is-align-content-flex-end{align-content:flex-end !important}.is-align-content-center{align-content:center !important}.is-align-content-space-between{align-content:space-between !important}.is-align-content-space-around{align-content:space-around !important}.is-align-content-space-evenly{align-content:space-evenly !important}.is-align-content-stretch{align-content:stretch !important}.is-align-content-start{align-content:start !important}.is-align-content-end{align-content:end !important}.is-align-content-baseline{align-content:baseline !important}.is-align-items-stretch{align-items:stretch !important}.is-align-items-flex-start{align-items:flex-start !important}.is-align-items-flex-end{align-items:flex-end !important}.is-align-items-center{align-items:center !important}.is-align-items-baseline{align-items:baseline !important}.is-align-items-start{align-items:start !important}.is-align-items-end{align-items:end !important}.is-align-items-self-start{align-items:self-start !important}.is-align-items-self-end{align-items:self-end !important}.is-align-self-auto{align-self:auto !important}.is-align-self-flex-start{align-self:flex-start !important}.is-align-self-flex-end{align-self:flex-end !important}.is-align-self-center{align-self:center !important}.is-align-self-baseline{align-self:baseline !important}.is-align-self-stretch{align-self:stretch !important}.is-flex-grow-0{flex-grow:0 !important}.is-flex-grow-1{flex-grow:1 !important}.is-flex-grow-2{flex-grow:2 !important}.is-flex-grow-3{flex-grow:3 !important}.is-flex-grow-4{flex-grow:4 !important}.is-flex-grow-5{flex-grow:5 !important}.is-flex-shrink-0{flex-shrink:0 !important}.is-flex-shrink-1{flex-shrink:1 !important}.is-flex-shrink-2{flex-shrink:2 !important}.is-flex-shrink-3{flex-shrink:3 !important}.is-flex-shrink-4{flex-shrink:4 !important}.is-flex-shrink-5{flex-shrink:5 !important}.is-clearfix::after{clear:both;content:" ";display:table}.is-pulled-left{float:left !important}.is-pulled-right{float:right !important}.is-radiusless{border-radius:0 !important}.is-shadowless{box-shadow:none !important}.is-clickable{cursor:pointer !important;pointer-events:all !important}.is-clipped{overflow:hidden !important}.is-relative{position:relative !important}.is-marginless{margin:0 !important}.is-paddingless{padding:0 !important}.m-0{margin:0 !important}.mt-0{margin-top:0 !important}.mr-0{margin-right:0 !important}.mb-0{margin-bottom:0 !important}.ml-0{margin-left:0 !important}.mx-0{margin-left:0 !important;margin-right:0 !important}.my-0{margin-top:0 !important;margin-bottom:0 !important}.m-1{margin:.25rem !important}.mt-1{margin-top:.25rem !important}.mr-1{margin-right:.25rem !important}.mb-1{margin-bottom:.25rem !important}.ml-1{margin-left:.25rem !important}.mx-1{margin-left:.25rem !important;margin-right:.25rem !important}.my-1{margin-top:.25rem !important;margin-bottom:.25rem !important}.m-2{margin:.5rem !important}.mt-2{margin-top:.5rem !important}.mr-2{margin-right:.5rem !important}.mb-2{margin-bottom:.5rem !important}.ml-2{margin-left:.5rem !important}.mx-2{margin-left:.5rem !important;margin-right:.5rem !important}.my-2{margin-top:.5rem !important;margin-bottom:.5rem !important}.m-3{margin:.75rem !important}.mt-3{margin-top:.75rem !important}.mr-3{margin-right:.75rem !important}.mb-3{margin-bottom:.75rem !important}.ml-3{margin-left:.75rem !important}.mx-3{margin-left:.75rem !important;margin-right:.75rem !important}.my-3{margin-top:.75rem !important;margin-bottom:.75rem !important}.m-4{margin:1rem !important}.mt-4{margin-top:1rem !important}.mr-4{margin-right:1rem !important}.mb-4{margin-bottom:1rem !important}.ml-4{margin-left:1rem !important}.mx-4{margin-left:1rem !important;margin-right:1rem !important}.my-4{margin-top:1rem !important;margin-bottom:1rem !important}.m-5{margin:1.5rem !important}.mt-5{margin-top:1.5rem !important}.mr-5{margin-right:1.5rem !important}.mb-5{margin-bottom:1.5rem !important}.ml-5{margin-left:1.5rem !important}.mx-5{margin-left:1.5rem !important;margin-right:1.5rem !important}.my-5{margin-top:1.5rem !important;margin-bottom:1.5rem !important}.m-6{margin:3rem !important}.mt-6{margin-top:3rem !important}.mr-6{margin-right:3rem !important}.mb-6{margin-bottom:3rem !important}.ml-6{margin-left:3rem !important}.mx-6{margin-left:3rem !important;margin-right:3rem !important}.my-6{margin-top:3rem !important;margin-bottom:3rem !important}.m-auto{margin:auto !important}.mt-auto{margin-top:auto !important}.mr-auto{margin-right:auto !important}.mb-auto{margin-bottom:auto !important}.ml-auto{margin-left:auto !important}.mx-auto{margin-left:auto !important;margin-right:auto !important}.my-auto{margin-top:auto !important;margin-bottom:auto !important}.p-0{padding:0 !important}.pt-0{padding-top:0 !important}.pr-0{padding-right:0 !important}.pb-0{padding-bottom:0 !important}.pl-0{padding-left:0 !important}.px-0{padding-left:0 !important;padding-right:0 !important}.py-0{padding-top:0 !important;padding-bottom:0 !important}.p-1{padding:.25rem !important}.pt-1{padding-top:.25rem !important}.pr-1{padding-right:.25rem !important}.pb-1{padding-bottom:.25rem !important}.pl-1{padding-left:.25rem !important}.px-1{padding-left:.25rem !important;padding-right:.25rem !important}.py-1{padding-top:.25rem !important;padding-bottom:.25rem !important}.p-2{padding:.5rem !important}.pt-2{padding-top:.5rem !important}.pr-2{padding-right:.5rem !important}.pb-2{padding-bottom:.5rem !important}.pl-2{padding-left:.5rem !important}.px-2{padding-left:.5rem !important;padding-right:.5rem !important}.py-2{padding-top:.5rem !important;padding-bottom:.5rem !important}.p-3{padding:.75rem !important}.pt-3{padding-top:.75rem !important}.pr-3{padding-right:.75rem !important}.pb-3{padding-bottom:.75rem !important}.pl-3{padding-left:.75rem !important}.px-3{padding-left:.75rem !important;padding-right:.75rem !important}.py-3{padding-top:.75rem !important;padding-bottom:.75rem !important}.p-4{padding:1rem !important}.pt-4{padding-top:1rem !important}.pr-4{padding-right:1rem !important}.pb-4{padding-bottom:1rem !important}.pl-4{padding-left:1rem !important}.px-4{padding-left:1rem !important;padding-right:1rem !important}.py-4{padding-top:1rem !important;padding-bottom:1rem !important}.p-5{padding:1.5rem !important}.pt-5{padding-top:1.5rem !important}.pr-5{padding-right:1.5rem !important}.pb-5{padding-bottom:1.5rem !important}.pl-5{padding-left:1.5rem !important}.px-5{padding-left:1.5rem !important;padding-right:1.5rem !important}.py-5{padding-top:1.5rem !important;padding-bottom:1.5rem !important}.p-6{padding:3rem !important}.pt-6{padding-top:3rem !important}.pr-6{padding-right:3rem !important}.pb-6{padding-bottom:3rem !important}.pl-6{padding-left:3rem !important}.px-6{padding-left:3rem !important;padding-right:3rem !important}.py-6{padding-top:3rem !important;padding-bottom:3rem !important}.p-auto{padding:auto !important}.pt-auto{padding-top:auto !important}.pr-auto{padding-right:auto !important}.pb-auto{padding-bottom:auto !important}.pl-auto{padding-left:auto !important}.px-auto{padding-left:auto !important;padding-right:auto !important}.py-auto{padding-top:auto !important;padding-bottom:auto !important}.is-size-1{font-size:3rem !important}.is-size-2{font-size:2.5rem !important}.is-size-3{font-size:2rem !important}.is-size-4{font-size:1.5rem !important}.is-size-5{font-size:1.25rem !important}.is-size-6{font-size:1rem !important}.is-size-7,.docstring>section>a.docs-sourcelink{font-size:.75rem !important}@media screen and (max-width: 768px){.is-size-1-mobile{font-size:3rem !important}.is-size-2-mobile{font-size:2.5rem !important}.is-size-3-mobile{font-size:2rem !important}.is-size-4-mobile{font-size:1.5rem !important}.is-size-5-mobile{font-size:1.25rem !important}.is-size-6-mobile{font-size:1rem !important}.is-size-7-mobile{font-size:.75rem !important}}@media screen and (min-width: 769px),print{.is-size-1-tablet{font-size:3rem !important}.is-size-2-tablet{font-size:2.5rem !important}.is-size-3-tablet{font-size:2rem !important}.is-size-4-tablet{font-size:1.5rem !important}.is-size-5-tablet{font-size:1.25rem !important}.is-size-6-tablet{font-size:1rem !important}.is-size-7-tablet{font-size:.75rem !important}}@media screen and (max-width: 1055px){.is-size-1-touch{font-size:3rem !important}.is-size-2-touch{font-size:2.5rem !important}.is-size-3-touch{font-size:2rem !important}.is-size-4-touch{font-size:1.5rem !important}.is-size-5-touch{font-size:1.25rem !important}.is-size-6-touch{font-size:1rem !important}.is-size-7-touch{font-size:.75rem !important}}@media screen and (min-width: 1056px){.is-size-1-desktop{font-size:3rem !important}.is-size-2-desktop{font-size:2.5rem !important}.is-size-3-desktop{font-size:2rem !important}.is-size-4-desktop{font-size:1.5rem !important}.is-size-5-desktop{font-size:1.25rem !important}.is-size-6-desktop{font-size:1rem !important}.is-size-7-desktop{font-size:.75rem !important}}@media screen and (min-width: 1216px){.is-size-1-widescreen{font-size:3rem !important}.is-size-2-widescreen{font-size:2.5rem !important}.is-size-3-widescreen{font-size:2rem !important}.is-size-4-widescreen{font-size:1.5rem !important}.is-size-5-widescreen{font-size:1.25rem !important}.is-size-6-widescreen{font-size:1rem !important}.is-size-7-widescreen{font-size:.75rem !important}}@media screen and (min-width: 1408px){.is-size-1-fullhd{font-size:3rem !important}.is-size-2-fullhd{font-size:2.5rem !important}.is-size-3-fullhd{font-size:2rem !important}.is-size-4-fullhd{font-size:1.5rem !important}.is-size-5-fullhd{font-size:1.25rem !important}.is-size-6-fullhd{font-size:1rem !important}.is-size-7-fullhd{font-size:.75rem !important}}.has-text-centered{text-align:center !important}.has-text-justified{text-align:justify !important}.has-text-left{text-align:left !important}.has-text-right{text-align:right !important}@media screen and (max-width: 768px){.has-text-centered-mobile{text-align:center !important}}@media screen and (min-width: 769px),print{.has-text-centered-tablet{text-align:center !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.has-text-centered-tablet-only{text-align:center !important}}@media screen and (max-width: 1055px){.has-text-centered-touch{text-align:center !important}}@media screen and (min-width: 1056px){.has-text-centered-desktop{text-align:center !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.has-text-centered-desktop-only{text-align:center !important}}@media screen and (min-width: 1216px){.has-text-centered-widescreen{text-align:center !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.has-text-centered-widescreen-only{text-align:center !important}}@media screen and (min-width: 1408px){.has-text-centered-fullhd{text-align:center !important}}@media screen and (max-width: 768px){.has-text-justified-mobile{text-align:justify !important}}@media screen and (min-width: 769px),print{.has-text-justified-tablet{text-align:justify !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.has-text-justified-tablet-only{text-align:justify !important}}@media screen and (max-width: 1055px){.has-text-justified-touch{text-align:justify !important}}@media screen and (min-width: 1056px){.has-text-justified-desktop{text-align:justify !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.has-text-justified-desktop-only{text-align:justify !important}}@media screen and (min-width: 1216px){.has-text-justified-widescreen{text-align:justify !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.has-text-justified-widescreen-only{text-align:justify !important}}@media screen and (min-width: 1408px){.has-text-justified-fullhd{text-align:justify !important}}@media screen and (max-width: 768px){.has-text-left-mobile{text-align:left !important}}@media screen and (min-width: 769px),print{.has-text-left-tablet{text-align:left !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.has-text-left-tablet-only{text-align:left !important}}@media screen and (max-width: 1055px){.has-text-left-touch{text-align:left !important}}@media screen and (min-width: 1056px){.has-text-left-desktop{text-align:left !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.has-text-left-desktop-only{text-align:left !important}}@media screen and (min-width: 1216px){.has-text-left-widescreen{text-align:left !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.has-text-left-widescreen-only{text-align:left !important}}@media screen and (min-width: 1408px){.has-text-left-fullhd{text-align:left !important}}@media screen and (max-width: 768px){.has-text-right-mobile{text-align:right !important}}@media screen and (min-width: 769px),print{.has-text-right-tablet{text-align:right !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.has-text-right-tablet-only{text-align:right !important}}@media screen and (max-width: 1055px){.has-text-right-touch{text-align:right !important}}@media screen and (min-width: 1056px){.has-text-right-desktop{text-align:right !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.has-text-right-desktop-only{text-align:right !important}}@media screen and (min-width: 1216px){.has-text-right-widescreen{text-align:right !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.has-text-right-widescreen-only{text-align:right !important}}@media screen and (min-width: 1408px){.has-text-right-fullhd{text-align:right !important}}.is-capitalized{text-transform:capitalize !important}.is-lowercase{text-transform:lowercase !important}.is-uppercase{text-transform:uppercase !important}.is-italic{font-style:italic !important}.is-underlined{text-decoration:underline !important}.has-text-weight-light{font-weight:300 !important}.has-text-weight-normal{font-weight:400 !important}.has-text-weight-medium{font-weight:500 !important}.has-text-weight-semibold{font-weight:600 !important}.has-text-weight-bold{font-weight:700 !important}.is-family-primary{font-family:"Lato Medium",-apple-system,BlinkMacSystemFont,"Segoe UI","Helvetica Neue","Helvetica","Arial",sans-serif !important}.is-family-secondary{font-family:"Lato Medium",-apple-system,BlinkMacSystemFont,"Segoe UI","Helvetica Neue","Helvetica","Arial",sans-serif !important}.is-family-sans-serif{font-family:"Lato Medium",-apple-system,BlinkMacSystemFont,"Segoe UI","Helvetica Neue","Helvetica","Arial",sans-serif !important}.is-family-monospace{font-family:"JuliaMono","SFMono-Regular","Menlo","Consolas","Liberation Mono","DejaVu Sans Mono",monospace !important}.is-family-code{font-family:"JuliaMono","SFMono-Regular","Menlo","Consolas","Liberation Mono","DejaVu Sans Mono",monospace !important}.is-block{display:block !important}@media screen and (max-width: 768px){.is-block-mobile{display:block !important}}@media screen and (min-width: 769px),print{.is-block-tablet{display:block !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.is-block-tablet-only{display:block !important}}@media screen and (max-width: 1055px){.is-block-touch{display:block !important}}@media screen and (min-width: 1056px){.is-block-desktop{display:block !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.is-block-desktop-only{display:block !important}}@media screen and (min-width: 1216px){.is-block-widescreen{display:block !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.is-block-widescreen-only{display:block !important}}@media screen and (min-width: 1408px){.is-block-fullhd{display:block !important}}.is-flex{display:flex !important}@media screen and (max-width: 768px){.is-flex-mobile{display:flex !important}}@media screen and (min-width: 769px),print{.is-flex-tablet{display:flex !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.is-flex-tablet-only{display:flex !important}}@media screen and (max-width: 1055px){.is-flex-touch{display:flex !important}}@media screen and (min-width: 1056px){.is-flex-desktop{display:flex !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.is-flex-desktop-only{display:flex !important}}@media screen and (min-width: 1216px){.is-flex-widescreen{display:flex !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.is-flex-widescreen-only{display:flex !important}}@media screen and (min-width: 1408px){.is-flex-fullhd{display:flex !important}}.is-inline{display:inline !important}@media screen and (max-width: 768px){.is-inline-mobile{display:inline !important}}@media screen and (min-width: 769px),print{.is-inline-tablet{display:inline !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.is-inline-tablet-only{display:inline !important}}@media screen and (max-width: 1055px){.is-inline-touch{display:inline !important}}@media screen and (min-width: 1056px){.is-inline-desktop{display:inline !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.is-inline-desktop-only{display:inline !important}}@media screen and (min-width: 1216px){.is-inline-widescreen{display:inline !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.is-inline-widescreen-only{display:inline !important}}@media screen and (min-width: 1408px){.is-inline-fullhd{display:inline !important}}.is-inline-block{display:inline-block !important}@media screen and (max-width: 768px){.is-inline-block-mobile{display:inline-block !important}}@media screen and (min-width: 769px),print{.is-inline-block-tablet{display:inline-block !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.is-inline-block-tablet-only{display:inline-block !important}}@media screen and (max-width: 1055px){.is-inline-block-touch{display:inline-block !important}}@media screen and (min-width: 1056px){.is-inline-block-desktop{display:inline-block !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.is-inline-block-desktop-only{display:inline-block !important}}@media screen and (min-width: 1216px){.is-inline-block-widescreen{display:inline-block !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.is-inline-block-widescreen-only{display:inline-block !important}}@media screen and (min-width: 1408px){.is-inline-block-fullhd{display:inline-block !important}}.is-inline-flex{display:inline-flex !important}@media screen and (max-width: 768px){.is-inline-flex-mobile{display:inline-flex !important}}@media screen and (min-width: 769px),print{.is-inline-flex-tablet{display:inline-flex !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.is-inline-flex-tablet-only{display:inline-flex !important}}@media screen and (max-width: 1055px){.is-inline-flex-touch{display:inline-flex !important}}@media screen and (min-width: 1056px){.is-inline-flex-desktop{display:inline-flex !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.is-inline-flex-desktop-only{display:inline-flex !important}}@media screen and (min-width: 1216px){.is-inline-flex-widescreen{display:inline-flex !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.is-inline-flex-widescreen-only{display:inline-flex !important}}@media screen and (min-width: 1408px){.is-inline-flex-fullhd{display:inline-flex !important}}.is-hidden{display:none !important}.is-sr-only{border:none !important;clip:rect(0, 0, 0, 0) !important;height:0.01em !important;overflow:hidden !important;padding:0 !important;position:absolute !important;white-space:nowrap !important;width:0.01em !important}@media screen and (max-width: 768px){.is-hidden-mobile{display:none !important}}@media screen and (min-width: 769px),print{.is-hidden-tablet{display:none !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.is-hidden-tablet-only{display:none !important}}@media screen and (max-width: 1055px){.is-hidden-touch{display:none !important}}@media screen and (min-width: 1056px){.is-hidden-desktop{display:none !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.is-hidden-desktop-only{display:none !important}}@media screen and (min-width: 1216px){.is-hidden-widescreen{display:none !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.is-hidden-widescreen-only{display:none !important}}@media screen and (min-width: 1408px){.is-hidden-fullhd{display:none !important}}.is-invisible{visibility:hidden !important}@media screen and (max-width: 768px){.is-invisible-mobile{visibility:hidden !important}}@media screen and (min-width: 769px),print{.is-invisible-tablet{visibility:hidden !important}}@media screen and (min-width: 769px) and (max-width: 1055px){.is-invisible-tablet-only{visibility:hidden !important}}@media screen and (max-width: 1055px){.is-invisible-touch{visibility:hidden !important}}@media screen and (min-width: 1056px){.is-invisible-desktop{visibility:hidden !important}}@media screen and (min-width: 1056px) and (max-width: 1215px){.is-invisible-desktop-only{visibility:hidden !important}}@media screen and (min-width: 1216px){.is-invisible-widescreen{visibility:hidden !important}}@media screen and (min-width: 1216px) and (max-width: 1407px){.is-invisible-widescreen-only{visibility:hidden !important}}@media screen and (min-width: 1408px){.is-invisible-fullhd{visibility:hidden !important}}/*! minireset.css v0.0.6 | MIT License | github.com/jgthms/minireset.css */html,body,p,ol,ul,li,dl,dt,dd,blockquote,figure,fieldset,legend,textarea,pre,iframe,hr,h1,h2,h3,h4,h5,h6{margin:0;padding:0}h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:normal}ul{list-style:none}button,input,select,textarea{margin:0}html{box-sizing:border-box}*,*::before,*::after{box-sizing:inherit}img,video{height:auto;max-width:100%}iframe{border:0}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}td:not([align]),th:not([align]){text-align:inherit}html{background-color:#fff;font-size:16px;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;min-width:300px;overflow-x:auto;overflow-y:scroll;text-rendering:optimizeLegibility;text-size-adjust:100%}article,aside,figure,footer,header,hgroup,section{display:block}body,button,input,optgroup,select,textarea{font-family:"Lato Medium",-apple-system,BlinkMacSystemFont,"Segoe UI","Helvetica Neue","Helvetica","Arial",sans-serif}code,pre{-moz-osx-font-smoothing:auto;-webkit-font-smoothing:auto;font-family:"JuliaMono","SFMono-Regular","Menlo","Consolas","Liberation Mono","DejaVu Sans Mono",monospace}body{color:#222;font-size:1em;font-weight:400;line-height:1.5}a{color:#2e63b8;cursor:pointer;text-decoration:none}a strong{color:currentColor}a:hover{color:#363636}code{background-color:rgba(0,0,0,0.05);color:#000;font-size:.875em;font-weight:normal;padding:.1em}hr{background-color:#f5f5f5;border:none;display:block;height:2px;margin:1.5rem 0}img{height:auto;max-width:100%}input[type="checkbox"],input[type="radio"]{vertical-align:baseline}small{font-size:.875em}span{font-style:inherit;font-weight:inherit}strong{color:#222;font-weight:700}fieldset{border:none}pre{-webkit-overflow-scrolling:touch;background-color:#f5f5f5;color:#222;font-size:.875em;overflow-x:auto;padding:1.25rem 1.5rem;white-space:pre;word-wrap:normal}pre code{background-color:transparent;color:currentColor;font-size:1em;padding:0}table td,table th{vertical-align:top}table td:not([align]),table th:not([align]){text-align:inherit}table th{color:#222}@keyframes spinAround{from{transform:rotate(0deg)}to{transform:rotate(359deg)}}.box{background-color:#fff;border-radius:6px;box-shadow:#bbb;color:#222;display:block;padding:1.25rem}a.box:hover,a.box:focus{box-shadow:0 0.5em 1em -0.125em rgba(10,10,10,0.1),0 0 0 1px #2e63b8}a.box:active{box-shadow:inset 0 1px 2px rgba(10,10,10,0.2),0 0 0 1px #2e63b8}.button{background-color:#fff;border-color:#dbdbdb;border-width:1px;color:#222;cursor:pointer;justify-content:center;padding-bottom:calc(0.5em - 1px);padding-left:1em;padding-right:1em;padding-top:calc(0.5em - 1px);text-align:center;white-space:nowrap}.button strong{color:inherit}.button .icon,.button .icon.is-small,.button #documenter .docs-sidebar form.docs-search>input.icon,#documenter .docs-sidebar .button form.docs-search>input.icon,.button .icon.is-medium,.button .icon.is-large{height:1.5em;width:1.5em}.button .icon:first-child:not(:last-child){margin-left:calc(-0.5em - 1px);margin-right:.25em}.button .icon:last-child:not(:first-child){margin-left:.25em;margin-right:calc(-0.5em - 1px)}.button .icon:first-child:last-child{margin-left:calc(-0.5em - 1px);margin-right:calc(-0.5em - 1px)}.button:hover,.button.is-hovered{border-color:#b5b5b5;color:#363636}.button:focus,.button.is-focused{border-color:#3c5dcd;color:#363636}.button:focus:not(:active),.button.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(46,99,184,0.25)}.button:active,.button.is-active{border-color:#4a4a4a;color:#363636}.button.is-text{background-color:transparent;border-color:transparent;color:#222;text-decoration:underline}.button.is-text:hover,.button.is-text.is-hovered,.button.is-text:focus,.button.is-text.is-focused{background-color:#f5f5f5;color:#222}.button.is-text:active,.button.is-text.is-active{background-color:#e8e8e8;color:#222}.button.is-text[disabled],fieldset[disabled] .button.is-text{background-color:transparent;border-color:transparent;box-shadow:none}.button.is-ghost{background:none;border-color:rgba(0,0,0,0);color:#2e63b8;text-decoration:none}.button.is-ghost:hover,.button.is-ghost.is-hovered{color:#2e63b8;text-decoration:underline}.button.is-white{background-color:#fff;border-color:transparent;color:#0a0a0a}.button.is-white:hover,.button.is-white.is-hovered{background-color:#f9f9f9;border-color:transparent;color:#0a0a0a}.button.is-white:focus,.button.is-white.is-focused{border-color:transparent;color:#0a0a0a}.button.is-white:focus:not(:active),.button.is-white.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(255,255,255,0.25)}.button.is-white:active,.button.is-white.is-active{background-color:#f2f2f2;border-color:transparent;color:#0a0a0a}.button.is-white[disabled],fieldset[disabled] .button.is-white{background-color:#fff;border-color:#fff;box-shadow:none}.button.is-white.is-inverted{background-color:#0a0a0a;color:#fff}.button.is-white.is-inverted:hover,.button.is-white.is-inverted.is-hovered{background-color:#000}.button.is-white.is-inverted[disabled],fieldset[disabled] .button.is-white.is-inverted{background-color:#0a0a0a;border-color:transparent;box-shadow:none;color:#fff}.button.is-white.is-loading::after{border-color:transparent transparent #0a0a0a #0a0a0a !important}.button.is-white.is-outlined{background-color:transparent;border-color:#fff;color:#fff}.button.is-white.is-outlined:hover,.button.is-white.is-outlined.is-hovered,.button.is-white.is-outlined:focus,.button.is-white.is-outlined.is-focused{background-color:#fff;border-color:#fff;color:#0a0a0a}.button.is-white.is-outlined.is-loading::after{border-color:transparent transparent #fff #fff !important}.button.is-white.is-outlined.is-loading:hover::after,.button.is-white.is-outlined.is-loading.is-hovered::after,.button.is-white.is-outlined.is-loading:focus::after,.button.is-white.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #0a0a0a #0a0a0a !important}.button.is-white.is-outlined[disabled],fieldset[disabled] .button.is-white.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}.button.is-white.is-inverted.is-outlined{background-color:transparent;border-color:#0a0a0a;color:#0a0a0a}.button.is-white.is-inverted.is-outlined:hover,.button.is-white.is-inverted.is-outlined.is-hovered,.button.is-white.is-inverted.is-outlined:focus,.button.is-white.is-inverted.is-outlined.is-focused{background-color:#0a0a0a;color:#fff}.button.is-white.is-inverted.is-outlined.is-loading:hover::after,.button.is-white.is-inverted.is-outlined.is-loading.is-hovered::after,.button.is-white.is-inverted.is-outlined.is-loading:focus::after,.button.is-white.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}.button.is-white.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-white.is-inverted.is-outlined{background-color:transparent;border-color:#0a0a0a;box-shadow:none;color:#0a0a0a}.button.is-black{background-color:#0a0a0a;border-color:transparent;color:#fff}.button.is-black:hover,.button.is-black.is-hovered{background-color:#040404;border-color:transparent;color:#fff}.button.is-black:focus,.button.is-black.is-focused{border-color:transparent;color:#fff}.button.is-black:focus:not(:active),.button.is-black.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(10,10,10,0.25)}.button.is-black:active,.button.is-black.is-active{background-color:#000;border-color:transparent;color:#fff}.button.is-black[disabled],fieldset[disabled] .button.is-black{background-color:#0a0a0a;border-color:#0a0a0a;box-shadow:none}.button.is-black.is-inverted{background-color:#fff;color:#0a0a0a}.button.is-black.is-inverted:hover,.button.is-black.is-inverted.is-hovered{background-color:#f2f2f2}.button.is-black.is-inverted[disabled],fieldset[disabled] .button.is-black.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#0a0a0a}.button.is-black.is-loading::after{border-color:transparent transparent #fff #fff !important}.button.is-black.is-outlined{background-color:transparent;border-color:#0a0a0a;color:#0a0a0a}.button.is-black.is-outlined:hover,.button.is-black.is-outlined.is-hovered,.button.is-black.is-outlined:focus,.button.is-black.is-outlined.is-focused{background-color:#0a0a0a;border-color:#0a0a0a;color:#fff}.button.is-black.is-outlined.is-loading::after{border-color:transparent transparent #0a0a0a #0a0a0a !important}.button.is-black.is-outlined.is-loading:hover::after,.button.is-black.is-outlined.is-loading.is-hovered::after,.button.is-black.is-outlined.is-loading:focus::after,.button.is-black.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}.button.is-black.is-outlined[disabled],fieldset[disabled] .button.is-black.is-outlined{background-color:transparent;border-color:#0a0a0a;box-shadow:none;color:#0a0a0a}.button.is-black.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}.button.is-black.is-inverted.is-outlined:hover,.button.is-black.is-inverted.is-outlined.is-hovered,.button.is-black.is-inverted.is-outlined:focus,.button.is-black.is-inverted.is-outlined.is-focused{background-color:#fff;color:#0a0a0a}.button.is-black.is-inverted.is-outlined.is-loading:hover::after,.button.is-black.is-inverted.is-outlined.is-loading.is-hovered::after,.button.is-black.is-inverted.is-outlined.is-loading:focus::after,.button.is-black.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #0a0a0a #0a0a0a !important}.button.is-black.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-black.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}.button.is-light{background-color:#f5f5f5;border-color:transparent;color:rgba(0,0,0,0.7)}.button.is-light:hover,.button.is-light.is-hovered{background-color:#eee;border-color:transparent;color:rgba(0,0,0,0.7)}.button.is-light:focus,.button.is-light.is-focused{border-color:transparent;color:rgba(0,0,0,0.7)}.button.is-light:focus:not(:active),.button.is-light.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(245,245,245,0.25)}.button.is-light:active,.button.is-light.is-active{background-color:#e8e8e8;border-color:transparent;color:rgba(0,0,0,0.7)}.button.is-light[disabled],fieldset[disabled] .button.is-light{background-color:#f5f5f5;border-color:#f5f5f5;box-shadow:none}.button.is-light.is-inverted{background-color:rgba(0,0,0,0.7);color:#f5f5f5}.button.is-light.is-inverted:hover,.button.is-light.is-inverted.is-hovered{background-color:rgba(0,0,0,0.7)}.button.is-light.is-inverted[disabled],fieldset[disabled] .button.is-light.is-inverted{background-color:rgba(0,0,0,0.7);border-color:transparent;box-shadow:none;color:#f5f5f5}.button.is-light.is-loading::after{border-color:transparent transparent rgba(0,0,0,0.7) rgba(0,0,0,0.7) !important}.button.is-light.is-outlined{background-color:transparent;border-color:#f5f5f5;color:#f5f5f5}.button.is-light.is-outlined:hover,.button.is-light.is-outlined.is-hovered,.button.is-light.is-outlined:focus,.button.is-light.is-outlined.is-focused{background-color:#f5f5f5;border-color:#f5f5f5;color:rgba(0,0,0,0.7)}.button.is-light.is-outlined.is-loading::after{border-color:transparent transparent #f5f5f5 #f5f5f5 !important}.button.is-light.is-outlined.is-loading:hover::after,.button.is-light.is-outlined.is-loading.is-hovered::after,.button.is-light.is-outlined.is-loading:focus::after,.button.is-light.is-outlined.is-loading.is-focused::after{border-color:transparent transparent rgba(0,0,0,0.7) rgba(0,0,0,0.7) !important}.button.is-light.is-outlined[disabled],fieldset[disabled] .button.is-light.is-outlined{background-color:transparent;border-color:#f5f5f5;box-shadow:none;color:#f5f5f5}.button.is-light.is-inverted.is-outlined{background-color:transparent;border-color:rgba(0,0,0,0.7);color:rgba(0,0,0,0.7)}.button.is-light.is-inverted.is-outlined:hover,.button.is-light.is-inverted.is-outlined.is-hovered,.button.is-light.is-inverted.is-outlined:focus,.button.is-light.is-inverted.is-outlined.is-focused{background-color:rgba(0,0,0,0.7);color:#f5f5f5}.button.is-light.is-inverted.is-outlined.is-loading:hover::after,.button.is-light.is-inverted.is-outlined.is-loading.is-hovered::after,.button.is-light.is-inverted.is-outlined.is-loading:focus::after,.button.is-light.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #f5f5f5 #f5f5f5 !important}.button.is-light.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-light.is-inverted.is-outlined{background-color:transparent;border-color:rgba(0,0,0,0.7);box-shadow:none;color:rgba(0,0,0,0.7)}.button.is-dark,.content kbd.button{background-color:#363636;border-color:transparent;color:#fff}.button.is-dark:hover,.content kbd.button:hover,.button.is-dark.is-hovered,.content kbd.button.is-hovered{background-color:#2f2f2f;border-color:transparent;color:#fff}.button.is-dark:focus,.content kbd.button:focus,.button.is-dark.is-focused,.content kbd.button.is-focused{border-color:transparent;color:#fff}.button.is-dark:focus:not(:active),.content kbd.button:focus:not(:active),.button.is-dark.is-focused:not(:active),.content kbd.button.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(54,54,54,0.25)}.button.is-dark:active,.content kbd.button:active,.button.is-dark.is-active,.content kbd.button.is-active{background-color:#292929;border-color:transparent;color:#fff}.button.is-dark[disabled],.content kbd.button[disabled],fieldset[disabled] .button.is-dark,fieldset[disabled] .content kbd.button,.content fieldset[disabled] kbd.button{background-color:#363636;border-color:#363636;box-shadow:none}.button.is-dark.is-inverted,.content kbd.button.is-inverted{background-color:#fff;color:#363636}.button.is-dark.is-inverted:hover,.content kbd.button.is-inverted:hover,.button.is-dark.is-inverted.is-hovered,.content kbd.button.is-inverted.is-hovered{background-color:#f2f2f2}.button.is-dark.is-inverted[disabled],.content kbd.button.is-inverted[disabled],fieldset[disabled] .button.is-dark.is-inverted,fieldset[disabled] .content kbd.button.is-inverted,.content fieldset[disabled] kbd.button.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#363636}.button.is-dark.is-loading::after,.content kbd.button.is-loading::after{border-color:transparent transparent #fff #fff !important}.button.is-dark.is-outlined,.content kbd.button.is-outlined{background-color:transparent;border-color:#363636;color:#363636}.button.is-dark.is-outlined:hover,.content kbd.button.is-outlined:hover,.button.is-dark.is-outlined.is-hovered,.content kbd.button.is-outlined.is-hovered,.button.is-dark.is-outlined:focus,.content kbd.button.is-outlined:focus,.button.is-dark.is-outlined.is-focused,.content kbd.button.is-outlined.is-focused{background-color:#363636;border-color:#363636;color:#fff}.button.is-dark.is-outlined.is-loading::after,.content kbd.button.is-outlined.is-loading::after{border-color:transparent transparent #363636 #363636 !important}.button.is-dark.is-outlined.is-loading:hover::after,.content kbd.button.is-outlined.is-loading:hover::after,.button.is-dark.is-outlined.is-loading.is-hovered::after,.content kbd.button.is-outlined.is-loading.is-hovered::after,.button.is-dark.is-outlined.is-loading:focus::after,.content kbd.button.is-outlined.is-loading:focus::after,.button.is-dark.is-outlined.is-loading.is-focused::after,.content kbd.button.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}.button.is-dark.is-outlined[disabled],.content kbd.button.is-outlined[disabled],fieldset[disabled] .button.is-dark.is-outlined,fieldset[disabled] .content kbd.button.is-outlined,.content fieldset[disabled] kbd.button.is-outlined{background-color:transparent;border-color:#363636;box-shadow:none;color:#363636}.button.is-dark.is-inverted.is-outlined,.content kbd.button.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}.button.is-dark.is-inverted.is-outlined:hover,.content kbd.button.is-inverted.is-outlined:hover,.button.is-dark.is-inverted.is-outlined.is-hovered,.content kbd.button.is-inverted.is-outlined.is-hovered,.button.is-dark.is-inverted.is-outlined:focus,.content kbd.button.is-inverted.is-outlined:focus,.button.is-dark.is-inverted.is-outlined.is-focused,.content kbd.button.is-inverted.is-outlined.is-focused{background-color:#fff;color:#363636}.button.is-dark.is-inverted.is-outlined.is-loading:hover::after,.content kbd.button.is-inverted.is-outlined.is-loading:hover::after,.button.is-dark.is-inverted.is-outlined.is-loading.is-hovered::after,.content kbd.button.is-inverted.is-outlined.is-loading.is-hovered::after,.button.is-dark.is-inverted.is-outlined.is-loading:focus::after,.content kbd.button.is-inverted.is-outlined.is-loading:focus::after,.button.is-dark.is-inverted.is-outlined.is-loading.is-focused::after,.content kbd.button.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #363636 #363636 !important}.button.is-dark.is-inverted.is-outlined[disabled],.content kbd.button.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-dark.is-inverted.is-outlined,fieldset[disabled] .content kbd.button.is-inverted.is-outlined,.content fieldset[disabled] kbd.button.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}.button.is-primary,.docstring>section>a.button.docs-sourcelink{background-color:#4eb5de;border-color:transparent;color:#fff}.button.is-primary:hover,.docstring>section>a.button.docs-sourcelink:hover,.button.is-primary.is-hovered,.docstring>section>a.button.is-hovered.docs-sourcelink{background-color:#43b1dc;border-color:transparent;color:#fff}.button.is-primary:focus,.docstring>section>a.button.docs-sourcelink:focus,.button.is-primary.is-focused,.docstring>section>a.button.is-focused.docs-sourcelink{border-color:transparent;color:#fff}.button.is-primary:focus:not(:active),.docstring>section>a.button.docs-sourcelink:focus:not(:active),.button.is-primary.is-focused:not(:active),.docstring>section>a.button.is-focused.docs-sourcelink:not(:active){box-shadow:0 0 0 0.125em rgba(78,181,222,0.25)}.button.is-primary:active,.docstring>section>a.button.docs-sourcelink:active,.button.is-primary.is-active,.docstring>section>a.button.is-active.docs-sourcelink{background-color:#39acda;border-color:transparent;color:#fff}.button.is-primary[disabled],.docstring>section>a.button.docs-sourcelink[disabled],fieldset[disabled] .button.is-primary,fieldset[disabled] .docstring>section>a.button.docs-sourcelink{background-color:#4eb5de;border-color:#4eb5de;box-shadow:none}.button.is-primary.is-inverted,.docstring>section>a.button.is-inverted.docs-sourcelink{background-color:#fff;color:#4eb5de}.button.is-primary.is-inverted:hover,.docstring>section>a.button.is-inverted.docs-sourcelink:hover,.button.is-primary.is-inverted.is-hovered,.docstring>section>a.button.is-inverted.is-hovered.docs-sourcelink{background-color:#f2f2f2}.button.is-primary.is-inverted[disabled],.docstring>section>a.button.is-inverted.docs-sourcelink[disabled],fieldset[disabled] .button.is-primary.is-inverted,fieldset[disabled] .docstring>section>a.button.is-inverted.docs-sourcelink{background-color:#fff;border-color:transparent;box-shadow:none;color:#4eb5de}.button.is-primary.is-loading::after,.docstring>section>a.button.is-loading.docs-sourcelink::after{border-color:transparent transparent #fff #fff !important}.button.is-primary.is-outlined,.docstring>section>a.button.is-outlined.docs-sourcelink{background-color:transparent;border-color:#4eb5de;color:#4eb5de}.button.is-primary.is-outlined:hover,.docstring>section>a.button.is-outlined.docs-sourcelink:hover,.button.is-primary.is-outlined.is-hovered,.docstring>section>a.button.is-outlined.is-hovered.docs-sourcelink,.button.is-primary.is-outlined:focus,.docstring>section>a.button.is-outlined.docs-sourcelink:focus,.button.is-primary.is-outlined.is-focused,.docstring>section>a.button.is-outlined.is-focused.docs-sourcelink{background-color:#4eb5de;border-color:#4eb5de;color:#fff}.button.is-primary.is-outlined.is-loading::after,.docstring>section>a.button.is-outlined.is-loading.docs-sourcelink::after{border-color:transparent transparent #4eb5de #4eb5de !important}.button.is-primary.is-outlined.is-loading:hover::after,.docstring>section>a.button.is-outlined.is-loading.docs-sourcelink:hover::after,.button.is-primary.is-outlined.is-loading.is-hovered::after,.docstring>section>a.button.is-outlined.is-loading.is-hovered.docs-sourcelink::after,.button.is-primary.is-outlined.is-loading:focus::after,.docstring>section>a.button.is-outlined.is-loading.docs-sourcelink:focus::after,.button.is-primary.is-outlined.is-loading.is-focused::after,.docstring>section>a.button.is-outlined.is-loading.is-focused.docs-sourcelink::after{border-color:transparent transparent #fff #fff !important}.button.is-primary.is-outlined[disabled],.docstring>section>a.button.is-outlined.docs-sourcelink[disabled],fieldset[disabled] .button.is-primary.is-outlined,fieldset[disabled] .docstring>section>a.button.is-outlined.docs-sourcelink{background-color:transparent;border-color:#4eb5de;box-shadow:none;color:#4eb5de}.button.is-primary.is-inverted.is-outlined,.docstring>section>a.button.is-inverted.is-outlined.docs-sourcelink{background-color:transparent;border-color:#fff;color:#fff}.button.is-primary.is-inverted.is-outlined:hover,.docstring>section>a.button.is-inverted.is-outlined.docs-sourcelink:hover,.button.is-primary.is-inverted.is-outlined.is-hovered,.docstring>section>a.button.is-inverted.is-outlined.is-hovered.docs-sourcelink,.button.is-primary.is-inverted.is-outlined:focus,.docstring>section>a.button.is-inverted.is-outlined.docs-sourcelink:focus,.button.is-primary.is-inverted.is-outlined.is-focused,.docstring>section>a.button.is-inverted.is-outlined.is-focused.docs-sourcelink{background-color:#fff;color:#4eb5de}.button.is-primary.is-inverted.is-outlined.is-loading:hover::after,.docstring>section>a.button.is-inverted.is-outlined.is-loading.docs-sourcelink:hover::after,.button.is-primary.is-inverted.is-outlined.is-loading.is-hovered::after,.docstring>section>a.button.is-inverted.is-outlined.is-loading.is-hovered.docs-sourcelink::after,.button.is-primary.is-inverted.is-outlined.is-loading:focus::after,.docstring>section>a.button.is-inverted.is-outlined.is-loading.docs-sourcelink:focus::after,.button.is-primary.is-inverted.is-outlined.is-loading.is-focused::after,.docstring>section>a.button.is-inverted.is-outlined.is-loading.is-focused.docs-sourcelink::after{border-color:transparent transparent #4eb5de #4eb5de !important}.button.is-primary.is-inverted.is-outlined[disabled],.docstring>section>a.button.is-inverted.is-outlined.docs-sourcelink[disabled],fieldset[disabled] .button.is-primary.is-inverted.is-outlined,fieldset[disabled] .docstring>section>a.button.is-inverted.is-outlined.docs-sourcelink{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}.button.is-primary.is-light,.docstring>section>a.button.is-light.docs-sourcelink{background-color:#eef8fc;color:#1a6d8e}.button.is-primary.is-light:hover,.docstring>section>a.button.is-light.docs-sourcelink:hover,.button.is-primary.is-light.is-hovered,.docstring>section>a.button.is-light.is-hovered.docs-sourcelink{background-color:#e3f3fa;border-color:transparent;color:#1a6d8e}.button.is-primary.is-light:active,.docstring>section>a.button.is-light.docs-sourcelink:active,.button.is-primary.is-light.is-active,.docstring>section>a.button.is-light.is-active.docs-sourcelink{background-color:#d8eff8;border-color:transparent;color:#1a6d8e}.button.is-link{background-color:#2e63b8;border-color:transparent;color:#fff}.button.is-link:hover,.button.is-link.is-hovered{background-color:#2b5eae;border-color:transparent;color:#fff}.button.is-link:focus,.button.is-link.is-focused{border-color:transparent;color:#fff}.button.is-link:focus:not(:active),.button.is-link.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(46,99,184,0.25)}.button.is-link:active,.button.is-link.is-active{background-color:#2958a4;border-color:transparent;color:#fff}.button.is-link[disabled],fieldset[disabled] .button.is-link{background-color:#2e63b8;border-color:#2e63b8;box-shadow:none}.button.is-link.is-inverted{background-color:#fff;color:#2e63b8}.button.is-link.is-inverted:hover,.button.is-link.is-inverted.is-hovered{background-color:#f2f2f2}.button.is-link.is-inverted[disabled],fieldset[disabled] .button.is-link.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#2e63b8}.button.is-link.is-loading::after{border-color:transparent transparent #fff #fff !important}.button.is-link.is-outlined{background-color:transparent;border-color:#2e63b8;color:#2e63b8}.button.is-link.is-outlined:hover,.button.is-link.is-outlined.is-hovered,.button.is-link.is-outlined:focus,.button.is-link.is-outlined.is-focused{background-color:#2e63b8;border-color:#2e63b8;color:#fff}.button.is-link.is-outlined.is-loading::after{border-color:transparent transparent #2e63b8 #2e63b8 !important}.button.is-link.is-outlined.is-loading:hover::after,.button.is-link.is-outlined.is-loading.is-hovered::after,.button.is-link.is-outlined.is-loading:focus::after,.button.is-link.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}.button.is-link.is-outlined[disabled],fieldset[disabled] .button.is-link.is-outlined{background-color:transparent;border-color:#2e63b8;box-shadow:none;color:#2e63b8}.button.is-link.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}.button.is-link.is-inverted.is-outlined:hover,.button.is-link.is-inverted.is-outlined.is-hovered,.button.is-link.is-inverted.is-outlined:focus,.button.is-link.is-inverted.is-outlined.is-focused{background-color:#fff;color:#2e63b8}.button.is-link.is-inverted.is-outlined.is-loading:hover::after,.button.is-link.is-inverted.is-outlined.is-loading.is-hovered::after,.button.is-link.is-inverted.is-outlined.is-loading:focus::after,.button.is-link.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #2e63b8 #2e63b8 !important}.button.is-link.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-link.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}.button.is-link.is-light{background-color:#eff3fb;color:#3169c4}.button.is-link.is-light:hover,.button.is-link.is-light.is-hovered{background-color:#e4ecf8;border-color:transparent;color:#3169c4}.button.is-link.is-light:active,.button.is-link.is-light.is-active{background-color:#dae5f6;border-color:transparent;color:#3169c4}.button.is-info{background-color:#209cee;border-color:transparent;color:#fff}.button.is-info:hover,.button.is-info.is-hovered{background-color:#1497ed;border-color:transparent;color:#fff}.button.is-info:focus,.button.is-info.is-focused{border-color:transparent;color:#fff}.button.is-info:focus:not(:active),.button.is-info.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(32,156,238,0.25)}.button.is-info:active,.button.is-info.is-active{background-color:#1190e3;border-color:transparent;color:#fff}.button.is-info[disabled],fieldset[disabled] .button.is-info{background-color:#209cee;border-color:#209cee;box-shadow:none}.button.is-info.is-inverted{background-color:#fff;color:#209cee}.button.is-info.is-inverted:hover,.button.is-info.is-inverted.is-hovered{background-color:#f2f2f2}.button.is-info.is-inverted[disabled],fieldset[disabled] .button.is-info.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#209cee}.button.is-info.is-loading::after{border-color:transparent transparent #fff #fff !important}.button.is-info.is-outlined{background-color:transparent;border-color:#209cee;color:#209cee}.button.is-info.is-outlined:hover,.button.is-info.is-outlined.is-hovered,.button.is-info.is-outlined:focus,.button.is-info.is-outlined.is-focused{background-color:#209cee;border-color:#209cee;color:#fff}.button.is-info.is-outlined.is-loading::after{border-color:transparent transparent #209cee #209cee !important}.button.is-info.is-outlined.is-loading:hover::after,.button.is-info.is-outlined.is-loading.is-hovered::after,.button.is-info.is-outlined.is-loading:focus::after,.button.is-info.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}.button.is-info.is-outlined[disabled],fieldset[disabled] .button.is-info.is-outlined{background-color:transparent;border-color:#209cee;box-shadow:none;color:#209cee}.button.is-info.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}.button.is-info.is-inverted.is-outlined:hover,.button.is-info.is-inverted.is-outlined.is-hovered,.button.is-info.is-inverted.is-outlined:focus,.button.is-info.is-inverted.is-outlined.is-focused{background-color:#fff;color:#209cee}.button.is-info.is-inverted.is-outlined.is-loading:hover::after,.button.is-info.is-inverted.is-outlined.is-loading.is-hovered::after,.button.is-info.is-inverted.is-outlined.is-loading:focus::after,.button.is-info.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #209cee #209cee !important}.button.is-info.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-info.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}.button.is-info.is-light{background-color:#ecf7fe;color:#0e72b4}.button.is-info.is-light:hover,.button.is-info.is-light.is-hovered{background-color:#e0f1fd;border-color:transparent;color:#0e72b4}.button.is-info.is-light:active,.button.is-info.is-light.is-active{background-color:#d4ecfc;border-color:transparent;color:#0e72b4}.button.is-success{background-color:#22c35b;border-color:transparent;color:#fff}.button.is-success:hover,.button.is-success.is-hovered{background-color:#20b856;border-color:transparent;color:#fff}.button.is-success:focus,.button.is-success.is-focused{border-color:transparent;color:#fff}.button.is-success:focus:not(:active),.button.is-success.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(34,195,91,0.25)}.button.is-success:active,.button.is-success.is-active{background-color:#1ead51;border-color:transparent;color:#fff}.button.is-success[disabled],fieldset[disabled] .button.is-success{background-color:#22c35b;border-color:#22c35b;box-shadow:none}.button.is-success.is-inverted{background-color:#fff;color:#22c35b}.button.is-success.is-inverted:hover,.button.is-success.is-inverted.is-hovered{background-color:#f2f2f2}.button.is-success.is-inverted[disabled],fieldset[disabled] .button.is-success.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#22c35b}.button.is-success.is-loading::after{border-color:transparent transparent #fff #fff !important}.button.is-success.is-outlined{background-color:transparent;border-color:#22c35b;color:#22c35b}.button.is-success.is-outlined:hover,.button.is-success.is-outlined.is-hovered,.button.is-success.is-outlined:focus,.button.is-success.is-outlined.is-focused{background-color:#22c35b;border-color:#22c35b;color:#fff}.button.is-success.is-outlined.is-loading::after{border-color:transparent transparent #22c35b #22c35b !important}.button.is-success.is-outlined.is-loading:hover::after,.button.is-success.is-outlined.is-loading.is-hovered::after,.button.is-success.is-outlined.is-loading:focus::after,.button.is-success.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}.button.is-success.is-outlined[disabled],fieldset[disabled] .button.is-success.is-outlined{background-color:transparent;border-color:#22c35b;box-shadow:none;color:#22c35b}.button.is-success.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}.button.is-success.is-inverted.is-outlined:hover,.button.is-success.is-inverted.is-outlined.is-hovered,.button.is-success.is-inverted.is-outlined:focus,.button.is-success.is-inverted.is-outlined.is-focused{background-color:#fff;color:#22c35b}.button.is-success.is-inverted.is-outlined.is-loading:hover::after,.button.is-success.is-inverted.is-outlined.is-loading.is-hovered::after,.button.is-success.is-inverted.is-outlined.is-loading:focus::after,.button.is-success.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #22c35b #22c35b !important}.button.is-success.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-success.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}.button.is-success.is-light{background-color:#eefcf3;color:#198f43}.button.is-success.is-light:hover,.button.is-success.is-light.is-hovered{background-color:#e3faeb;border-color:transparent;color:#198f43}.button.is-success.is-light:active,.button.is-success.is-light.is-active{background-color:#d8f8e3;border-color:transparent;color:#198f43}.button.is-warning{background-color:#ffdd57;border-color:transparent;color:rgba(0,0,0,0.7)}.button.is-warning:hover,.button.is-warning.is-hovered{background-color:#ffda4a;border-color:transparent;color:rgba(0,0,0,0.7)}.button.is-warning:focus,.button.is-warning.is-focused{border-color:transparent;color:rgba(0,0,0,0.7)}.button.is-warning:focus:not(:active),.button.is-warning.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(255,221,87,0.25)}.button.is-warning:active,.button.is-warning.is-active{background-color:#ffd83e;border-color:transparent;color:rgba(0,0,0,0.7)}.button.is-warning[disabled],fieldset[disabled] .button.is-warning{background-color:#ffdd57;border-color:#ffdd57;box-shadow:none}.button.is-warning.is-inverted{background-color:rgba(0,0,0,0.7);color:#ffdd57}.button.is-warning.is-inverted:hover,.button.is-warning.is-inverted.is-hovered{background-color:rgba(0,0,0,0.7)}.button.is-warning.is-inverted[disabled],fieldset[disabled] .button.is-warning.is-inverted{background-color:rgba(0,0,0,0.7);border-color:transparent;box-shadow:none;color:#ffdd57}.button.is-warning.is-loading::after{border-color:transparent transparent rgba(0,0,0,0.7) rgba(0,0,0,0.7) !important}.button.is-warning.is-outlined{background-color:transparent;border-color:#ffdd57;color:#ffdd57}.button.is-warning.is-outlined:hover,.button.is-warning.is-outlined.is-hovered,.button.is-warning.is-outlined:focus,.button.is-warning.is-outlined.is-focused{background-color:#ffdd57;border-color:#ffdd57;color:rgba(0,0,0,0.7)}.button.is-warning.is-outlined.is-loading::after{border-color:transparent transparent #ffdd57 #ffdd57 !important}.button.is-warning.is-outlined.is-loading:hover::after,.button.is-warning.is-outlined.is-loading.is-hovered::after,.button.is-warning.is-outlined.is-loading:focus::after,.button.is-warning.is-outlined.is-loading.is-focused::after{border-color:transparent transparent rgba(0,0,0,0.7) rgba(0,0,0,0.7) !important}.button.is-warning.is-outlined[disabled],fieldset[disabled] .button.is-warning.is-outlined{background-color:transparent;border-color:#ffdd57;box-shadow:none;color:#ffdd57}.button.is-warning.is-inverted.is-outlined{background-color:transparent;border-color:rgba(0,0,0,0.7);color:rgba(0,0,0,0.7)}.button.is-warning.is-inverted.is-outlined:hover,.button.is-warning.is-inverted.is-outlined.is-hovered,.button.is-warning.is-inverted.is-outlined:focus,.button.is-warning.is-inverted.is-outlined.is-focused{background-color:rgba(0,0,0,0.7);color:#ffdd57}.button.is-warning.is-inverted.is-outlined.is-loading:hover::after,.button.is-warning.is-inverted.is-outlined.is-loading.is-hovered::after,.button.is-warning.is-inverted.is-outlined.is-loading:focus::after,.button.is-warning.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #ffdd57 #ffdd57 !important}.button.is-warning.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-warning.is-inverted.is-outlined{background-color:transparent;border-color:rgba(0,0,0,0.7);box-shadow:none;color:rgba(0,0,0,0.7)}.button.is-warning.is-light{background-color:#fffbeb;color:#947600}.button.is-warning.is-light:hover,.button.is-warning.is-light.is-hovered{background-color:#fff8de;border-color:transparent;color:#947600}.button.is-warning.is-light:active,.button.is-warning.is-light.is-active{background-color:#fff6d1;border-color:transparent;color:#947600}.button.is-danger{background-color:#da0b00;border-color:transparent;color:#fff}.button.is-danger:hover,.button.is-danger.is-hovered{background-color:#cd0a00;border-color:transparent;color:#fff}.button.is-danger:focus,.button.is-danger.is-focused{border-color:transparent;color:#fff}.button.is-danger:focus:not(:active),.button.is-danger.is-focused:not(:active){box-shadow:0 0 0 0.125em rgba(218,11,0,0.25)}.button.is-danger:active,.button.is-danger.is-active{background-color:#c10a00;border-color:transparent;color:#fff}.button.is-danger[disabled],fieldset[disabled] .button.is-danger{background-color:#da0b00;border-color:#da0b00;box-shadow:none}.button.is-danger.is-inverted{background-color:#fff;color:#da0b00}.button.is-danger.is-inverted:hover,.button.is-danger.is-inverted.is-hovered{background-color:#f2f2f2}.button.is-danger.is-inverted[disabled],fieldset[disabled] .button.is-danger.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#da0b00}.button.is-danger.is-loading::after{border-color:transparent transparent #fff #fff !important}.button.is-danger.is-outlined{background-color:transparent;border-color:#da0b00;color:#da0b00}.button.is-danger.is-outlined:hover,.button.is-danger.is-outlined.is-hovered,.button.is-danger.is-outlined:focus,.button.is-danger.is-outlined.is-focused{background-color:#da0b00;border-color:#da0b00;color:#fff}.button.is-danger.is-outlined.is-loading::after{border-color:transparent transparent #da0b00 #da0b00 !important}.button.is-danger.is-outlined.is-loading:hover::after,.button.is-danger.is-outlined.is-loading.is-hovered::after,.button.is-danger.is-outlined.is-loading:focus::after,.button.is-danger.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #fff #fff !important}.button.is-danger.is-outlined[disabled],fieldset[disabled] .button.is-danger.is-outlined{background-color:transparent;border-color:#da0b00;box-shadow:none;color:#da0b00}.button.is-danger.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}.button.is-danger.is-inverted.is-outlined:hover,.button.is-danger.is-inverted.is-outlined.is-hovered,.button.is-danger.is-inverted.is-outlined:focus,.button.is-danger.is-inverted.is-outlined.is-focused{background-color:#fff;color:#da0b00}.button.is-danger.is-inverted.is-outlined.is-loading:hover::after,.button.is-danger.is-inverted.is-outlined.is-loading.is-hovered::after,.button.is-danger.is-inverted.is-outlined.is-loading:focus::after,.button.is-danger.is-inverted.is-outlined.is-loading.is-focused::after{border-color:transparent transparent #da0b00 #da0b00 !important}.button.is-danger.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-danger.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}.button.is-danger.is-light{background-color:#ffeceb;color:#f50c00}.button.is-danger.is-light:hover,.button.is-danger.is-light.is-hovered{background-color:#ffe0de;border-color:transparent;color:#f50c00}.button.is-danger.is-light:active,.button.is-danger.is-light.is-active{background-color:#ffd3d1;border-color:transparent;color:#f50c00}.button.is-small,#documenter .docs-sidebar form.docs-search>input.button{font-size:.75rem}.button.is-small:not(.is-rounded),#documenter .docs-sidebar form.docs-search>input.button:not(.is-rounded){border-radius:2px}.button.is-normal{font-size:1rem}.button.is-medium{font-size:1.25rem}.button.is-large{font-size:1.5rem}.button[disabled],fieldset[disabled] .button{background-color:#fff;border-color:#dbdbdb;box-shadow:none;opacity:.5}.button.is-fullwidth{display:flex;width:100%}.button.is-loading{color:transparent !important;pointer-events:none}.button.is-loading::after{position:absolute;left:calc(50% - (1em * 0.5));top:calc(50% - (1em * 0.5));position:absolute !important}.button.is-static{background-color:#f5f5f5;border-color:#dbdbdb;color:#6b6b6b;box-shadow:none;pointer-events:none}.button.is-rounded,#documenter .docs-sidebar form.docs-search>input.button{border-radius:9999px;padding-left:calc(1em + 0.25em);padding-right:calc(1em + 0.25em)}.buttons{align-items:center;display:flex;flex-wrap:wrap;justify-content:flex-start}.buttons .button{margin-bottom:0.5rem}.buttons .button:not(:last-child):not(.is-fullwidth){margin-right:.5rem}.buttons:last-child{margin-bottom:-0.5rem}.buttons:not(:last-child){margin-bottom:1rem}.buttons.are-small .button:not(.is-normal):not(.is-medium):not(.is-large){font-size:.75rem}.buttons.are-small .button:not(.is-normal):not(.is-medium):not(.is-large):not(.is-rounded){border-radius:2px}.buttons.are-medium .button:not(.is-small):not(.is-normal):not(.is-large){font-size:1.25rem}.buttons.are-large .button:not(.is-small):not(.is-normal):not(.is-medium){font-size:1.5rem}.buttons.has-addons .button:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.buttons.has-addons .button:not(:last-child){border-bottom-right-radius:0;border-top-right-radius:0;margin-right:-1px}.buttons.has-addons .button:last-child{margin-right:0}.buttons.has-addons .button:hover,.buttons.has-addons .button.is-hovered{z-index:2}.buttons.has-addons .button:focus,.buttons.has-addons .button.is-focused,.buttons.has-addons .button:active,.buttons.has-addons .button.is-active,.buttons.has-addons .button.is-selected{z-index:3}.buttons.has-addons .button:focus:hover,.buttons.has-addons .button.is-focused:hover,.buttons.has-addons .button:active:hover,.buttons.has-addons .button.is-active:hover,.buttons.has-addons .button.is-selected:hover{z-index:4}.buttons.has-addons .button.is-expanded{flex-grow:1;flex-shrink:1}.buttons.is-centered{justify-content:center}.buttons.is-centered:not(.has-addons) .button:not(.is-fullwidth){margin-left:0.25rem;margin-right:0.25rem}.buttons.is-right{justify-content:flex-end}.buttons.is-right:not(.has-addons) .button:not(.is-fullwidth){margin-left:0.25rem;margin-right:0.25rem}@media screen and (max-width: 768px){.button.is-responsive.is-small,#documenter .docs-sidebar form.docs-search>input.is-responsive{font-size:.5625rem}.button.is-responsive,.button.is-responsive.is-normal{font-size:.65625rem}.button.is-responsive.is-medium{font-size:.75rem}.button.is-responsive.is-large{font-size:1rem}}@media screen and (min-width: 769px) and (max-width: 1055px){.button.is-responsive.is-small,#documenter .docs-sidebar form.docs-search>input.is-responsive{font-size:.65625rem}.button.is-responsive,.button.is-responsive.is-normal{font-size:.75rem}.button.is-responsive.is-medium{font-size:1rem}.button.is-responsive.is-large{font-size:1.25rem}}.container{flex-grow:1;margin:0 auto;position:relative;width:auto}.container.is-fluid{max-width:none !important;padding-left:32px;padding-right:32px;width:100%}@media screen and (min-width: 1056px){.container{max-width:992px}}@media screen and (max-width: 1215px){.container.is-widescreen:not(.is-max-desktop){max-width:1152px}}@media screen and (max-width: 1407px){.container.is-fullhd:not(.is-max-desktop):not(.is-max-widescreen){max-width:1344px}}@media screen and (min-width: 1216px){.container:not(.is-max-desktop){max-width:1152px}}@media screen and (min-width: 1408px){.container:not(.is-max-desktop):not(.is-max-widescreen){max-width:1344px}}.content li+li{margin-top:0.25em}.content p:not(:last-child),.content dl:not(:last-child),.content ol:not(:last-child),.content ul:not(:last-child),.content blockquote:not(:last-child),.content pre:not(:last-child),.content table:not(:last-child){margin-bottom:1em}.content h1,.content h2,.content h3,.content h4,.content h5,.content h6{color:#222;font-weight:600;line-height:1.125}.content h1{font-size:2em;margin-bottom:0.5em}.content h1:not(:first-child){margin-top:1em}.content h2{font-size:1.75em;margin-bottom:0.5714em}.content h2:not(:first-child){margin-top:1.1428em}.content h3{font-size:1.5em;margin-bottom:0.6666em}.content h3:not(:first-child){margin-top:1.3333em}.content h4{font-size:1.25em;margin-bottom:0.8em}.content h5{font-size:1.125em;margin-bottom:0.8888em}.content h6{font-size:1em;margin-bottom:1em}.content blockquote{background-color:#f5f5f5;border-left:5px solid #dbdbdb;padding:1.25em 1.5em}.content ol{list-style-position:outside;margin-left:2em;margin-top:1em}.content ol:not([type]){list-style-type:decimal}.content ol.is-lower-alpha:not([type]){list-style-type:lower-alpha}.content ol.is-lower-roman:not([type]){list-style-type:lower-roman}.content ol.is-upper-alpha:not([type]){list-style-type:upper-alpha}.content ol.is-upper-roman:not([type]){list-style-type:upper-roman}.content ul{list-style:disc outside;margin-left:2em;margin-top:1em}.content ul ul{list-style-type:circle;margin-top:0.5em}.content ul ul ul{list-style-type:square}.content dd{margin-left:2em}.content figure{margin-left:2em;margin-right:2em;text-align:center}.content figure:not(:first-child){margin-top:2em}.content figure:not(:last-child){margin-bottom:2em}.content figure img{display:inline-block}.content figure figcaption{font-style:italic}.content pre{-webkit-overflow-scrolling:touch;overflow-x:auto;padding:0;white-space:pre;word-wrap:normal}.content sup,.content sub{font-size:75%}.content table{width:100%}.content table td,.content table th{border:1px solid #dbdbdb;border-width:0 0 1px;padding:0.5em 0.75em;vertical-align:top}.content table th{color:#222}.content table th:not([align]){text-align:inherit}.content table thead td,.content table thead th{border-width:0 0 2px;color:#222}.content table tfoot td,.content table tfoot th{border-width:2px 0 0;color:#222}.content table tbody tr:last-child td,.content table tbody tr:last-child th{border-bottom-width:0}.content .tabs li+li{margin-top:0}.content.is-small,#documenter .docs-sidebar form.docs-search>input.content{font-size:.75rem}.content.is-normal{font-size:1rem}.content.is-medium{font-size:1.25rem}.content.is-large{font-size:1.5rem}.icon{align-items:center;display:inline-flex;justify-content:center;height:1.5rem;width:1.5rem}.icon.is-small,#documenter .docs-sidebar form.docs-search>input.icon{height:1rem;width:1rem}.icon.is-medium{height:2rem;width:2rem}.icon.is-large{height:3rem;width:3rem}.icon-text{align-items:flex-start;color:inherit;display:inline-flex;flex-wrap:wrap;line-height:1.5rem;vertical-align:top}.icon-text .icon{flex-grow:0;flex-shrink:0}.icon-text .icon:not(:last-child){margin-right:.25em}.icon-text .icon:not(:first-child){margin-left:.25em}div.icon-text{display:flex}.image,#documenter .docs-sidebar .docs-logo>img{display:block;position:relative}.image img,#documenter .docs-sidebar .docs-logo>img img{display:block;height:auto;width:100%}.image img.is-rounded,#documenter .docs-sidebar .docs-logo>img img.is-rounded{border-radius:9999px}.image.is-fullwidth,#documenter .docs-sidebar .docs-logo>img.is-fullwidth{width:100%}.image.is-square img,#documenter .docs-sidebar .docs-logo>img.is-square img,.image.is-square .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-square .has-ratio,.image.is-1by1 img,#documenter .docs-sidebar .docs-logo>img.is-1by1 img,.image.is-1by1 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-1by1 .has-ratio,.image.is-5by4 img,#documenter .docs-sidebar .docs-logo>img.is-5by4 img,.image.is-5by4 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-5by4 .has-ratio,.image.is-4by3 img,#documenter .docs-sidebar .docs-logo>img.is-4by3 img,.image.is-4by3 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-4by3 .has-ratio,.image.is-3by2 img,#documenter .docs-sidebar .docs-logo>img.is-3by2 img,.image.is-3by2 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-3by2 .has-ratio,.image.is-5by3 img,#documenter .docs-sidebar .docs-logo>img.is-5by3 img,.image.is-5by3 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-5by3 .has-ratio,.image.is-16by9 img,#documenter .docs-sidebar .docs-logo>img.is-16by9 img,.image.is-16by9 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-16by9 .has-ratio,.image.is-2by1 img,#documenter .docs-sidebar .docs-logo>img.is-2by1 img,.image.is-2by1 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-2by1 .has-ratio,.image.is-3by1 img,#documenter .docs-sidebar .docs-logo>img.is-3by1 img,.image.is-3by1 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-3by1 .has-ratio,.image.is-4by5 img,#documenter .docs-sidebar .docs-logo>img.is-4by5 img,.image.is-4by5 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-4by5 .has-ratio,.image.is-3by4 img,#documenter .docs-sidebar .docs-logo>img.is-3by4 img,.image.is-3by4 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-3by4 .has-ratio,.image.is-2by3 img,#documenter .docs-sidebar .docs-logo>img.is-2by3 img,.image.is-2by3 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-2by3 .has-ratio,.image.is-3by5 img,#documenter .docs-sidebar .docs-logo>img.is-3by5 img,.image.is-3by5 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-3by5 .has-ratio,.image.is-9by16 img,#documenter .docs-sidebar .docs-logo>img.is-9by16 img,.image.is-9by16 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-9by16 .has-ratio,.image.is-1by2 img,#documenter .docs-sidebar .docs-logo>img.is-1by2 img,.image.is-1by2 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-1by2 .has-ratio,.image.is-1by3 img,#documenter .docs-sidebar .docs-logo>img.is-1by3 img,.image.is-1by3 .has-ratio,#documenter .docs-sidebar .docs-logo>img.is-1by3 .has-ratio{height:100%;width:100%}.image.is-square,#documenter .docs-sidebar .docs-logo>img.is-square,.image.is-1by1,#documenter .docs-sidebar .docs-logo>img.is-1by1{padding-top:100%}.image.is-5by4,#documenter .docs-sidebar .docs-logo>img.is-5by4{padding-top:80%}.image.is-4by3,#documenter .docs-sidebar .docs-logo>img.is-4by3{padding-top:75%}.image.is-3by2,#documenter .docs-sidebar .docs-logo>img.is-3by2{padding-top:66.6666%}.image.is-5by3,#documenter .docs-sidebar .docs-logo>img.is-5by3{padding-top:60%}.image.is-16by9,#documenter .docs-sidebar .docs-logo>img.is-16by9{padding-top:56.25%}.image.is-2by1,#documenter .docs-sidebar .docs-logo>img.is-2by1{padding-top:50%}.image.is-3by1,#documenter .docs-sidebar .docs-logo>img.is-3by1{padding-top:33.3333%}.image.is-4by5,#documenter .docs-sidebar .docs-logo>img.is-4by5{padding-top:125%}.image.is-3by4,#documenter .docs-sidebar .docs-logo>img.is-3by4{padding-top:133.3333%}.image.is-2by3,#documenter .docs-sidebar .docs-logo>img.is-2by3{padding-top:150%}.image.is-3by5,#documenter .docs-sidebar .docs-logo>img.is-3by5{padding-top:166.6666%}.image.is-9by16,#documenter .docs-sidebar .docs-logo>img.is-9by16{padding-top:177.7777%}.image.is-1by2,#documenter .docs-sidebar .docs-logo>img.is-1by2{padding-top:200%}.image.is-1by3,#documenter .docs-sidebar .docs-logo>img.is-1by3{padding-top:300%}.image.is-16x16,#documenter .docs-sidebar .docs-logo>img.is-16x16{height:16px;width:16px}.image.is-24x24,#documenter .docs-sidebar .docs-logo>img.is-24x24{height:24px;width:24px}.image.is-32x32,#documenter .docs-sidebar .docs-logo>img.is-32x32{height:32px;width:32px}.image.is-48x48,#documenter .docs-sidebar .docs-logo>img.is-48x48{height:48px;width:48px}.image.is-64x64,#documenter .docs-sidebar .docs-logo>img.is-64x64{height:64px;width:64px}.image.is-96x96,#documenter .docs-sidebar .docs-logo>img.is-96x96{height:96px;width:96px}.image.is-128x128,#documenter .docs-sidebar .docs-logo>img.is-128x128{height:128px;width:128px}.notification{background-color:#f5f5f5;border-radius:4px;position:relative;padding:1.25rem 2.5rem 1.25rem 1.5rem}.notification a:not(.button):not(.dropdown-item){color:currentColor;text-decoration:underline}.notification strong{color:currentColor}.notification code,.notification pre{background:#fff}.notification pre code{background:transparent}.notification>.delete{right:.5rem;position:absolute;top:0.5rem}.notification .title,.notification .subtitle,.notification .content{color:currentColor}.notification.is-white{background-color:#fff;color:#0a0a0a}.notification.is-black{background-color:#0a0a0a;color:#fff}.notification.is-light{background-color:#f5f5f5;color:rgba(0,0,0,0.7)}.notification.is-dark,.content kbd.notification{background-color:#363636;color:#fff}.notification.is-primary,.docstring>section>a.notification.docs-sourcelink{background-color:#4eb5de;color:#fff}.notification.is-primary.is-light,.docstring>section>a.notification.is-light.docs-sourcelink{background-color:#eef8fc;color:#1a6d8e}.notification.is-link{background-color:#2e63b8;color:#fff}.notification.is-link.is-light{background-color:#eff3fb;color:#3169c4}.notification.is-info{background-color:#209cee;color:#fff}.notification.is-info.is-light{background-color:#ecf7fe;color:#0e72b4}.notification.is-success{background-color:#22c35b;color:#fff}.notification.is-success.is-light{background-color:#eefcf3;color:#198f43}.notification.is-warning{background-color:#ffdd57;color:rgba(0,0,0,0.7)}.notification.is-warning.is-light{background-color:#fffbeb;color:#947600}.notification.is-danger{background-color:#da0b00;color:#fff}.notification.is-danger.is-light{background-color:#ffeceb;color:#f50c00}.progress{-moz-appearance:none;-webkit-appearance:none;border:none;border-radius:9999px;display:block;height:1rem;overflow:hidden;padding:0;width:100%}.progress::-webkit-progress-bar{background-color:#ededed}.progress::-webkit-progress-value{background-color:#222}.progress::-moz-progress-bar{background-color:#222}.progress::-ms-fill{background-color:#222;border:none}.progress.is-white::-webkit-progress-value{background-color:#fff}.progress.is-white::-moz-progress-bar{background-color:#fff}.progress.is-white::-ms-fill{background-color:#fff}.progress.is-white:indeterminate{background-image:linear-gradient(to right, #fff 30%, #ededed 30%)}.progress.is-black::-webkit-progress-value{background-color:#0a0a0a}.progress.is-black::-moz-progress-bar{background-color:#0a0a0a}.progress.is-black::-ms-fill{background-color:#0a0a0a}.progress.is-black:indeterminate{background-image:linear-gradient(to right, #0a0a0a 30%, #ededed 30%)}.progress.is-light::-webkit-progress-value{background-color:#f5f5f5}.progress.is-light::-moz-progress-bar{background-color:#f5f5f5}.progress.is-light::-ms-fill{background-color:#f5f5f5}.progress.is-light:indeterminate{background-image:linear-gradient(to right, #f5f5f5 30%, #ededed 30%)}.progress.is-dark::-webkit-progress-value,.content kbd.progress::-webkit-progress-value{background-color:#363636}.progress.is-dark::-moz-progress-bar,.content kbd.progress::-moz-progress-bar{background-color:#363636}.progress.is-dark::-ms-fill,.content kbd.progress::-ms-fill{background-color:#363636}.progress.is-dark:indeterminate,.content kbd.progress:indeterminate{background-image:linear-gradient(to right, #363636 30%, #ededed 30%)}.progress.is-primary::-webkit-progress-value,.docstring>section>a.progress.docs-sourcelink::-webkit-progress-value{background-color:#4eb5de}.progress.is-primary::-moz-progress-bar,.docstring>section>a.progress.docs-sourcelink::-moz-progress-bar{background-color:#4eb5de}.progress.is-primary::-ms-fill,.docstring>section>a.progress.docs-sourcelink::-ms-fill{background-color:#4eb5de}.progress.is-primary:indeterminate,.docstring>section>a.progress.docs-sourcelink:indeterminate{background-image:linear-gradient(to right, #4eb5de 30%, #ededed 30%)}.progress.is-link::-webkit-progress-value{background-color:#2e63b8}.progress.is-link::-moz-progress-bar{background-color:#2e63b8}.progress.is-link::-ms-fill{background-color:#2e63b8}.progress.is-link:indeterminate{background-image:linear-gradient(to right, #2e63b8 30%, #ededed 30%)}.progress.is-info::-webkit-progress-value{background-color:#209cee}.progress.is-info::-moz-progress-bar{background-color:#209cee}.progress.is-info::-ms-fill{background-color:#209cee}.progress.is-info:indeterminate{background-image:linear-gradient(to right, #209cee 30%, #ededed 30%)}.progress.is-success::-webkit-progress-value{background-color:#22c35b}.progress.is-success::-moz-progress-bar{background-color:#22c35b}.progress.is-success::-ms-fill{background-color:#22c35b}.progress.is-success:indeterminate{background-image:linear-gradient(to right, #22c35b 30%, #ededed 30%)}.progress.is-warning::-webkit-progress-value{background-color:#ffdd57}.progress.is-warning::-moz-progress-bar{background-color:#ffdd57}.progress.is-warning::-ms-fill{background-color:#ffdd57}.progress.is-warning:indeterminate{background-image:linear-gradient(to right, #ffdd57 30%, #ededed 30%)}.progress.is-danger::-webkit-progress-value{background-color:#da0b00}.progress.is-danger::-moz-progress-bar{background-color:#da0b00}.progress.is-danger::-ms-fill{background-color:#da0b00}.progress.is-danger:indeterminate{background-image:linear-gradient(to right, #da0b00 30%, #ededed 30%)}.progress:indeterminate{animation-duration:1.5s;animation-iteration-count:infinite;animation-name:moveIndeterminate;animation-timing-function:linear;background-color:#ededed;background-image:linear-gradient(to right, #222 30%, #ededed 30%);background-position:top left;background-repeat:no-repeat;background-size:150% 150%}.progress:indeterminate::-webkit-progress-bar{background-color:transparent}.progress:indeterminate::-moz-progress-bar{background-color:transparent}.progress:indeterminate::-ms-fill{animation-name:none}.progress.is-small,#documenter .docs-sidebar form.docs-search>input.progress{height:.75rem}.progress.is-medium{height:1.25rem}.progress.is-large{height:1.5rem}@keyframes moveIndeterminate{from{background-position:200% 0}to{background-position:-200% 0}}.table{background-color:#fff;color:#222}.table td,.table th{border:1px solid #dbdbdb;border-width:0 0 1px;padding:0.5em 0.75em;vertical-align:top}.table td.is-white,.table th.is-white{background-color:#fff;border-color:#fff;color:#0a0a0a}.table td.is-black,.table th.is-black{background-color:#0a0a0a;border-color:#0a0a0a;color:#fff}.table td.is-light,.table th.is-light{background-color:#f5f5f5;border-color:#f5f5f5;color:rgba(0,0,0,0.7)}.table td.is-dark,.table th.is-dark{background-color:#363636;border-color:#363636;color:#fff}.table td.is-primary,.table th.is-primary{background-color:#4eb5de;border-color:#4eb5de;color:#fff}.table td.is-link,.table th.is-link{background-color:#2e63b8;border-color:#2e63b8;color:#fff}.table td.is-info,.table th.is-info{background-color:#209cee;border-color:#209cee;color:#fff}.table td.is-success,.table th.is-success{background-color:#22c35b;border-color:#22c35b;color:#fff}.table td.is-warning,.table th.is-warning{background-color:#ffdd57;border-color:#ffdd57;color:rgba(0,0,0,0.7)}.table td.is-danger,.table th.is-danger{background-color:#da0b00;border-color:#da0b00;color:#fff}.table td.is-narrow,.table th.is-narrow{white-space:nowrap;width:1%}.table td.is-selected,.table th.is-selected{background-color:#4eb5de;color:#fff}.table td.is-selected a,.table td.is-selected strong,.table th.is-selected a,.table th.is-selected strong{color:currentColor}.table td.is-vcentered,.table th.is-vcentered{vertical-align:middle}.table th{color:#222}.table th:not([align]){text-align:left}.table tr.is-selected{background-color:#4eb5de;color:#fff}.table tr.is-selected a,.table tr.is-selected strong{color:currentColor}.table tr.is-selected td,.table tr.is-selected th{border-color:#fff;color:currentColor}.table thead{background-color:rgba(0,0,0,0)}.table thead td,.table thead th{border-width:0 0 2px;color:#222}.table tfoot{background-color:rgba(0,0,0,0)}.table tfoot td,.table tfoot th{border-width:2px 0 0;color:#222}.table tbody{background-color:rgba(0,0,0,0)}.table tbody tr:last-child td,.table tbody tr:last-child th{border-bottom-width:0}.table.is-bordered td,.table.is-bordered th{border-width:1px}.table.is-bordered tr:last-child td,.table.is-bordered tr:last-child th{border-bottom-width:1px}.table.is-fullwidth{width:100%}.table.is-hoverable tbody tr:not(.is-selected):hover{background-color:#fafafa}.table.is-hoverable.is-striped tbody tr:not(.is-selected):hover{background-color:#fafafa}.table.is-hoverable.is-striped tbody tr:not(.is-selected):hover:nth-child(even){background-color:#f5f5f5}.table.is-narrow td,.table.is-narrow th{padding:0.25em 0.5em}.table.is-striped tbody tr:not(.is-selected):nth-child(even){background-color:#fafafa}.table-container{-webkit-overflow-scrolling:touch;overflow:auto;overflow-y:hidden;max-width:100%}.tags{align-items:center;display:flex;flex-wrap:wrap;justify-content:flex-start}.tags .tag,.tags .content kbd,.content .tags kbd,.tags .docstring>section>a.docs-sourcelink{margin-bottom:0.5rem}.tags .tag:not(:last-child),.tags .content kbd:not(:last-child),.content .tags kbd:not(:last-child),.tags .docstring>section>a.docs-sourcelink:not(:last-child){margin-right:.5rem}.tags:last-child{margin-bottom:-0.5rem}.tags:not(:last-child){margin-bottom:1rem}.tags.are-medium .tag:not(.is-normal):not(.is-large),.tags.are-medium .content kbd:not(.is-normal):not(.is-large),.content .tags.are-medium kbd:not(.is-normal):not(.is-large),.tags.are-medium .docstring>section>a.docs-sourcelink:not(.is-normal):not(.is-large){font-size:1rem}.tags.are-large .tag:not(.is-normal):not(.is-medium),.tags.are-large .content kbd:not(.is-normal):not(.is-medium),.content .tags.are-large kbd:not(.is-normal):not(.is-medium),.tags.are-large .docstring>section>a.docs-sourcelink:not(.is-normal):not(.is-medium){font-size:1.25rem}.tags.is-centered{justify-content:center}.tags.is-centered .tag,.tags.is-centered .content kbd,.content .tags.is-centered kbd,.tags.is-centered .docstring>section>a.docs-sourcelink{margin-right:0.25rem;margin-left:0.25rem}.tags.is-right{justify-content:flex-end}.tags.is-right .tag:not(:first-child),.tags.is-right .content kbd:not(:first-child),.content .tags.is-right kbd:not(:first-child),.tags.is-right .docstring>section>a.docs-sourcelink:not(:first-child){margin-left:0.5rem}.tags.is-right .tag:not(:last-child),.tags.is-right .content kbd:not(:last-child),.content .tags.is-right kbd:not(:last-child),.tags.is-right .docstring>section>a.docs-sourcelink:not(:last-child){margin-right:0}.tags.has-addons .tag,.tags.has-addons .content kbd,.content .tags.has-addons kbd,.tags.has-addons .docstring>section>a.docs-sourcelink{margin-right:0}.tags.has-addons .tag:not(:first-child),.tags.has-addons .content kbd:not(:first-child),.content .tags.has-addons kbd:not(:first-child),.tags.has-addons .docstring>section>a.docs-sourcelink:not(:first-child){margin-left:0;border-top-left-radius:0;border-bottom-left-radius:0}.tags.has-addons .tag:not(:last-child),.tags.has-addons .content kbd:not(:last-child),.content .tags.has-addons kbd:not(:last-child),.tags.has-addons .docstring>section>a.docs-sourcelink:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.tag:not(body),.content kbd:not(body),.docstring>section>a.docs-sourcelink:not(body){align-items:center;background-color:#f5f5f5;border-radius:4px;color:#222;display:inline-flex;font-size:.75rem;height:2em;justify-content:center;line-height:1.5;padding-left:0.75em;padding-right:0.75em;white-space:nowrap}.tag:not(body) .delete,.content kbd:not(body) .delete,.docstring>section>a.docs-sourcelink:not(body) .delete{margin-left:.25rem;margin-right:-.375rem}.tag.is-white:not(body),.content kbd.is-white:not(body),.docstring>section>a.docs-sourcelink.is-white:not(body){background-color:#fff;color:#0a0a0a}.tag.is-black:not(body),.content kbd.is-black:not(body),.docstring>section>a.docs-sourcelink.is-black:not(body){background-color:#0a0a0a;color:#fff}.tag.is-light:not(body),.content kbd.is-light:not(body),.docstring>section>a.docs-sourcelink.is-light:not(body){background-color:#f5f5f5;color:rgba(0,0,0,0.7)}.tag.is-dark:not(body),.content kbd:not(body),.docstring>section>a.docs-sourcelink.is-dark:not(body),.content .docstring>section>kbd:not(body){background-color:#363636;color:#fff}.tag.is-primary:not(body),.content kbd.is-primary:not(body),.docstring>section>a.docs-sourcelink:not(body){background-color:#4eb5de;color:#fff}.tag.is-primary.is-light:not(body),.content kbd.is-primary.is-light:not(body),.docstring>section>a.docs-sourcelink.is-light:not(body){background-color:#eef8fc;color:#1a6d8e}.tag.is-link:not(body),.content kbd.is-link:not(body),.docstring>section>a.docs-sourcelink.is-link:not(body){background-color:#2e63b8;color:#fff}.tag.is-link.is-light:not(body),.content kbd.is-link.is-light:not(body),.docstring>section>a.docs-sourcelink.is-link.is-light:not(body){background-color:#eff3fb;color:#3169c4}.tag.is-info:not(body),.content kbd.is-info:not(body),.docstring>section>a.docs-sourcelink.is-info:not(body){background-color:#209cee;color:#fff}.tag.is-info.is-light:not(body),.content kbd.is-info.is-light:not(body),.docstring>section>a.docs-sourcelink.is-info.is-light:not(body){background-color:#ecf7fe;color:#0e72b4}.tag.is-success:not(body),.content kbd.is-success:not(body),.docstring>section>a.docs-sourcelink.is-success:not(body){background-color:#22c35b;color:#fff}.tag.is-success.is-light:not(body),.content kbd.is-success.is-light:not(body),.docstring>section>a.docs-sourcelink.is-success.is-light:not(body){background-color:#eefcf3;color:#198f43}.tag.is-warning:not(body),.content kbd.is-warning:not(body),.docstring>section>a.docs-sourcelink.is-warning:not(body){background-color:#ffdd57;color:rgba(0,0,0,0.7)}.tag.is-warning.is-light:not(body),.content kbd.is-warning.is-light:not(body),.docstring>section>a.docs-sourcelink.is-warning.is-light:not(body){background-color:#fffbeb;color:#947600}.tag.is-danger:not(body),.content kbd.is-danger:not(body),.docstring>section>a.docs-sourcelink.is-danger:not(body){background-color:#da0b00;color:#fff}.tag.is-danger.is-light:not(body),.content kbd.is-danger.is-light:not(body),.docstring>section>a.docs-sourcelink.is-danger.is-light:not(body){background-color:#ffeceb;color:#f50c00}.tag.is-normal:not(body),.content kbd.is-normal:not(body),.docstring>section>a.docs-sourcelink.is-normal:not(body){font-size:.75rem}.tag.is-medium:not(body),.content kbd.is-medium:not(body),.docstring>section>a.docs-sourcelink.is-medium:not(body){font-size:1rem}.tag.is-large:not(body),.content kbd.is-large:not(body),.docstring>section>a.docs-sourcelink.is-large:not(body){font-size:1.25rem}.tag:not(body) .icon:first-child:not(:last-child),.content kbd:not(body) .icon:first-child:not(:last-child),.docstring>section>a.docs-sourcelink:not(body) .icon:first-child:not(:last-child){margin-left:-.375em;margin-right:.1875em}.tag:not(body) .icon:last-child:not(:first-child),.content kbd:not(body) .icon:last-child:not(:first-child),.docstring>section>a.docs-sourcelink:not(body) .icon:last-child:not(:first-child){margin-left:.1875em;margin-right:-.375em}.tag:not(body) .icon:first-child:last-child,.content kbd:not(body) .icon:first-child:last-child,.docstring>section>a.docs-sourcelink:not(body) .icon:first-child:last-child{margin-left:-.375em;margin-right:-.375em}.tag.is-delete:not(body),.content kbd.is-delete:not(body),.docstring>section>a.docs-sourcelink.is-delete:not(body){margin-left:1px;padding:0;position:relative;width:2em}.tag.is-delete:not(body)::before,.content kbd.is-delete:not(body)::before,.docstring>section>a.docs-sourcelink.is-delete:not(body)::before,.tag.is-delete:not(body)::after,.content kbd.is-delete:not(body)::after,.docstring>section>a.docs-sourcelink.is-delete:not(body)::after{background-color:currentColor;content:"";display:block;left:50%;position:absolute;top:50%;transform:translateX(-50%) translateY(-50%) rotate(45deg);transform-origin:center center}.tag.is-delete:not(body)::before,.content kbd.is-delete:not(body)::before,.docstring>section>a.docs-sourcelink.is-delete:not(body)::before{height:1px;width:50%}.tag.is-delete:not(body)::after,.content kbd.is-delete:not(body)::after,.docstring>section>a.docs-sourcelink.is-delete:not(body)::after{height:50%;width:1px}.tag.is-delete:not(body):hover,.content kbd.is-delete:not(body):hover,.docstring>section>a.docs-sourcelink.is-delete:not(body):hover,.tag.is-delete:not(body):focus,.content kbd.is-delete:not(body):focus,.docstring>section>a.docs-sourcelink.is-delete:not(body):focus{background-color:#e8e8e8}.tag.is-delete:not(body):active,.content kbd.is-delete:not(body):active,.docstring>section>a.docs-sourcelink.is-delete:not(body):active{background-color:#dbdbdb}.tag.is-rounded:not(body),#documenter .docs-sidebar form.docs-search>input:not(body),.content kbd.is-rounded:not(body),#documenter .docs-sidebar .content form.docs-search>input:not(body),.docstring>section>a.docs-sourcelink.is-rounded:not(body){border-radius:9999px}a.tag:hover,.docstring>section>a.docs-sourcelink:hover{text-decoration:underline}.title,.subtitle{word-break:break-word}.title em,.title span,.subtitle em,.subtitle span{font-weight:inherit}.title sub,.subtitle sub{font-size:.75em}.title sup,.subtitle sup{font-size:.75em}.title .tag,.title .content kbd,.content .title kbd,.title .docstring>section>a.docs-sourcelink,.subtitle .tag,.subtitle .content kbd,.content .subtitle kbd,.subtitle .docstring>section>a.docs-sourcelink{vertical-align:middle}.title{color:#222;font-size:2rem;font-weight:600;line-height:1.125}.title strong{color:inherit;font-weight:inherit}.title:not(.is-spaced)+.subtitle{margin-top:-1.25rem}.title.is-1{font-size:3rem}.title.is-2{font-size:2.5rem}.title.is-3{font-size:2rem}.title.is-4{font-size:1.5rem}.title.is-5{font-size:1.25rem}.title.is-6{font-size:1rem}.title.is-7{font-size:.75rem}.subtitle{color:#222;font-size:1.25rem;font-weight:400;line-height:1.25}.subtitle strong{color:#222;font-weight:600}.subtitle:not(.is-spaced)+.title{margin-top:-1.25rem}.subtitle.is-1{font-size:3rem}.subtitle.is-2{font-size:2.5rem}.subtitle.is-3{font-size:2rem}.subtitle.is-4{font-size:1.5rem}.subtitle.is-5{font-size:1.25rem}.subtitle.is-6{font-size:1rem}.subtitle.is-7{font-size:.75rem}.heading{display:block;font-size:11px;letter-spacing:1px;margin-bottom:5px;text-transform:uppercase}.number{align-items:center;background-color:#f5f5f5;border-radius:9999px;display:inline-flex;font-size:1.25rem;height:2em;justify-content:center;margin-right:1.5rem;min-width:2.5em;padding:0.25rem 0.5rem;text-align:center;vertical-align:top}.select select,.textarea,.input,#documenter .docs-sidebar form.docs-search>input{background-color:#fff;border-color:#dbdbdb;border-radius:4px;color:#222}.select select::-moz-placeholder,.textarea::-moz-placeholder,.input::-moz-placeholder,#documenter .docs-sidebar form.docs-search>input::-moz-placeholder{color:#707070}.select select::-webkit-input-placeholder,.textarea::-webkit-input-placeholder,.input::-webkit-input-placeholder,#documenter .docs-sidebar form.docs-search>input::-webkit-input-placeholder{color:#707070}.select select:-moz-placeholder,.textarea:-moz-placeholder,.input:-moz-placeholder,#documenter .docs-sidebar form.docs-search>input:-moz-placeholder{color:#707070}.select select:-ms-input-placeholder,.textarea:-ms-input-placeholder,.input:-ms-input-placeholder,#documenter .docs-sidebar form.docs-search>input:-ms-input-placeholder{color:#707070}.select select:hover,.textarea:hover,.input:hover,#documenter .docs-sidebar form.docs-search>input:hover,.select select.is-hovered,.is-hovered.textarea,.is-hovered.input,#documenter .docs-sidebar form.docs-search>input.is-hovered{border-color:#b5b5b5}.select select:focus,.textarea:focus,.input:focus,#documenter .docs-sidebar form.docs-search>input:focus,.select select.is-focused,.is-focused.textarea,.is-focused.input,#documenter .docs-sidebar form.docs-search>input.is-focused,.select select:active,.textarea:active,.input:active,#documenter .docs-sidebar form.docs-search>input:active,.select select.is-active,.is-active.textarea,.is-active.input,#documenter .docs-sidebar form.docs-search>input.is-active{border-color:#2e63b8;box-shadow:0 0 0 0.125em rgba(46,99,184,0.25)}.select select[disabled],.textarea[disabled],.input[disabled],#documenter .docs-sidebar form.docs-search>input[disabled],fieldset[disabled] .select select,.select fieldset[disabled] select,fieldset[disabled] .textarea,fieldset[disabled] .input,fieldset[disabled] #documenter .docs-sidebar form.docs-search>input,#documenter .docs-sidebar fieldset[disabled] form.docs-search>input{background-color:#f5f5f5;border-color:#f5f5f5;box-shadow:none;color:#6b6b6b}.select select[disabled]::-moz-placeholder,.textarea[disabled]::-moz-placeholder,.input[disabled]::-moz-placeholder,#documenter .docs-sidebar form.docs-search>input[disabled]::-moz-placeholder,fieldset[disabled] .select select::-moz-placeholder,.select fieldset[disabled] select::-moz-placeholder,fieldset[disabled] .textarea::-moz-placeholder,fieldset[disabled] .input::-moz-placeholder,fieldset[disabled] #documenter .docs-sidebar form.docs-search>input::-moz-placeholder,#documenter .docs-sidebar fieldset[disabled] form.docs-search>input::-moz-placeholder{color:rgba(107,107,107,0.3)}.select select[disabled]::-webkit-input-placeholder,.textarea[disabled]::-webkit-input-placeholder,.input[disabled]::-webkit-input-placeholder,#documenter .docs-sidebar form.docs-search>input[disabled]::-webkit-input-placeholder,fieldset[disabled] .select select::-webkit-input-placeholder,.select fieldset[disabled] select::-webkit-input-placeholder,fieldset[disabled] .textarea::-webkit-input-placeholder,fieldset[disabled] .input::-webkit-input-placeholder,fieldset[disabled] #documenter .docs-sidebar form.docs-search>input::-webkit-input-placeholder,#documenter .docs-sidebar fieldset[disabled] form.docs-search>input::-webkit-input-placeholder{color:rgba(107,107,107,0.3)}.select select[disabled]:-moz-placeholder,.textarea[disabled]:-moz-placeholder,.input[disabled]:-moz-placeholder,#documenter .docs-sidebar form.docs-search>input[disabled]:-moz-placeholder,fieldset[disabled] .select select:-moz-placeholder,.select fieldset[disabled] select:-moz-placeholder,fieldset[disabled] .textarea:-moz-placeholder,fieldset[disabled] .input:-moz-placeholder,fieldset[disabled] #documenter .docs-sidebar form.docs-search>input:-moz-placeholder,#documenter .docs-sidebar fieldset[disabled] form.docs-search>input:-moz-placeholder{color:rgba(107,107,107,0.3)}.select select[disabled]:-ms-input-placeholder,.textarea[disabled]:-ms-input-placeholder,.input[disabled]:-ms-input-placeholder,#documenter .docs-sidebar form.docs-search>input[disabled]:-ms-input-placeholder,fieldset[disabled] .select select:-ms-input-placeholder,.select fieldset[disabled] select:-ms-input-placeholder,fieldset[disabled] .textarea:-ms-input-placeholder,fieldset[disabled] .input:-ms-input-placeholder,fieldset[disabled] #documenter .docs-sidebar form.docs-search>input:-ms-input-placeholder,#documenter .docs-sidebar fieldset[disabled] form.docs-search>input:-ms-input-placeholder{color:rgba(107,107,107,0.3)}.textarea,.input,#documenter .docs-sidebar form.docs-search>input{box-shadow:inset 0 0.0625em 0.125em rgba(10,10,10,0.05);max-width:100%;width:100%}.textarea[readonly],.input[readonly],#documenter .docs-sidebar form.docs-search>input[readonly]{box-shadow:none}.is-white.textarea,.is-white.input,#documenter .docs-sidebar form.docs-search>input.is-white{border-color:#fff}.is-white.textarea:focus,.is-white.input:focus,#documenter .docs-sidebar form.docs-search>input.is-white:focus,.is-white.is-focused.textarea,.is-white.is-focused.input,#documenter .docs-sidebar form.docs-search>input.is-focused,.is-white.textarea:active,.is-white.input:active,#documenter .docs-sidebar form.docs-search>input.is-white:active,.is-white.is-active.textarea,.is-white.is-active.input,#documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(255,255,255,0.25)}.is-black.textarea,.is-black.input,#documenter .docs-sidebar form.docs-search>input.is-black{border-color:#0a0a0a}.is-black.textarea:focus,.is-black.input:focus,#documenter .docs-sidebar form.docs-search>input.is-black:focus,.is-black.is-focused.textarea,.is-black.is-focused.input,#documenter .docs-sidebar form.docs-search>input.is-focused,.is-black.textarea:active,.is-black.input:active,#documenter .docs-sidebar form.docs-search>input.is-black:active,.is-black.is-active.textarea,.is-black.is-active.input,#documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(10,10,10,0.25)}.is-light.textarea,.is-light.input,#documenter .docs-sidebar form.docs-search>input.is-light{border-color:#f5f5f5}.is-light.textarea:focus,.is-light.input:focus,#documenter .docs-sidebar form.docs-search>input.is-light:focus,.is-light.is-focused.textarea,.is-light.is-focused.input,#documenter .docs-sidebar form.docs-search>input.is-focused,.is-light.textarea:active,.is-light.input:active,#documenter .docs-sidebar form.docs-search>input.is-light:active,.is-light.is-active.textarea,.is-light.is-active.input,#documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(245,245,245,0.25)}.is-dark.textarea,.content kbd.textarea,.is-dark.input,#documenter .docs-sidebar form.docs-search>input.is-dark,.content kbd.input{border-color:#363636}.is-dark.textarea:focus,.content kbd.textarea:focus,.is-dark.input:focus,#documenter .docs-sidebar form.docs-search>input.is-dark:focus,.content kbd.input:focus,.is-dark.is-focused.textarea,.content kbd.is-focused.textarea,.is-dark.is-focused.input,#documenter .docs-sidebar form.docs-search>input.is-focused,.content kbd.is-focused.input,#documenter .docs-sidebar .content form.docs-search>input.is-focused,.is-dark.textarea:active,.content kbd.textarea:active,.is-dark.input:active,#documenter .docs-sidebar form.docs-search>input.is-dark:active,.content kbd.input:active,.is-dark.is-active.textarea,.content kbd.is-active.textarea,.is-dark.is-active.input,#documenter .docs-sidebar form.docs-search>input.is-active,.content kbd.is-active.input,#documenter .docs-sidebar .content form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(54,54,54,0.25)}.is-primary.textarea,.docstring>section>a.textarea.docs-sourcelink,.is-primary.input,#documenter .docs-sidebar form.docs-search>input.is-primary,.docstring>section>a.input.docs-sourcelink{border-color:#4eb5de}.is-primary.textarea:focus,.docstring>section>a.textarea.docs-sourcelink:focus,.is-primary.input:focus,#documenter .docs-sidebar form.docs-search>input.is-primary:focus,.docstring>section>a.input.docs-sourcelink:focus,.is-primary.is-focused.textarea,.docstring>section>a.is-focused.textarea.docs-sourcelink,.is-primary.is-focused.input,#documenter .docs-sidebar form.docs-search>input.is-focused,.docstring>section>a.is-focused.input.docs-sourcelink,.is-primary.textarea:active,.docstring>section>a.textarea.docs-sourcelink:active,.is-primary.input:active,#documenter .docs-sidebar form.docs-search>input.is-primary:active,.docstring>section>a.input.docs-sourcelink:active,.is-primary.is-active.textarea,.docstring>section>a.is-active.textarea.docs-sourcelink,.is-primary.is-active.input,#documenter .docs-sidebar form.docs-search>input.is-active,.docstring>section>a.is-active.input.docs-sourcelink{box-shadow:0 0 0 0.125em rgba(78,181,222,0.25)}.is-link.textarea,.is-link.input,#documenter .docs-sidebar form.docs-search>input.is-link{border-color:#2e63b8}.is-link.textarea:focus,.is-link.input:focus,#documenter .docs-sidebar form.docs-search>input.is-link:focus,.is-link.is-focused.textarea,.is-link.is-focused.input,#documenter .docs-sidebar form.docs-search>input.is-focused,.is-link.textarea:active,.is-link.input:active,#documenter .docs-sidebar form.docs-search>input.is-link:active,.is-link.is-active.textarea,.is-link.is-active.input,#documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(46,99,184,0.25)}.is-info.textarea,.is-info.input,#documenter .docs-sidebar form.docs-search>input.is-info{border-color:#209cee}.is-info.textarea:focus,.is-info.input:focus,#documenter .docs-sidebar form.docs-search>input.is-info:focus,.is-info.is-focused.textarea,.is-info.is-focused.input,#documenter .docs-sidebar form.docs-search>input.is-focused,.is-info.textarea:active,.is-info.input:active,#documenter .docs-sidebar form.docs-search>input.is-info:active,.is-info.is-active.textarea,.is-info.is-active.input,#documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(32,156,238,0.25)}.is-success.textarea,.is-success.input,#documenter .docs-sidebar form.docs-search>input.is-success{border-color:#22c35b}.is-success.textarea:focus,.is-success.input:focus,#documenter .docs-sidebar form.docs-search>input.is-success:focus,.is-success.is-focused.textarea,.is-success.is-focused.input,#documenter .docs-sidebar form.docs-search>input.is-focused,.is-success.textarea:active,.is-success.input:active,#documenter .docs-sidebar form.docs-search>input.is-success:active,.is-success.is-active.textarea,.is-success.is-active.input,#documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(34,195,91,0.25)}.is-warning.textarea,.is-warning.input,#documenter .docs-sidebar form.docs-search>input.is-warning{border-color:#ffdd57}.is-warning.textarea:focus,.is-warning.input:focus,#documenter .docs-sidebar form.docs-search>input.is-warning:focus,.is-warning.is-focused.textarea,.is-warning.is-focused.input,#documenter .docs-sidebar form.docs-search>input.is-focused,.is-warning.textarea:active,.is-warning.input:active,#documenter .docs-sidebar form.docs-search>input.is-warning:active,.is-warning.is-active.textarea,.is-warning.is-active.input,#documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(255,221,87,0.25)}.is-danger.textarea,.is-danger.input,#documenter .docs-sidebar form.docs-search>input.is-danger{border-color:#da0b00}.is-danger.textarea:focus,.is-danger.input:focus,#documenter .docs-sidebar form.docs-search>input.is-danger:focus,.is-danger.is-focused.textarea,.is-danger.is-focused.input,#documenter .docs-sidebar form.docs-search>input.is-focused,.is-danger.textarea:active,.is-danger.input:active,#documenter .docs-sidebar form.docs-search>input.is-danger:active,.is-danger.is-active.textarea,.is-danger.is-active.input,#documenter .docs-sidebar form.docs-search>input.is-active{box-shadow:0 0 0 0.125em rgba(218,11,0,0.25)}.is-small.textarea,.is-small.input,#documenter .docs-sidebar form.docs-search>input{border-radius:2px;font-size:.75rem}.is-medium.textarea,.is-medium.input,#documenter .docs-sidebar form.docs-search>input.is-medium{font-size:1.25rem}.is-large.textarea,.is-large.input,#documenter .docs-sidebar form.docs-search>input.is-large{font-size:1.5rem}.is-fullwidth.textarea,.is-fullwidth.input,#documenter .docs-sidebar form.docs-search>input.is-fullwidth{display:block;width:100%}.is-inline.textarea,.is-inline.input,#documenter .docs-sidebar form.docs-search>input.is-inline{display:inline;width:auto}.input.is-rounded,#documenter .docs-sidebar form.docs-search>input{border-radius:9999px;padding-left:calc(calc(0.75em - 1px) + 0.375em);padding-right:calc(calc(0.75em - 1px) + 0.375em)}.input.is-static,#documenter .docs-sidebar form.docs-search>input.is-static{background-color:transparent;border-color:transparent;box-shadow:none;padding-left:0;padding-right:0}.textarea{display:block;max-width:100%;min-width:100%;padding:calc(0.75em - 1px);resize:vertical}.textarea:not([rows]){max-height:40em;min-height:8em}.textarea[rows]{height:initial}.textarea.has-fixed-size{resize:none}.radio,.checkbox{cursor:pointer;display:inline-block;line-height:1.25;position:relative}.radio input,.checkbox input{cursor:pointer}.radio:hover,.checkbox:hover{color:#222}.radio[disabled],.checkbox[disabled],fieldset[disabled] .radio,fieldset[disabled] .checkbox,.radio input[disabled],.checkbox input[disabled]{color:#6b6b6b;cursor:not-allowed}.radio+.radio{margin-left:.5em}.select{display:inline-block;max-width:100%;position:relative;vertical-align:top}.select:not(.is-multiple){height:2.5em}.select:not(.is-multiple):not(.is-loading)::after{border-color:#2e63b8;right:1.125em;z-index:4}.select.is-rounded select,#documenter .docs-sidebar form.docs-search>input.select select{border-radius:9999px;padding-left:1em}.select select{cursor:pointer;display:block;font-size:1em;max-width:100%;outline:none}.select select::-ms-expand{display:none}.select select[disabled]:hover,fieldset[disabled] .select select:hover{border-color:#f5f5f5}.select select:not([multiple]){padding-right:2.5em}.select select[multiple]{height:auto;padding:0}.select select[multiple] option{padding:0.5em 1em}.select:not(.is-multiple):not(.is-loading):hover::after{border-color:#222}.select.is-white:not(:hover)::after{border-color:#fff}.select.is-white select{border-color:#fff}.select.is-white select:hover,.select.is-white select.is-hovered{border-color:#f2f2f2}.select.is-white select:focus,.select.is-white select.is-focused,.select.is-white select:active,.select.is-white select.is-active{box-shadow:0 0 0 0.125em rgba(255,255,255,0.25)}.select.is-black:not(:hover)::after{border-color:#0a0a0a}.select.is-black select{border-color:#0a0a0a}.select.is-black select:hover,.select.is-black select.is-hovered{border-color:#000}.select.is-black select:focus,.select.is-black select.is-focused,.select.is-black select:active,.select.is-black select.is-active{box-shadow:0 0 0 0.125em rgba(10,10,10,0.25)}.select.is-light:not(:hover)::after{border-color:#f5f5f5}.select.is-light select{border-color:#f5f5f5}.select.is-light select:hover,.select.is-light select.is-hovered{border-color:#e8e8e8}.select.is-light select:focus,.select.is-light select.is-focused,.select.is-light select:active,.select.is-light select.is-active{box-shadow:0 0 0 0.125em rgba(245,245,245,0.25)}.select.is-dark:not(:hover)::after,.content kbd.select:not(:hover)::after{border-color:#363636}.select.is-dark select,.content kbd.select select{border-color:#363636}.select.is-dark select:hover,.content kbd.select select:hover,.select.is-dark select.is-hovered,.content kbd.select select.is-hovered{border-color:#292929}.select.is-dark select:focus,.content kbd.select select:focus,.select.is-dark select.is-focused,.content kbd.select select.is-focused,.select.is-dark select:active,.content kbd.select select:active,.select.is-dark select.is-active,.content kbd.select select.is-active{box-shadow:0 0 0 0.125em rgba(54,54,54,0.25)}.select.is-primary:not(:hover)::after,.docstring>section>a.select.docs-sourcelink:not(:hover)::after{border-color:#4eb5de}.select.is-primary select,.docstring>section>a.select.docs-sourcelink select{border-color:#4eb5de}.select.is-primary select:hover,.docstring>section>a.select.docs-sourcelink select:hover,.select.is-primary select.is-hovered,.docstring>section>a.select.docs-sourcelink select.is-hovered{border-color:#39acda}.select.is-primary select:focus,.docstring>section>a.select.docs-sourcelink select:focus,.select.is-primary select.is-focused,.docstring>section>a.select.docs-sourcelink select.is-focused,.select.is-primary select:active,.docstring>section>a.select.docs-sourcelink select:active,.select.is-primary select.is-active,.docstring>section>a.select.docs-sourcelink select.is-active{box-shadow:0 0 0 0.125em rgba(78,181,222,0.25)}.select.is-link:not(:hover)::after{border-color:#2e63b8}.select.is-link select{border-color:#2e63b8}.select.is-link select:hover,.select.is-link select.is-hovered{border-color:#2958a4}.select.is-link select:focus,.select.is-link select.is-focused,.select.is-link select:active,.select.is-link select.is-active{box-shadow:0 0 0 0.125em rgba(46,99,184,0.25)}.select.is-info:not(:hover)::after{border-color:#209cee}.select.is-info select{border-color:#209cee}.select.is-info select:hover,.select.is-info select.is-hovered{border-color:#1190e3}.select.is-info select:focus,.select.is-info select.is-focused,.select.is-info select:active,.select.is-info select.is-active{box-shadow:0 0 0 0.125em rgba(32,156,238,0.25)}.select.is-success:not(:hover)::after{border-color:#22c35b}.select.is-success select{border-color:#22c35b}.select.is-success select:hover,.select.is-success select.is-hovered{border-color:#1ead51}.select.is-success select:focus,.select.is-success select.is-focused,.select.is-success select:active,.select.is-success select.is-active{box-shadow:0 0 0 0.125em rgba(34,195,91,0.25)}.select.is-warning:not(:hover)::after{border-color:#ffdd57}.select.is-warning select{border-color:#ffdd57}.select.is-warning select:hover,.select.is-warning select.is-hovered{border-color:#ffd83e}.select.is-warning select:focus,.select.is-warning select.is-focused,.select.is-warning select:active,.select.is-warning select.is-active{box-shadow:0 0 0 0.125em rgba(255,221,87,0.25)}.select.is-danger:not(:hover)::after{border-color:#da0b00}.select.is-danger select{border-color:#da0b00}.select.is-danger select:hover,.select.is-danger select.is-hovered{border-color:#c10a00}.select.is-danger select:focus,.select.is-danger select.is-focused,.select.is-danger select:active,.select.is-danger select.is-active{box-shadow:0 0 0 0.125em rgba(218,11,0,0.25)}.select.is-small,#documenter .docs-sidebar form.docs-search>input.select{border-radius:2px;font-size:.75rem}.select.is-medium{font-size:1.25rem}.select.is-large{font-size:1.5rem}.select.is-disabled::after{border-color:#6b6b6b !important;opacity:0.5}.select.is-fullwidth{width:100%}.select.is-fullwidth select{width:100%}.select.is-loading::after{margin-top:0;position:absolute;right:.625em;top:0.625em;transform:none}.select.is-loading.is-small:after,#documenter .docs-sidebar form.docs-search>input.is-loading:after{font-size:.75rem}.select.is-loading.is-medium:after{font-size:1.25rem}.select.is-loading.is-large:after{font-size:1.5rem}.file{align-items:stretch;display:flex;justify-content:flex-start;position:relative}.file.is-white .file-cta{background-color:#fff;border-color:transparent;color:#0a0a0a}.file.is-white:hover .file-cta,.file.is-white.is-hovered .file-cta{background-color:#f9f9f9;border-color:transparent;color:#0a0a0a}.file.is-white:focus .file-cta,.file.is-white.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(255,255,255,0.25);color:#0a0a0a}.file.is-white:active .file-cta,.file.is-white.is-active .file-cta{background-color:#f2f2f2;border-color:transparent;color:#0a0a0a}.file.is-black .file-cta{background-color:#0a0a0a;border-color:transparent;color:#fff}.file.is-black:hover .file-cta,.file.is-black.is-hovered .file-cta{background-color:#040404;border-color:transparent;color:#fff}.file.is-black:focus .file-cta,.file.is-black.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(10,10,10,0.25);color:#fff}.file.is-black:active .file-cta,.file.is-black.is-active .file-cta{background-color:#000;border-color:transparent;color:#fff}.file.is-light .file-cta{background-color:#f5f5f5;border-color:transparent;color:rgba(0,0,0,0.7)}.file.is-light:hover .file-cta,.file.is-light.is-hovered .file-cta{background-color:#eee;border-color:transparent;color:rgba(0,0,0,0.7)}.file.is-light:focus .file-cta,.file.is-light.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(245,245,245,0.25);color:rgba(0,0,0,0.7)}.file.is-light:active .file-cta,.file.is-light.is-active .file-cta{background-color:#e8e8e8;border-color:transparent;color:rgba(0,0,0,0.7)}.file.is-dark .file-cta,.content kbd.file .file-cta{background-color:#363636;border-color:transparent;color:#fff}.file.is-dark:hover .file-cta,.content kbd.file:hover .file-cta,.file.is-dark.is-hovered .file-cta,.content kbd.file.is-hovered .file-cta{background-color:#2f2f2f;border-color:transparent;color:#fff}.file.is-dark:focus .file-cta,.content kbd.file:focus .file-cta,.file.is-dark.is-focused .file-cta,.content kbd.file.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(54,54,54,0.25);color:#fff}.file.is-dark:active .file-cta,.content kbd.file:active .file-cta,.file.is-dark.is-active .file-cta,.content kbd.file.is-active .file-cta{background-color:#292929;border-color:transparent;color:#fff}.file.is-primary .file-cta,.docstring>section>a.file.docs-sourcelink .file-cta{background-color:#4eb5de;border-color:transparent;color:#fff}.file.is-primary:hover .file-cta,.docstring>section>a.file.docs-sourcelink:hover .file-cta,.file.is-primary.is-hovered .file-cta,.docstring>section>a.file.is-hovered.docs-sourcelink .file-cta{background-color:#43b1dc;border-color:transparent;color:#fff}.file.is-primary:focus .file-cta,.docstring>section>a.file.docs-sourcelink:focus .file-cta,.file.is-primary.is-focused .file-cta,.docstring>section>a.file.is-focused.docs-sourcelink .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(78,181,222,0.25);color:#fff}.file.is-primary:active .file-cta,.docstring>section>a.file.docs-sourcelink:active .file-cta,.file.is-primary.is-active .file-cta,.docstring>section>a.file.is-active.docs-sourcelink .file-cta{background-color:#39acda;border-color:transparent;color:#fff}.file.is-link .file-cta{background-color:#2e63b8;border-color:transparent;color:#fff}.file.is-link:hover .file-cta,.file.is-link.is-hovered .file-cta{background-color:#2b5eae;border-color:transparent;color:#fff}.file.is-link:focus .file-cta,.file.is-link.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(46,99,184,0.25);color:#fff}.file.is-link:active .file-cta,.file.is-link.is-active .file-cta{background-color:#2958a4;border-color:transparent;color:#fff}.file.is-info .file-cta{background-color:#209cee;border-color:transparent;color:#fff}.file.is-info:hover .file-cta,.file.is-info.is-hovered .file-cta{background-color:#1497ed;border-color:transparent;color:#fff}.file.is-info:focus .file-cta,.file.is-info.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(32,156,238,0.25);color:#fff}.file.is-info:active .file-cta,.file.is-info.is-active .file-cta{background-color:#1190e3;border-color:transparent;color:#fff}.file.is-success .file-cta{background-color:#22c35b;border-color:transparent;color:#fff}.file.is-success:hover .file-cta,.file.is-success.is-hovered .file-cta{background-color:#20b856;border-color:transparent;color:#fff}.file.is-success:focus .file-cta,.file.is-success.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(34,195,91,0.25);color:#fff}.file.is-success:active .file-cta,.file.is-success.is-active .file-cta{background-color:#1ead51;border-color:transparent;color:#fff}.file.is-warning .file-cta{background-color:#ffdd57;border-color:transparent;color:rgba(0,0,0,0.7)}.file.is-warning:hover .file-cta,.file.is-warning.is-hovered .file-cta{background-color:#ffda4a;border-color:transparent;color:rgba(0,0,0,0.7)}.file.is-warning:focus .file-cta,.file.is-warning.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(255,221,87,0.25);color:rgba(0,0,0,0.7)}.file.is-warning:active .file-cta,.file.is-warning.is-active .file-cta{background-color:#ffd83e;border-color:transparent;color:rgba(0,0,0,0.7)}.file.is-danger .file-cta{background-color:#da0b00;border-color:transparent;color:#fff}.file.is-danger:hover .file-cta,.file.is-danger.is-hovered .file-cta{background-color:#cd0a00;border-color:transparent;color:#fff}.file.is-danger:focus .file-cta,.file.is-danger.is-focused .file-cta{border-color:transparent;box-shadow:0 0 0.5em rgba(218,11,0,0.25);color:#fff}.file.is-danger:active .file-cta,.file.is-danger.is-active .file-cta{background-color:#c10a00;border-color:transparent;color:#fff}.file.is-small,#documenter .docs-sidebar form.docs-search>input.file{font-size:.75rem}.file.is-normal{font-size:1rem}.file.is-medium{font-size:1.25rem}.file.is-medium .file-icon .fa{font-size:21px}.file.is-large{font-size:1.5rem}.file.is-large .file-icon .fa{font-size:28px}.file.has-name .file-cta{border-bottom-right-radius:0;border-top-right-radius:0}.file.has-name .file-name{border-bottom-left-radius:0;border-top-left-radius:0}.file.has-name.is-empty .file-cta{border-radius:4px}.file.has-name.is-empty .file-name{display:none}.file.is-boxed .file-label{flex-direction:column}.file.is-boxed .file-cta{flex-direction:column;height:auto;padding:1em 3em}.file.is-boxed .file-name{border-width:0 1px 1px}.file.is-boxed .file-icon{height:1.5em;width:1.5em}.file.is-boxed .file-icon .fa{font-size:21px}.file.is-boxed.is-small .file-icon .fa,#documenter .docs-sidebar form.docs-search>input.is-boxed .file-icon .fa{font-size:14px}.file.is-boxed.is-medium .file-icon .fa{font-size:28px}.file.is-boxed.is-large .file-icon .fa{font-size:35px}.file.is-boxed.has-name .file-cta{border-radius:4px 4px 0 0}.file.is-boxed.has-name .file-name{border-radius:0 0 4px 4px;border-width:0 1px 1px}.file.is-centered{justify-content:center}.file.is-fullwidth .file-label{width:100%}.file.is-fullwidth .file-name{flex-grow:1;max-width:none}.file.is-right{justify-content:flex-end}.file.is-right .file-cta{border-radius:0 4px 4px 0}.file.is-right .file-name{border-radius:4px 0 0 4px;border-width:1px 0 1px 1px;order:-1}.file-label{align-items:stretch;display:flex;cursor:pointer;justify-content:flex-start;overflow:hidden;position:relative}.file-label:hover .file-cta{background-color:#eee;color:#222}.file-label:hover .file-name{border-color:#d5d5d5}.file-label:active .file-cta{background-color:#e8e8e8;color:#222}.file-label:active .file-name{border-color:#cfcfcf}.file-input{height:100%;left:0;opacity:0;outline:none;position:absolute;top:0;width:100%}.file-cta,.file-name{border-color:#dbdbdb;border-radius:4px;font-size:1em;padding-left:1em;padding-right:1em;white-space:nowrap}.file-cta{background-color:#f5f5f5;color:#222}.file-name{border-color:#dbdbdb;border-style:solid;border-width:1px 1px 1px 0;display:block;max-width:16em;overflow:hidden;text-align:inherit;text-overflow:ellipsis}.file-icon{align-items:center;display:flex;height:1em;justify-content:center;margin-right:.5em;width:1em}.file-icon .fa{font-size:14px}.label{color:#222;display:block;font-size:1rem;font-weight:700}.label:not(:last-child){margin-bottom:0.5em}.label.is-small,#documenter .docs-sidebar form.docs-search>input.label{font-size:.75rem}.label.is-medium{font-size:1.25rem}.label.is-large{font-size:1.5rem}.help{display:block;font-size:.75rem;margin-top:0.25rem}.help.is-white{color:#fff}.help.is-black{color:#0a0a0a}.help.is-light{color:#f5f5f5}.help.is-dark,.content kbd.help{color:#363636}.help.is-primary,.docstring>section>a.help.docs-sourcelink{color:#4eb5de}.help.is-link{color:#2e63b8}.help.is-info{color:#209cee}.help.is-success{color:#22c35b}.help.is-warning{color:#ffdd57}.help.is-danger{color:#da0b00}.field:not(:last-child){margin-bottom:0.75rem}.field.has-addons{display:flex;justify-content:flex-start}.field.has-addons .control:not(:last-child){margin-right:-1px}.field.has-addons .control:not(:first-child):not(:last-child) .button,.field.has-addons .control:not(:first-child):not(:last-child) .input,.field.has-addons .control:not(:first-child):not(:last-child) #documenter .docs-sidebar form.docs-search>input,#documenter .docs-sidebar .field.has-addons .control:not(:first-child):not(:last-child) form.docs-search>input,.field.has-addons .control:not(:first-child):not(:last-child) .select select{border-radius:0}.field.has-addons .control:first-child:not(:only-child) .button,.field.has-addons .control:first-child:not(:only-child) .input,.field.has-addons .control:first-child:not(:only-child) #documenter .docs-sidebar form.docs-search>input,#documenter .docs-sidebar .field.has-addons .control:first-child:not(:only-child) form.docs-search>input,.field.has-addons .control:first-child:not(:only-child) .select select{border-bottom-right-radius:0;border-top-right-radius:0}.field.has-addons .control:last-child:not(:only-child) .button,.field.has-addons .control:last-child:not(:only-child) .input,.field.has-addons .control:last-child:not(:only-child) #documenter .docs-sidebar form.docs-search>input,#documenter .docs-sidebar .field.has-addons .control:last-child:not(:only-child) form.docs-search>input,.field.has-addons .control:last-child:not(:only-child) .select select{border-bottom-left-radius:0;border-top-left-radius:0}.field.has-addons .control .button:not([disabled]):hover,.field.has-addons .control .button.is-hovered:not([disabled]),.field.has-addons .control .input:not([disabled]):hover,.field.has-addons .control #documenter .docs-sidebar form.docs-search>input:not([disabled]):hover,#documenter .docs-sidebar .field.has-addons .control form.docs-search>input:not([disabled]):hover,.field.has-addons .control .input.is-hovered:not([disabled]),.field.has-addons .control #documenter .docs-sidebar form.docs-search>input.is-hovered:not([disabled]),#documenter .docs-sidebar .field.has-addons .control form.docs-search>input.is-hovered:not([disabled]),.field.has-addons .control .select select:not([disabled]):hover,.field.has-addons .control .select select.is-hovered:not([disabled]){z-index:2}.field.has-addons .control .button:not([disabled]):focus,.field.has-addons .control .button.is-focused:not([disabled]),.field.has-addons .control .button:not([disabled]):active,.field.has-addons .control .button.is-active:not([disabled]),.field.has-addons .control .input:not([disabled]):focus,.field.has-addons .control #documenter .docs-sidebar form.docs-search>input:not([disabled]):focus,#documenter .docs-sidebar .field.has-addons .control form.docs-search>input:not([disabled]):focus,.field.has-addons .control .input.is-focused:not([disabled]),.field.has-addons .control #documenter .docs-sidebar form.docs-search>input.is-focused:not([disabled]),#documenter .docs-sidebar .field.has-addons .control form.docs-search>input.is-focused:not([disabled]),.field.has-addons .control .input:not([disabled]):active,.field.has-addons .control #documenter .docs-sidebar form.docs-search>input:not([disabled]):active,#documenter .docs-sidebar .field.has-addons .control form.docs-search>input:not([disabled]):active,.field.has-addons .control .input.is-active:not([disabled]),.field.has-addons .control #documenter .docs-sidebar form.docs-search>input.is-active:not([disabled]),#documenter .docs-sidebar .field.has-addons .control form.docs-search>input.is-active:not([disabled]),.field.has-addons .control .select select:not([disabled]):focus,.field.has-addons .control .select select.is-focused:not([disabled]),.field.has-addons .control .select select:not([disabled]):active,.field.has-addons .control .select select.is-active:not([disabled]){z-index:3}.field.has-addons .control .button:not([disabled]):focus:hover,.field.has-addons .control .button.is-focused:not([disabled]):hover,.field.has-addons .control .button:not([disabled]):active:hover,.field.has-addons .control .button.is-active:not([disabled]):hover,.field.has-addons .control .input:not([disabled]):focus:hover,.field.has-addons .control #documenter .docs-sidebar form.docs-search>input:not([disabled]):focus:hover,#documenter .docs-sidebar .field.has-addons .control form.docs-search>input:not([disabled]):focus:hover,.field.has-addons .control .input.is-focused:not([disabled]):hover,.field.has-addons .control #documenter .docs-sidebar form.docs-search>input.is-focused:not([disabled]):hover,#documenter .docs-sidebar .field.has-addons .control form.docs-search>input.is-focused:not([disabled]):hover,.field.has-addons .control .input:not([disabled]):active:hover,.field.has-addons .control #documenter .docs-sidebar form.docs-search>input:not([disabled]):active:hover,#documenter .docs-sidebar .field.has-addons .control form.docs-search>input:not([disabled]):active:hover,.field.has-addons .control .input.is-active:not([disabled]):hover,.field.has-addons .control #documenter .docs-sidebar form.docs-search>input.is-active:not([disabled]):hover,#documenter .docs-sidebar .field.has-addons .control form.docs-search>input.is-active:not([disabled]):hover,.field.has-addons .control .select select:not([disabled]):focus:hover,.field.has-addons .control .select select.is-focused:not([disabled]):hover,.field.has-addons .control .select select:not([disabled]):active:hover,.field.has-addons .control .select select.is-active:not([disabled]):hover{z-index:4}.field.has-addons .control.is-expanded{flex-grow:1;flex-shrink:1}.field.has-addons.has-addons-centered{justify-content:center}.field.has-addons.has-addons-right{justify-content:flex-end}.field.has-addons.has-addons-fullwidth .control{flex-grow:1;flex-shrink:0}.field.is-grouped{display:flex;justify-content:flex-start}.field.is-grouped>.control{flex-shrink:0}.field.is-grouped>.control:not(:last-child){margin-bottom:0;margin-right:.75rem}.field.is-grouped>.control.is-expanded{flex-grow:1;flex-shrink:1}.field.is-grouped.is-grouped-centered{justify-content:center}.field.is-grouped.is-grouped-right{justify-content:flex-end}.field.is-grouped.is-grouped-multiline{flex-wrap:wrap}.field.is-grouped.is-grouped-multiline>.control:last-child,.field.is-grouped.is-grouped-multiline>.control:not(:last-child){margin-bottom:0.75rem}.field.is-grouped.is-grouped-multiline:last-child{margin-bottom:-0.75rem}.field.is-grouped.is-grouped-multiline:not(:last-child){margin-bottom:0}@media screen and (min-width: 769px),print{.field.is-horizontal{display:flex}}.field-label .label{font-size:inherit}@media screen and (max-width: 768px){.field-label{margin-bottom:0.5rem}}@media screen and (min-width: 769px),print{.field-label{flex-basis:0;flex-grow:1;flex-shrink:0;margin-right:1.5rem;text-align:right}.field-label.is-small,#documenter .docs-sidebar form.docs-search>input.field-label{font-size:.75rem;padding-top:0.375em}.field-label.is-normal{padding-top:0.375em}.field-label.is-medium{font-size:1.25rem;padding-top:0.375em}.field-label.is-large{font-size:1.5rem;padding-top:0.375em}}.field-body .field .field{margin-bottom:0}@media screen and (min-width: 769px),print{.field-body{display:flex;flex-basis:0;flex-grow:5;flex-shrink:1}.field-body .field{margin-bottom:0}.field-body>.field{flex-shrink:1}.field-body>.field:not(.is-narrow){flex-grow:1}.field-body>.field:not(:last-child){margin-right:.75rem}}.control{box-sizing:border-box;clear:both;font-size:1rem;position:relative;text-align:inherit}.control.has-icons-left .input:focus~.icon,.control.has-icons-left #documenter .docs-sidebar form.docs-search>input:focus~.icon,#documenter .docs-sidebar .control.has-icons-left form.docs-search>input:focus~.icon,.control.has-icons-left .select:focus~.icon,.control.has-icons-right .input:focus~.icon,.control.has-icons-right #documenter .docs-sidebar form.docs-search>input:focus~.icon,#documenter .docs-sidebar .control.has-icons-right form.docs-search>input:focus~.icon,.control.has-icons-right .select:focus~.icon{color:#222}.control.has-icons-left .input.is-small~.icon,.control.has-icons-left #documenter .docs-sidebar form.docs-search>input~.icon,#documenter .docs-sidebar .control.has-icons-left form.docs-search>input~.icon,.control.has-icons-left .select.is-small~.icon,.control.has-icons-right .input.is-small~.icon,.control.has-icons-right #documenter .docs-sidebar form.docs-search>input~.icon,#documenter .docs-sidebar .control.has-icons-right form.docs-search>input~.icon,.control.has-icons-right .select.is-small~.icon{font-size:.75rem}.control.has-icons-left .input.is-medium~.icon,.control.has-icons-left #documenter .docs-sidebar form.docs-search>input.is-medium~.icon,#documenter .docs-sidebar .control.has-icons-left form.docs-search>input.is-medium~.icon,.control.has-icons-left .select.is-medium~.icon,.control.has-icons-right .input.is-medium~.icon,.control.has-icons-right #documenter .docs-sidebar form.docs-search>input.is-medium~.icon,#documenter .docs-sidebar .control.has-icons-right form.docs-search>input.is-medium~.icon,.control.has-icons-right .select.is-medium~.icon{font-size:1.25rem}.control.has-icons-left .input.is-large~.icon,.control.has-icons-left #documenter .docs-sidebar form.docs-search>input.is-large~.icon,#documenter .docs-sidebar .control.has-icons-left form.docs-search>input.is-large~.icon,.control.has-icons-left .select.is-large~.icon,.control.has-icons-right .input.is-large~.icon,.control.has-icons-right #documenter .docs-sidebar form.docs-search>input.is-large~.icon,#documenter .docs-sidebar .control.has-icons-right form.docs-search>input.is-large~.icon,.control.has-icons-right .select.is-large~.icon{font-size:1.5rem}.control.has-icons-left .icon,.control.has-icons-right .icon{color:#dbdbdb;height:2.5em;pointer-events:none;position:absolute;top:0;width:2.5em;z-index:4}.control.has-icons-left .input,.control.has-icons-left #documenter .docs-sidebar form.docs-search>input,#documenter .docs-sidebar .control.has-icons-left form.docs-search>input,.control.has-icons-left .select select{padding-left:2.5em}.control.has-icons-left .icon.is-left{left:0}.control.has-icons-right .input,.control.has-icons-right #documenter .docs-sidebar form.docs-search>input,#documenter .docs-sidebar .control.has-icons-right form.docs-search>input,.control.has-icons-right .select select{padding-right:2.5em}.control.has-icons-right .icon.is-right{right:0}.control.is-loading::after{position:absolute !important;right:.625em;top:0.625em;z-index:4}.control.is-loading.is-small:after,#documenter .docs-sidebar form.docs-search>input.is-loading:after{font-size:.75rem}.control.is-loading.is-medium:after{font-size:1.25rem}.control.is-loading.is-large:after{font-size:1.5rem}.breadcrumb{font-size:1rem;white-space:nowrap}.breadcrumb a{align-items:center;color:#2e63b8;display:flex;justify-content:center;padding:0 .75em}.breadcrumb a:hover{color:#363636}.breadcrumb li{align-items:center;display:flex}.breadcrumb li:first-child a{padding-left:0}.breadcrumb li.is-active a{color:#222;cursor:default;pointer-events:none}.breadcrumb li+li::before{color:#b5b5b5;content:"\0002f"}.breadcrumb ul,.breadcrumb ol{align-items:flex-start;display:flex;flex-wrap:wrap;justify-content:flex-start}.breadcrumb .icon:first-child{margin-right:.5em}.breadcrumb .icon:last-child{margin-left:.5em}.breadcrumb.is-centered ol,.breadcrumb.is-centered ul{justify-content:center}.breadcrumb.is-right ol,.breadcrumb.is-right ul{justify-content:flex-end}.breadcrumb.is-small,#documenter .docs-sidebar form.docs-search>input.breadcrumb{font-size:.75rem}.breadcrumb.is-medium{font-size:1.25rem}.breadcrumb.is-large{font-size:1.5rem}.breadcrumb.has-arrow-separator li+li::before{content:"\02192"}.breadcrumb.has-bullet-separator li+li::before{content:"\02022"}.breadcrumb.has-dot-separator li+li::before{content:"\000b7"}.breadcrumb.has-succeeds-separator li+li::before{content:"\0227B"}.card{background-color:#fff;border-radius:.25rem;box-shadow:#bbb;color:#222;max-width:100%;position:relative}.card-footer:first-child,.card-content:first-child,.card-header:first-child{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.card-footer:last-child,.card-content:last-child,.card-header:last-child{border-bottom-left-radius:.25rem;border-bottom-right-radius:.25rem}.card-header{background-color:rgba(0,0,0,0);align-items:stretch;box-shadow:0 0.125em 0.25em rgba(10,10,10,0.1);display:flex}.card-header-title{align-items:center;color:#222;display:flex;flex-grow:1;font-weight:700;padding:0.75rem 1rem}.card-header-title.is-centered{justify-content:center}.card-header-icon{-moz-appearance:none;-webkit-appearance:none;appearance:none;background:none;border:none;color:currentColor;font-family:inherit;font-size:1em;margin:0;padding:0;align-items:center;cursor:pointer;display:flex;justify-content:center;padding:0.75rem 1rem}.card-image{display:block;position:relative}.card-image:first-child img{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.card-image:last-child img{border-bottom-left-radius:.25rem;border-bottom-right-radius:.25rem}.card-content{background-color:rgba(0,0,0,0);padding:1.5rem}.card-footer{background-color:rgba(0,0,0,0);border-top:1px solid #ededed;align-items:stretch;display:flex}.card-footer-item{align-items:center;display:flex;flex-basis:0;flex-grow:1;flex-shrink:0;justify-content:center;padding:.75rem}.card-footer-item:not(:last-child){border-right:1px solid #ededed}.card .media:not(:last-child){margin-bottom:1.5rem}.dropdown{display:inline-flex;position:relative;vertical-align:top}.dropdown.is-active .dropdown-menu,.dropdown.is-hoverable:hover .dropdown-menu{display:block}.dropdown.is-right .dropdown-menu{left:auto;right:0}.dropdown.is-up .dropdown-menu{bottom:100%;padding-bottom:4px;padding-top:initial;top:auto}.dropdown-menu{display:none;left:0;min-width:12rem;padding-top:4px;position:absolute;top:100%;z-index:20}.dropdown-content{background-color:#fff;border-radius:4px;box-shadow:#bbb;padding-bottom:.5rem;padding-top:.5rem}.dropdown-item{color:#222;display:block;font-size:0.875rem;line-height:1.5;padding:0.375rem 1rem;position:relative}a.dropdown-item,button.dropdown-item{padding-right:3rem;text-align:inherit;white-space:nowrap;width:100%}a.dropdown-item:hover,button.dropdown-item:hover{background-color:#f5f5f5;color:#0a0a0a}a.dropdown-item.is-active,button.dropdown-item.is-active{background-color:#2e63b8;color:#fff}.dropdown-divider{background-color:#ededed;border:none;display:block;height:1px;margin:0.5rem 0}.level{align-items:center;justify-content:space-between}.level code{border-radius:4px}.level img{display:inline-block;vertical-align:top}.level.is-mobile{display:flex}.level.is-mobile .level-left,.level.is-mobile .level-right{display:flex}.level.is-mobile .level-left+.level-right{margin-top:0}.level.is-mobile .level-item:not(:last-child){margin-bottom:0;margin-right:.75rem}.level.is-mobile .level-item:not(.is-narrow){flex-grow:1}@media screen and (min-width: 769px),print{.level{display:flex}.level>.level-item:not(.is-narrow){flex-grow:1}}.level-item{align-items:center;display:flex;flex-basis:auto;flex-grow:0;flex-shrink:0;justify-content:center}.level-item .title,.level-item .subtitle{margin-bottom:0}@media screen and (max-width: 768px){.level-item:not(:last-child){margin-bottom:.75rem}}.level-left,.level-right{flex-basis:auto;flex-grow:0;flex-shrink:0}.level-left .level-item.is-flexible,.level-right .level-item.is-flexible{flex-grow:1}@media screen and (min-width: 769px),print{.level-left .level-item:not(:last-child),.level-right .level-item:not(:last-child){margin-right:.75rem}}.level-left{align-items:center;justify-content:flex-start}@media screen and (max-width: 768px){.level-left+.level-right{margin-top:1.5rem}}@media screen and (min-width: 769px),print{.level-left{display:flex}}.level-right{align-items:center;justify-content:flex-end}@media screen and (min-width: 769px),print{.level-right{display:flex}}.media{align-items:flex-start;display:flex;text-align:inherit}.media .content:not(:last-child){margin-bottom:.75rem}.media .media{border-top:1px solid rgba(219,219,219,0.5);display:flex;padding-top:.75rem}.media .media .content:not(:last-child),.media .media .control:not(:last-child){margin-bottom:.5rem}.media .media .media{padding-top:.5rem}.media .media .media+.media{margin-top:.5rem}.media+.media{border-top:1px solid rgba(219,219,219,0.5);margin-top:1rem;padding-top:1rem}.media.is-large+.media{margin-top:1.5rem;padding-top:1.5rem}.media-left,.media-right{flex-basis:auto;flex-grow:0;flex-shrink:0}.media-left{margin-right:1rem}.media-right{margin-left:1rem}.media-content{flex-basis:auto;flex-grow:1;flex-shrink:1;text-align:inherit}@media screen and (max-width: 768px){.media-content{overflow-x:auto}}.menu{font-size:1rem}.menu.is-small,#documenter .docs-sidebar form.docs-search>input.menu{font-size:.75rem}.menu.is-medium{font-size:1.25rem}.menu.is-large{font-size:1.5rem}.menu-list{line-height:1.25}.menu-list a{border-radius:2px;color:#222;display:block;padding:0.5em 0.75em}.menu-list a:hover{background-color:#f5f5f5;color:#222}.menu-list a.is-active{background-color:#2e63b8;color:#fff}.menu-list li ul{border-left:1px solid #dbdbdb;margin:.75em;padding-left:.75em}.menu-label{color:#6b6b6b;font-size:.75em;letter-spacing:.1em;text-transform:uppercase}.menu-label:not(:first-child){margin-top:1em}.menu-label:not(:last-child){margin-bottom:1em}.message{background-color:#f5f5f5;border-radius:4px;font-size:1rem}.message strong{color:currentColor}.message a:not(.button):not(.tag):not(.dropdown-item){color:currentColor;text-decoration:underline}.message.is-small,#documenter .docs-sidebar form.docs-search>input.message{font-size:.75rem}.message.is-medium{font-size:1.25rem}.message.is-large{font-size:1.5rem}.message.is-white{background-color:#fff}.message.is-white .message-header{background-color:#fff;color:#0a0a0a}.message.is-white .message-body{border-color:#fff}.message.is-black{background-color:#fafafa}.message.is-black .message-header{background-color:#0a0a0a;color:#fff}.message.is-black .message-body{border-color:#0a0a0a}.message.is-light{background-color:#fafafa}.message.is-light .message-header{background-color:#f5f5f5;color:rgba(0,0,0,0.7)}.message.is-light .message-body{border-color:#f5f5f5}.message.is-dark,.content kbd.message{background-color:#fafafa}.message.is-dark .message-header,.content kbd.message .message-header{background-color:#363636;color:#fff}.message.is-dark .message-body,.content kbd.message .message-body{border-color:#363636}.message.is-primary,.docstring>section>a.message.docs-sourcelink{background-color:#eef8fc}.message.is-primary .message-header,.docstring>section>a.message.docs-sourcelink .message-header{background-color:#4eb5de;color:#fff}.message.is-primary .message-body,.docstring>section>a.message.docs-sourcelink .message-body{border-color:#4eb5de;color:#1a6d8e}.message.is-link{background-color:#eff3fb}.message.is-link .message-header{background-color:#2e63b8;color:#fff}.message.is-link .message-body{border-color:#2e63b8;color:#3169c4}.message.is-info{background-color:#ecf7fe}.message.is-info .message-header{background-color:#209cee;color:#fff}.message.is-info .message-body{border-color:#209cee;color:#0e72b4}.message.is-success{background-color:#eefcf3}.message.is-success .message-header{background-color:#22c35b;color:#fff}.message.is-success .message-body{border-color:#22c35b;color:#198f43}.message.is-warning{background-color:#fffbeb}.message.is-warning .message-header{background-color:#ffdd57;color:rgba(0,0,0,0.7)}.message.is-warning .message-body{border-color:#ffdd57;color:#947600}.message.is-danger{background-color:#ffeceb}.message.is-danger .message-header{background-color:#da0b00;color:#fff}.message.is-danger .message-body{border-color:#da0b00;color:#f50c00}.message-header{align-items:center;background-color:#222;border-radius:4px 4px 0 0;color:#fff;display:flex;font-weight:700;justify-content:space-between;line-height:1.25;padding:0.75em 1em;position:relative}.message-header .delete{flex-grow:0;flex-shrink:0;margin-left:.75em}.message-header+.message-body{border-width:0;border-top-left-radius:0;border-top-right-radius:0}.message-body{border-color:#dbdbdb;border-radius:4px;border-style:solid;border-width:0 0 0 4px;color:#222;padding:1.25em 1.5em}.message-body code,.message-body pre{background-color:#fff}.message-body pre code{background-color:rgba(0,0,0,0)}.modal{align-items:center;display:none;flex-direction:column;justify-content:center;overflow:hidden;position:fixed;z-index:40}.modal.is-active{display:flex}.modal-background{background-color:rgba(10,10,10,0.86)}.modal-content,.modal-card{margin:0 20px;max-height:calc(100vh - 160px);overflow:auto;position:relative;width:100%}@media screen and (min-width: 769px){.modal-content,.modal-card{margin:0 auto;max-height:calc(100vh - 40px);width:640px}}.modal-close{background:none;height:40px;position:fixed;right:20px;top:20px;width:40px}.modal-card{display:flex;flex-direction:column;max-height:calc(100vh - 40px);overflow:hidden;-ms-overflow-y:visible}.modal-card-head,.modal-card-foot{align-items:center;background-color:#f5f5f5;display:flex;flex-shrink:0;justify-content:flex-start;padding:20px;position:relative}.modal-card-head{border-bottom:1px solid #dbdbdb;border-top-left-radius:6px;border-top-right-radius:6px}.modal-card-title{color:#222;flex-grow:1;flex-shrink:0;font-size:1.5rem;line-height:1}.modal-card-foot{border-bottom-left-radius:6px;border-bottom-right-radius:6px;border-top:1px solid #dbdbdb}.modal-card-foot .button:not(:last-child){margin-right:.5em}.modal-card-body{-webkit-overflow-scrolling:touch;background-color:#fff;flex-grow:1;flex-shrink:1;overflow:auto;padding:20px}.navbar{background-color:#fff;min-height:3.25rem;position:relative;z-index:30}.navbar.is-white{background-color:#fff;color:#0a0a0a}.navbar.is-white .navbar-brand>.navbar-item,.navbar.is-white .navbar-brand .navbar-link{color:#0a0a0a}.navbar.is-white .navbar-brand>a.navbar-item:focus,.navbar.is-white .navbar-brand>a.navbar-item:hover,.navbar.is-white .navbar-brand>a.navbar-item.is-active,.navbar.is-white .navbar-brand .navbar-link:focus,.navbar.is-white .navbar-brand .navbar-link:hover,.navbar.is-white .navbar-brand .navbar-link.is-active{background-color:#f2f2f2;color:#0a0a0a}.navbar.is-white .navbar-brand .navbar-link::after{border-color:#0a0a0a}.navbar.is-white .navbar-burger{color:#0a0a0a}@media screen and (min-width: 1056px){.navbar.is-white .navbar-start>.navbar-item,.navbar.is-white .navbar-start .navbar-link,.navbar.is-white .navbar-end>.navbar-item,.navbar.is-white .navbar-end .navbar-link{color:#0a0a0a}.navbar.is-white .navbar-start>a.navbar-item:focus,.navbar.is-white .navbar-start>a.navbar-item:hover,.navbar.is-white .navbar-start>a.navbar-item.is-active,.navbar.is-white .navbar-start .navbar-link:focus,.navbar.is-white .navbar-start .navbar-link:hover,.navbar.is-white .navbar-start .navbar-link.is-active,.navbar.is-white .navbar-end>a.navbar-item:focus,.navbar.is-white .navbar-end>a.navbar-item:hover,.navbar.is-white .navbar-end>a.navbar-item.is-active,.navbar.is-white .navbar-end .navbar-link:focus,.navbar.is-white .navbar-end .navbar-link:hover,.navbar.is-white .navbar-end .navbar-link.is-active{background-color:#f2f2f2;color:#0a0a0a}.navbar.is-white .navbar-start .navbar-link::after,.navbar.is-white .navbar-end .navbar-link::after{border-color:#0a0a0a}.navbar.is-white .navbar-item.has-dropdown:focus .navbar-link,.navbar.is-white .navbar-item.has-dropdown:hover .navbar-link,.navbar.is-white .navbar-item.has-dropdown.is-active .navbar-link{background-color:#f2f2f2;color:#0a0a0a}.navbar.is-white .navbar-dropdown a.navbar-item.is-active{background-color:#fff;color:#0a0a0a}}.navbar.is-black{background-color:#0a0a0a;color:#fff}.navbar.is-black .navbar-brand>.navbar-item,.navbar.is-black .navbar-brand .navbar-link{color:#fff}.navbar.is-black .navbar-brand>a.navbar-item:focus,.navbar.is-black .navbar-brand>a.navbar-item:hover,.navbar.is-black .navbar-brand>a.navbar-item.is-active,.navbar.is-black .navbar-brand .navbar-link:focus,.navbar.is-black .navbar-brand .navbar-link:hover,.navbar.is-black .navbar-brand .navbar-link.is-active{background-color:#000;color:#fff}.navbar.is-black .navbar-brand .navbar-link::after{border-color:#fff}.navbar.is-black .navbar-burger{color:#fff}@media screen and (min-width: 1056px){.navbar.is-black .navbar-start>.navbar-item,.navbar.is-black .navbar-start .navbar-link,.navbar.is-black .navbar-end>.navbar-item,.navbar.is-black .navbar-end .navbar-link{color:#fff}.navbar.is-black .navbar-start>a.navbar-item:focus,.navbar.is-black .navbar-start>a.navbar-item:hover,.navbar.is-black .navbar-start>a.navbar-item.is-active,.navbar.is-black .navbar-start .navbar-link:focus,.navbar.is-black .navbar-start .navbar-link:hover,.navbar.is-black .navbar-start .navbar-link.is-active,.navbar.is-black .navbar-end>a.navbar-item:focus,.navbar.is-black .navbar-end>a.navbar-item:hover,.navbar.is-black .navbar-end>a.navbar-item.is-active,.navbar.is-black .navbar-end .navbar-link:focus,.navbar.is-black .navbar-end .navbar-link:hover,.navbar.is-black .navbar-end .navbar-link.is-active{background-color:#000;color:#fff}.navbar.is-black .navbar-start .navbar-link::after,.navbar.is-black .navbar-end .navbar-link::after{border-color:#fff}.navbar.is-black .navbar-item.has-dropdown:focus .navbar-link,.navbar.is-black .navbar-item.has-dropdown:hover .navbar-link,.navbar.is-black .navbar-item.has-dropdown.is-active .navbar-link{background-color:#000;color:#fff}.navbar.is-black .navbar-dropdown a.navbar-item.is-active{background-color:#0a0a0a;color:#fff}}.navbar.is-light{background-color:#f5f5f5;color:rgba(0,0,0,0.7)}.navbar.is-light .navbar-brand>.navbar-item,.navbar.is-light .navbar-brand .navbar-link{color:rgba(0,0,0,0.7)}.navbar.is-light .navbar-brand>a.navbar-item:focus,.navbar.is-light .navbar-brand>a.navbar-item:hover,.navbar.is-light .navbar-brand>a.navbar-item.is-active,.navbar.is-light .navbar-brand .navbar-link:focus,.navbar.is-light .navbar-brand .navbar-link:hover,.navbar.is-light .navbar-brand .navbar-link.is-active{background-color:#e8e8e8;color:rgba(0,0,0,0.7)}.navbar.is-light .navbar-brand .navbar-link::after{border-color:rgba(0,0,0,0.7)}.navbar.is-light .navbar-burger{color:rgba(0,0,0,0.7)}@media screen and (min-width: 1056px){.navbar.is-light .navbar-start>.navbar-item,.navbar.is-light .navbar-start .navbar-link,.navbar.is-light .navbar-end>.navbar-item,.navbar.is-light .navbar-end .navbar-link{color:rgba(0,0,0,0.7)}.navbar.is-light .navbar-start>a.navbar-item:focus,.navbar.is-light .navbar-start>a.navbar-item:hover,.navbar.is-light .navbar-start>a.navbar-item.is-active,.navbar.is-light .navbar-start .navbar-link:focus,.navbar.is-light .navbar-start .navbar-link:hover,.navbar.is-light .navbar-start .navbar-link.is-active,.navbar.is-light .navbar-end>a.navbar-item:focus,.navbar.is-light .navbar-end>a.navbar-item:hover,.navbar.is-light .navbar-end>a.navbar-item.is-active,.navbar.is-light .navbar-end .navbar-link:focus,.navbar.is-light .navbar-end .navbar-link:hover,.navbar.is-light .navbar-end .navbar-link.is-active{background-color:#e8e8e8;color:rgba(0,0,0,0.7)}.navbar.is-light .navbar-start .navbar-link::after,.navbar.is-light .navbar-end .navbar-link::after{border-color:rgba(0,0,0,0.7)}.navbar.is-light .navbar-item.has-dropdown:focus .navbar-link,.navbar.is-light .navbar-item.has-dropdown:hover .navbar-link,.navbar.is-light .navbar-item.has-dropdown.is-active .navbar-link{background-color:#e8e8e8;color:rgba(0,0,0,0.7)}.navbar.is-light .navbar-dropdown a.navbar-item.is-active{background-color:#f5f5f5;color:rgba(0,0,0,0.7)}}.navbar.is-dark,.content kbd.navbar{background-color:#363636;color:#fff}.navbar.is-dark .navbar-brand>.navbar-item,.content kbd.navbar .navbar-brand>.navbar-item,.navbar.is-dark .navbar-brand .navbar-link,.content kbd.navbar .navbar-brand .navbar-link{color:#fff}.navbar.is-dark .navbar-brand>a.navbar-item:focus,.content kbd.navbar .navbar-brand>a.navbar-item:focus,.navbar.is-dark .navbar-brand>a.navbar-item:hover,.content kbd.navbar .navbar-brand>a.navbar-item:hover,.navbar.is-dark .navbar-brand>a.navbar-item.is-active,.content kbd.navbar .navbar-brand>a.navbar-item.is-active,.navbar.is-dark .navbar-brand .navbar-link:focus,.content kbd.navbar .navbar-brand .navbar-link:focus,.navbar.is-dark .navbar-brand .navbar-link:hover,.content kbd.navbar .navbar-brand .navbar-link:hover,.navbar.is-dark .navbar-brand .navbar-link.is-active,.content kbd.navbar .navbar-brand .navbar-link.is-active{background-color:#292929;color:#fff}.navbar.is-dark .navbar-brand .navbar-link::after,.content kbd.navbar .navbar-brand .navbar-link::after{border-color:#fff}.navbar.is-dark .navbar-burger,.content kbd.navbar .navbar-burger{color:#fff}@media screen and (min-width: 1056px){.navbar.is-dark .navbar-start>.navbar-item,.content kbd.navbar .navbar-start>.navbar-item,.navbar.is-dark .navbar-start .navbar-link,.content kbd.navbar .navbar-start .navbar-link,.navbar.is-dark .navbar-end>.navbar-item,.content kbd.navbar .navbar-end>.navbar-item,.navbar.is-dark .navbar-end .navbar-link,.content kbd.navbar .navbar-end .navbar-link{color:#fff}.navbar.is-dark .navbar-start>a.navbar-item:focus,.content kbd.navbar .navbar-start>a.navbar-item:focus,.navbar.is-dark .navbar-start>a.navbar-item:hover,.content kbd.navbar .navbar-start>a.navbar-item:hover,.navbar.is-dark .navbar-start>a.navbar-item.is-active,.content kbd.navbar .navbar-start>a.navbar-item.is-active,.navbar.is-dark .navbar-start .navbar-link:focus,.content kbd.navbar .navbar-start .navbar-link:focus,.navbar.is-dark .navbar-start .navbar-link:hover,.content kbd.navbar .navbar-start .navbar-link:hover,.navbar.is-dark .navbar-start .navbar-link.is-active,.content kbd.navbar .navbar-start .navbar-link.is-active,.navbar.is-dark .navbar-end>a.navbar-item:focus,.content kbd.navbar .navbar-end>a.navbar-item:focus,.navbar.is-dark .navbar-end>a.navbar-item:hover,.content kbd.navbar .navbar-end>a.navbar-item:hover,.navbar.is-dark .navbar-end>a.navbar-item.is-active,.content kbd.navbar .navbar-end>a.navbar-item.is-active,.navbar.is-dark .navbar-end .navbar-link:focus,.content kbd.navbar .navbar-end .navbar-link:focus,.navbar.is-dark .navbar-end .navbar-link:hover,.content kbd.navbar .navbar-end .navbar-link:hover,.navbar.is-dark .navbar-end .navbar-link.is-active,.content kbd.navbar .navbar-end .navbar-link.is-active{background-color:#292929;color:#fff}.navbar.is-dark .navbar-start .navbar-link::after,.content kbd.navbar .navbar-start .navbar-link::after,.navbar.is-dark .navbar-end .navbar-link::after,.content kbd.navbar .navbar-end .navbar-link::after{border-color:#fff}.navbar.is-dark .navbar-item.has-dropdown:focus .navbar-link,.content kbd.navbar .navbar-item.has-dropdown:focus .navbar-link,.navbar.is-dark .navbar-item.has-dropdown:hover .navbar-link,.content kbd.navbar .navbar-item.has-dropdown:hover .navbar-link,.navbar.is-dark .navbar-item.has-dropdown.is-active .navbar-link,.content kbd.navbar .navbar-item.has-dropdown.is-active .navbar-link{background-color:#292929;color:#fff}.navbar.is-dark .navbar-dropdown a.navbar-item.is-active,.content kbd.navbar .navbar-dropdown a.navbar-item.is-active{background-color:#363636;color:#fff}}.navbar.is-primary,.docstring>section>a.navbar.docs-sourcelink{background-color:#4eb5de;color:#fff}.navbar.is-primary .navbar-brand>.navbar-item,.docstring>section>a.navbar.docs-sourcelink .navbar-brand>.navbar-item,.navbar.is-primary .navbar-brand .navbar-link,.docstring>section>a.navbar.docs-sourcelink .navbar-brand .navbar-link{color:#fff}.navbar.is-primary .navbar-brand>a.navbar-item:focus,.docstring>section>a.navbar.docs-sourcelink .navbar-brand>a.navbar-item:focus,.navbar.is-primary .navbar-brand>a.navbar-item:hover,.docstring>section>a.navbar.docs-sourcelink .navbar-brand>a.navbar-item:hover,.navbar.is-primary .navbar-brand>a.navbar-item.is-active,.docstring>section>a.navbar.docs-sourcelink .navbar-brand>a.navbar-item.is-active,.navbar.is-primary .navbar-brand .navbar-link:focus,.docstring>section>a.navbar.docs-sourcelink .navbar-brand .navbar-link:focus,.navbar.is-primary .navbar-brand .navbar-link:hover,.docstring>section>a.navbar.docs-sourcelink .navbar-brand .navbar-link:hover,.navbar.is-primary .navbar-brand .navbar-link.is-active,.docstring>section>a.navbar.docs-sourcelink .navbar-brand .navbar-link.is-active{background-color:#39acda;color:#fff}.navbar.is-primary .navbar-brand .navbar-link::after,.docstring>section>a.navbar.docs-sourcelink .navbar-brand .navbar-link::after{border-color:#fff}.navbar.is-primary .navbar-burger,.docstring>section>a.navbar.docs-sourcelink .navbar-burger{color:#fff}@media screen and (min-width: 1056px){.navbar.is-primary .navbar-start>.navbar-item,.docstring>section>a.navbar.docs-sourcelink .navbar-start>.navbar-item,.navbar.is-primary .navbar-start .navbar-link,.docstring>section>a.navbar.docs-sourcelink .navbar-start .navbar-link,.navbar.is-primary .navbar-end>.navbar-item,.docstring>section>a.navbar.docs-sourcelink .navbar-end>.navbar-item,.navbar.is-primary .navbar-end .navbar-link,.docstring>section>a.navbar.docs-sourcelink .navbar-end .navbar-link{color:#fff}.navbar.is-primary .navbar-start>a.navbar-item:focus,.docstring>section>a.navbar.docs-sourcelink .navbar-start>a.navbar-item:focus,.navbar.is-primary .navbar-start>a.navbar-item:hover,.docstring>section>a.navbar.docs-sourcelink .navbar-start>a.navbar-item:hover,.navbar.is-primary .navbar-start>a.navbar-item.is-active,.docstring>section>a.navbar.docs-sourcelink .navbar-start>a.navbar-item.is-active,.navbar.is-primary .navbar-start .navbar-link:focus,.docstring>section>a.navbar.docs-sourcelink .navbar-start .navbar-link:focus,.navbar.is-primary .navbar-start .navbar-link:hover,.docstring>section>a.navbar.docs-sourcelink .navbar-start .navbar-link:hover,.navbar.is-primary .navbar-start .navbar-link.is-active,.docstring>section>a.navbar.docs-sourcelink .navbar-start .navbar-link.is-active,.navbar.is-primary .navbar-end>a.navbar-item:focus,.docstring>section>a.navbar.docs-sourcelink .navbar-end>a.navbar-item:focus,.navbar.is-primary .navbar-end>a.navbar-item:hover,.docstring>section>a.navbar.docs-sourcelink .navbar-end>a.navbar-item:hover,.navbar.is-primary .navbar-end>a.navbar-item.is-active,.docstring>section>a.navbar.docs-sourcelink .navbar-end>a.navbar-item.is-active,.navbar.is-primary .navbar-end .navbar-link:focus,.docstring>section>a.navbar.docs-sourcelink .navbar-end .navbar-link:focus,.navbar.is-primary .navbar-end .navbar-link:hover,.docstring>section>a.navbar.docs-sourcelink .navbar-end .navbar-link:hover,.navbar.is-primary .navbar-end .navbar-link.is-active,.docstring>section>a.navbar.docs-sourcelink .navbar-end .navbar-link.is-active{background-color:#39acda;color:#fff}.navbar.is-primary .navbar-start .navbar-link::after,.docstring>section>a.navbar.docs-sourcelink .navbar-start .navbar-link::after,.navbar.is-primary .navbar-end .navbar-link::after,.docstring>section>a.navbar.docs-sourcelink .navbar-end .navbar-link::after{border-color:#fff}.navbar.is-primary .navbar-item.has-dropdown:focus .navbar-link,.docstring>section>a.navbar.docs-sourcelink .navbar-item.has-dropdown:focus .navbar-link,.navbar.is-primary .navbar-item.has-dropdown:hover .navbar-link,.docstring>section>a.navbar.docs-sourcelink .navbar-item.has-dropdown:hover .navbar-link,.navbar.is-primary .navbar-item.has-dropdown.is-active .navbar-link,.docstring>section>a.navbar.docs-sourcelink .navbar-item.has-dropdown.is-active .navbar-link{background-color:#39acda;color:#fff}.navbar.is-primary .navbar-dropdown a.navbar-item.is-active,.docstring>section>a.navbar.docs-sourcelink .navbar-dropdown a.navbar-item.is-active{background-color:#4eb5de;color:#fff}}.navbar.is-link{background-color:#2e63b8;color:#fff}.navbar.is-link .navbar-brand>.navbar-item,.navbar.is-link .navbar-brand .navbar-link{color:#fff}.navbar.is-link .navbar-brand>a.navbar-item:focus,.navbar.is-link .navbar-brand>a.navbar-item:hover,.navbar.is-link .navbar-brand>a.navbar-item.is-active,.navbar.is-link .navbar-brand .navbar-link:focus,.navbar.is-link .navbar-brand .navbar-link:hover,.navbar.is-link .navbar-brand .navbar-link.is-active{background-color:#2958a4;color:#fff}.navbar.is-link .navbar-brand .navbar-link::after{border-color:#fff}.navbar.is-link .navbar-burger{color:#fff}@media screen and (min-width: 1056px){.navbar.is-link .navbar-start>.navbar-item,.navbar.is-link .navbar-start .navbar-link,.navbar.is-link .navbar-end>.navbar-item,.navbar.is-link .navbar-end .navbar-link{color:#fff}.navbar.is-link .navbar-start>a.navbar-item:focus,.navbar.is-link .navbar-start>a.navbar-item:hover,.navbar.is-link .navbar-start>a.navbar-item.is-active,.navbar.is-link .navbar-start .navbar-link:focus,.navbar.is-link .navbar-start .navbar-link:hover,.navbar.is-link .navbar-start .navbar-link.is-active,.navbar.is-link .navbar-end>a.navbar-item:focus,.navbar.is-link .navbar-end>a.navbar-item:hover,.navbar.is-link .navbar-end>a.navbar-item.is-active,.navbar.is-link .navbar-end .navbar-link:focus,.navbar.is-link .navbar-end .navbar-link:hover,.navbar.is-link .navbar-end .navbar-link.is-active{background-color:#2958a4;color:#fff}.navbar.is-link .navbar-start .navbar-link::after,.navbar.is-link .navbar-end .navbar-link::after{border-color:#fff}.navbar.is-link .navbar-item.has-dropdown:focus .navbar-link,.navbar.is-link .navbar-item.has-dropdown:hover .navbar-link,.navbar.is-link .navbar-item.has-dropdown.is-active .navbar-link{background-color:#2958a4;color:#fff}.navbar.is-link .navbar-dropdown a.navbar-item.is-active{background-color:#2e63b8;color:#fff}}.navbar.is-info{background-color:#209cee;color:#fff}.navbar.is-info .navbar-brand>.navbar-item,.navbar.is-info .navbar-brand .navbar-link{color:#fff}.navbar.is-info .navbar-brand>a.navbar-item:focus,.navbar.is-info .navbar-brand>a.navbar-item:hover,.navbar.is-info .navbar-brand>a.navbar-item.is-active,.navbar.is-info .navbar-brand .navbar-link:focus,.navbar.is-info .navbar-brand .navbar-link:hover,.navbar.is-info .navbar-brand .navbar-link.is-active{background-color:#1190e3;color:#fff}.navbar.is-info .navbar-brand .navbar-link::after{border-color:#fff}.navbar.is-info .navbar-burger{color:#fff}@media screen and (min-width: 1056px){.navbar.is-info .navbar-start>.navbar-item,.navbar.is-info .navbar-start .navbar-link,.navbar.is-info .navbar-end>.navbar-item,.navbar.is-info .navbar-end .navbar-link{color:#fff}.navbar.is-info .navbar-start>a.navbar-item:focus,.navbar.is-info .navbar-start>a.navbar-item:hover,.navbar.is-info .navbar-start>a.navbar-item.is-active,.navbar.is-info .navbar-start .navbar-link:focus,.navbar.is-info .navbar-start .navbar-link:hover,.navbar.is-info .navbar-start .navbar-link.is-active,.navbar.is-info .navbar-end>a.navbar-item:focus,.navbar.is-info .navbar-end>a.navbar-item:hover,.navbar.is-info .navbar-end>a.navbar-item.is-active,.navbar.is-info .navbar-end .navbar-link:focus,.navbar.is-info .navbar-end .navbar-link:hover,.navbar.is-info .navbar-end .navbar-link.is-active{background-color:#1190e3;color:#fff}.navbar.is-info .navbar-start .navbar-link::after,.navbar.is-info .navbar-end .navbar-link::after{border-color:#fff}.navbar.is-info .navbar-item.has-dropdown:focus .navbar-link,.navbar.is-info .navbar-item.has-dropdown:hover .navbar-link,.navbar.is-info .navbar-item.has-dropdown.is-active .navbar-link{background-color:#1190e3;color:#fff}.navbar.is-info .navbar-dropdown a.navbar-item.is-active{background-color:#209cee;color:#fff}}.navbar.is-success{background-color:#22c35b;color:#fff}.navbar.is-success .navbar-brand>.navbar-item,.navbar.is-success .navbar-brand .navbar-link{color:#fff}.navbar.is-success .navbar-brand>a.navbar-item:focus,.navbar.is-success .navbar-brand>a.navbar-item:hover,.navbar.is-success .navbar-brand>a.navbar-item.is-active,.navbar.is-success .navbar-brand .navbar-link:focus,.navbar.is-success .navbar-brand .navbar-link:hover,.navbar.is-success .navbar-brand .navbar-link.is-active{background-color:#1ead51;color:#fff}.navbar.is-success .navbar-brand .navbar-link::after{border-color:#fff}.navbar.is-success .navbar-burger{color:#fff}@media screen and (min-width: 1056px){.navbar.is-success .navbar-start>.navbar-item,.navbar.is-success .navbar-start .navbar-link,.navbar.is-success .navbar-end>.navbar-item,.navbar.is-success .navbar-end .navbar-link{color:#fff}.navbar.is-success .navbar-start>a.navbar-item:focus,.navbar.is-success .navbar-start>a.navbar-item:hover,.navbar.is-success .navbar-start>a.navbar-item.is-active,.navbar.is-success .navbar-start .navbar-link:focus,.navbar.is-success .navbar-start .navbar-link:hover,.navbar.is-success .navbar-start .navbar-link.is-active,.navbar.is-success .navbar-end>a.navbar-item:focus,.navbar.is-success .navbar-end>a.navbar-item:hover,.navbar.is-success .navbar-end>a.navbar-item.is-active,.navbar.is-success .navbar-end .navbar-link:focus,.navbar.is-success .navbar-end .navbar-link:hover,.navbar.is-success .navbar-end .navbar-link.is-active{background-color:#1ead51;color:#fff}.navbar.is-success .navbar-start .navbar-link::after,.navbar.is-success .navbar-end .navbar-link::after{border-color:#fff}.navbar.is-success .navbar-item.has-dropdown:focus .navbar-link,.navbar.is-success .navbar-item.has-dropdown:hover .navbar-link,.navbar.is-success .navbar-item.has-dropdown.is-active .navbar-link{background-color:#1ead51;color:#fff}.navbar.is-success .navbar-dropdown a.navbar-item.is-active{background-color:#22c35b;color:#fff}}.navbar.is-warning{background-color:#ffdd57;color:rgba(0,0,0,0.7)}.navbar.is-warning .navbar-brand>.navbar-item,.navbar.is-warning .navbar-brand .navbar-link{color:rgba(0,0,0,0.7)}.navbar.is-warning .navbar-brand>a.navbar-item:focus,.navbar.is-warning .navbar-brand>a.navbar-item:hover,.navbar.is-warning .navbar-brand>a.navbar-item.is-active,.navbar.is-warning .navbar-brand .navbar-link:focus,.navbar.is-warning .navbar-brand .navbar-link:hover,.navbar.is-warning .navbar-brand .navbar-link.is-active{background-color:#ffd83e;color:rgba(0,0,0,0.7)}.navbar.is-warning .navbar-brand .navbar-link::after{border-color:rgba(0,0,0,0.7)}.navbar.is-warning .navbar-burger{color:rgba(0,0,0,0.7)}@media screen and (min-width: 1056px){.navbar.is-warning .navbar-start>.navbar-item,.navbar.is-warning .navbar-start .navbar-link,.navbar.is-warning .navbar-end>.navbar-item,.navbar.is-warning .navbar-end .navbar-link{color:rgba(0,0,0,0.7)}.navbar.is-warning .navbar-start>a.navbar-item:focus,.navbar.is-warning .navbar-start>a.navbar-item:hover,.navbar.is-warning .navbar-start>a.navbar-item.is-active,.navbar.is-warning .navbar-start .navbar-link:focus,.navbar.is-warning .navbar-start .navbar-link:hover,.navbar.is-warning .navbar-start .navbar-link.is-active,.navbar.is-warning .navbar-end>a.navbar-item:focus,.navbar.is-warning .navbar-end>a.navbar-item:hover,.navbar.is-warning .navbar-end>a.navbar-item.is-active,.navbar.is-warning .navbar-end .navbar-link:focus,.navbar.is-warning .navbar-end .navbar-link:hover,.navbar.is-warning .navbar-end .navbar-link.is-active{background-color:#ffd83e;color:rgba(0,0,0,0.7)}.navbar.is-warning .navbar-start .navbar-link::after,.navbar.is-warning .navbar-end .navbar-link::after{border-color:rgba(0,0,0,0.7)}.navbar.is-warning .navbar-item.has-dropdown:focus .navbar-link,.navbar.is-warning .navbar-item.has-dropdown:hover .navbar-link,.navbar.is-warning .navbar-item.has-dropdown.is-active .navbar-link{background-color:#ffd83e;color:rgba(0,0,0,0.7)}.navbar.is-warning .navbar-dropdown a.navbar-item.is-active{background-color:#ffdd57;color:rgba(0,0,0,0.7)}}.navbar.is-danger{background-color:#da0b00;color:#fff}.navbar.is-danger .navbar-brand>.navbar-item,.navbar.is-danger .navbar-brand .navbar-link{color:#fff}.navbar.is-danger .navbar-brand>a.navbar-item:focus,.navbar.is-danger .navbar-brand>a.navbar-item:hover,.navbar.is-danger .navbar-brand>a.navbar-item.is-active,.navbar.is-danger .navbar-brand .navbar-link:focus,.navbar.is-danger .navbar-brand .navbar-link:hover,.navbar.is-danger .navbar-brand .navbar-link.is-active{background-color:#c10a00;color:#fff}.navbar.is-danger .navbar-brand .navbar-link::after{border-color:#fff}.navbar.is-danger .navbar-burger{color:#fff}@media screen and (min-width: 1056px){.navbar.is-danger .navbar-start>.navbar-item,.navbar.is-danger .navbar-start .navbar-link,.navbar.is-danger .navbar-end>.navbar-item,.navbar.is-danger .navbar-end .navbar-link{color:#fff}.navbar.is-danger .navbar-start>a.navbar-item:focus,.navbar.is-danger .navbar-start>a.navbar-item:hover,.navbar.is-danger .navbar-start>a.navbar-item.is-active,.navbar.is-danger .navbar-start .navbar-link:focus,.navbar.is-danger .navbar-start .navbar-link:hover,.navbar.is-danger .navbar-start .navbar-link.is-active,.navbar.is-danger .navbar-end>a.navbar-item:focus,.navbar.is-danger .navbar-end>a.navbar-item:hover,.navbar.is-danger .navbar-end>a.navbar-item.is-active,.navbar.is-danger .navbar-end .navbar-link:focus,.navbar.is-danger .navbar-end .navbar-link:hover,.navbar.is-danger .navbar-end .navbar-link.is-active{background-color:#c10a00;color:#fff}.navbar.is-danger .navbar-start .navbar-link::after,.navbar.is-danger .navbar-end .navbar-link::after{border-color:#fff}.navbar.is-danger .navbar-item.has-dropdown:focus .navbar-link,.navbar.is-danger .navbar-item.has-dropdown:hover .navbar-link,.navbar.is-danger .navbar-item.has-dropdown.is-active .navbar-link{background-color:#c10a00;color:#fff}.navbar.is-danger .navbar-dropdown a.navbar-item.is-active{background-color:#da0b00;color:#fff}}.navbar>.container{align-items:stretch;display:flex;min-height:3.25rem;width:100%}.navbar.has-shadow{box-shadow:0 2px 0 0 #f5f5f5}.navbar.is-fixed-bottom,.navbar.is-fixed-top{left:0;position:fixed;right:0;z-index:30}.navbar.is-fixed-bottom{bottom:0}.navbar.is-fixed-bottom.has-shadow{box-shadow:0 -2px 0 0 #f5f5f5}.navbar.is-fixed-top{top:0}html.has-navbar-fixed-top,body.has-navbar-fixed-top{padding-top:3.25rem}html.has-navbar-fixed-bottom,body.has-navbar-fixed-bottom{padding-bottom:3.25rem}.navbar-brand,.navbar-tabs{align-items:stretch;display:flex;flex-shrink:0;min-height:3.25rem}.navbar-brand a.navbar-item:focus,.navbar-brand a.navbar-item:hover{background-color:transparent}.navbar-tabs{-webkit-overflow-scrolling:touch;max-width:100vw;overflow-x:auto;overflow-y:hidden}.navbar-burger{color:#222;-moz-appearance:none;-webkit-appearance:none;appearance:none;background:none;border:none;cursor:pointer;display:block;height:3.25rem;position:relative;width:3.25rem;margin-left:auto}.navbar-burger span{background-color:currentColor;display:block;height:1px;left:calc(50% - 8px);position:absolute;transform-origin:center;transition-duration:86ms;transition-property:background-color, opacity, transform;transition-timing-function:ease-out;width:16px}.navbar-burger span:nth-child(1){top:calc(50% - 6px)}.navbar-burger span:nth-child(2){top:calc(50% - 1px)}.navbar-burger span:nth-child(3){top:calc(50% + 4px)}.navbar-burger:hover{background-color:rgba(0,0,0,0.05)}.navbar-burger.is-active span:nth-child(1){transform:translateY(5px) rotate(45deg)}.navbar-burger.is-active span:nth-child(2){opacity:0}.navbar-burger.is-active span:nth-child(3){transform:translateY(-5px) rotate(-45deg)}.navbar-menu{display:none}.navbar-item,.navbar-link{color:#222;display:block;line-height:1.5;padding:0.5rem 0.75rem;position:relative}.navbar-item .icon:only-child,.navbar-link .icon:only-child{margin-left:-0.25rem;margin-right:-0.25rem}a.navbar-item,.navbar-link{cursor:pointer}a.navbar-item:focus,a.navbar-item:focus-within,a.navbar-item:hover,a.navbar-item.is-active,.navbar-link:focus,.navbar-link:focus-within,.navbar-link:hover,.navbar-link.is-active{background-color:#fafafa;color:#2e63b8}.navbar-item{flex-grow:0;flex-shrink:0}.navbar-item img{max-height:1.75rem}.navbar-item.has-dropdown{padding:0}.navbar-item.is-expanded{flex-grow:1;flex-shrink:1}.navbar-item.is-tab{border-bottom:1px solid transparent;min-height:3.25rem;padding-bottom:calc(0.5rem - 1px)}.navbar-item.is-tab:focus,.navbar-item.is-tab:hover{background-color:rgba(0,0,0,0);border-bottom-color:#2e63b8}.navbar-item.is-tab.is-active{background-color:rgba(0,0,0,0);border-bottom-color:#2e63b8;border-bottom-style:solid;border-bottom-width:3px;color:#2e63b8;padding-bottom:calc(0.5rem - 3px)}.navbar-content{flex-grow:1;flex-shrink:1}.navbar-link:not(.is-arrowless){padding-right:2.5em}.navbar-link:not(.is-arrowless)::after{border-color:#2e63b8;margin-top:-0.375em;right:1.125em}.navbar-dropdown{font-size:0.875rem;padding-bottom:0.5rem;padding-top:0.5rem}.navbar-dropdown .navbar-item{padding-left:1.5rem;padding-right:1.5rem}.navbar-divider{background-color:#f5f5f5;border:none;display:none;height:2px;margin:0.5rem 0}@media screen and (max-width: 1055px){.navbar>.container{display:block}.navbar-brand .navbar-item,.navbar-tabs .navbar-item{align-items:center;display:flex}.navbar-link::after{display:none}.navbar-menu{background-color:#fff;box-shadow:0 8px 16px rgba(10,10,10,0.1);padding:0.5rem 0}.navbar-menu.is-active{display:block}.navbar.is-fixed-bottom-touch,.navbar.is-fixed-top-touch{left:0;position:fixed;right:0;z-index:30}.navbar.is-fixed-bottom-touch{bottom:0}.navbar.is-fixed-bottom-touch.has-shadow{box-shadow:0 -2px 3px rgba(10,10,10,0.1)}.navbar.is-fixed-top-touch{top:0}.navbar.is-fixed-top .navbar-menu,.navbar.is-fixed-top-touch .navbar-menu{-webkit-overflow-scrolling:touch;max-height:calc(100vh - 3.25rem);overflow:auto}html.has-navbar-fixed-top-touch,body.has-navbar-fixed-top-touch{padding-top:3.25rem}html.has-navbar-fixed-bottom-touch,body.has-navbar-fixed-bottom-touch{padding-bottom:3.25rem}}@media screen and (min-width: 1056px){.navbar,.navbar-menu,.navbar-start,.navbar-end{align-items:stretch;display:flex}.navbar{min-height:3.25rem}.navbar.is-spaced{padding:1rem 2rem}.navbar.is-spaced .navbar-start,.navbar.is-spaced .navbar-end{align-items:center}.navbar.is-spaced a.navbar-item,.navbar.is-spaced .navbar-link{border-radius:4px}.navbar.is-transparent a.navbar-item:focus,.navbar.is-transparent a.navbar-item:hover,.navbar.is-transparent a.navbar-item.is-active,.navbar.is-transparent .navbar-link:focus,.navbar.is-transparent .navbar-link:hover,.navbar.is-transparent .navbar-link.is-active{background-color:transparent !important}.navbar.is-transparent .navbar-item.has-dropdown.is-active .navbar-link,.navbar.is-transparent .navbar-item.has-dropdown.is-hoverable:focus .navbar-link,.navbar.is-transparent .navbar-item.has-dropdown.is-hoverable:focus-within .navbar-link,.navbar.is-transparent .navbar-item.has-dropdown.is-hoverable:hover .navbar-link{background-color:transparent !important}.navbar.is-transparent .navbar-dropdown a.navbar-item:focus,.navbar.is-transparent .navbar-dropdown a.navbar-item:hover{background-color:#f5f5f5;color:#0a0a0a}.navbar.is-transparent .navbar-dropdown a.navbar-item.is-active{background-color:#f5f5f5;color:#2e63b8}.navbar-burger{display:none}.navbar-item,.navbar-link{align-items:center;display:flex}.navbar-item.has-dropdown{align-items:stretch}.navbar-item.has-dropdown-up .navbar-link::after{transform:rotate(135deg) translate(0.25em, -0.25em)}.navbar-item.has-dropdown-up .navbar-dropdown{border-bottom:2px solid #dbdbdb;border-radius:6px 6px 0 0;border-top:none;bottom:100%;box-shadow:0 -8px 8px rgba(10,10,10,0.1);top:auto}.navbar-item.is-active .navbar-dropdown,.navbar-item.is-hoverable:focus .navbar-dropdown,.navbar-item.is-hoverable:focus-within .navbar-dropdown,.navbar-item.is-hoverable:hover .navbar-dropdown{display:block}.navbar.is-spaced .navbar-item.is-active .navbar-dropdown,.navbar-item.is-active .navbar-dropdown.is-boxed,.navbar.is-spaced .navbar-item.is-hoverable:focus .navbar-dropdown,.navbar-item.is-hoverable:focus .navbar-dropdown.is-boxed,.navbar.is-spaced .navbar-item.is-hoverable:focus-within .navbar-dropdown,.navbar-item.is-hoverable:focus-within .navbar-dropdown.is-boxed,.navbar.is-spaced .navbar-item.is-hoverable:hover .navbar-dropdown,.navbar-item.is-hoverable:hover .navbar-dropdown.is-boxed{opacity:1;pointer-events:auto;transform:translateY(0)}.navbar-menu{flex-grow:1;flex-shrink:0}.navbar-start{justify-content:flex-start;margin-right:auto}.navbar-end{justify-content:flex-end;margin-left:auto}.navbar-dropdown{background-color:#fff;border-bottom-left-radius:6px;border-bottom-right-radius:6px;border-top:2px solid #dbdbdb;box-shadow:0 8px 8px rgba(10,10,10,0.1);display:none;font-size:0.875rem;left:0;min-width:100%;position:absolute;top:100%;z-index:20}.navbar-dropdown .navbar-item{padding:0.375rem 1rem;white-space:nowrap}.navbar-dropdown a.navbar-item{padding-right:3rem}.navbar-dropdown a.navbar-item:focus,.navbar-dropdown a.navbar-item:hover{background-color:#f5f5f5;color:#0a0a0a}.navbar-dropdown a.navbar-item.is-active{background-color:#f5f5f5;color:#2e63b8}.navbar.is-spaced .navbar-dropdown,.navbar-dropdown.is-boxed{border-radius:6px;border-top:none;box-shadow:0 8px 8px rgba(10,10,10,0.1), 0 0 0 1px rgba(10,10,10,0.1);display:block;opacity:0;pointer-events:none;top:calc(100% + (-4px));transform:translateY(-5px);transition-duration:86ms;transition-property:opacity, transform}.navbar-dropdown.is-right{left:auto;right:0}.navbar-divider{display:block}.navbar>.container .navbar-brand,.container>.navbar .navbar-brand{margin-left:-.75rem}.navbar>.container .navbar-menu,.container>.navbar .navbar-menu{margin-right:-.75rem}.navbar.is-fixed-bottom-desktop,.navbar.is-fixed-top-desktop{left:0;position:fixed;right:0;z-index:30}.navbar.is-fixed-bottom-desktop{bottom:0}.navbar.is-fixed-bottom-desktop.has-shadow{box-shadow:0 -2px 3px rgba(10,10,10,0.1)}.navbar.is-fixed-top-desktop{top:0}html.has-navbar-fixed-top-desktop,body.has-navbar-fixed-top-desktop{padding-top:3.25rem}html.has-navbar-fixed-bottom-desktop,body.has-navbar-fixed-bottom-desktop{padding-bottom:3.25rem}html.has-spaced-navbar-fixed-top,body.has-spaced-navbar-fixed-top{padding-top:5.25rem}html.has-spaced-navbar-fixed-bottom,body.has-spaced-navbar-fixed-bottom{padding-bottom:5.25rem}a.navbar-item.is-active,.navbar-link.is-active{color:#0a0a0a}a.navbar-item.is-active:not(:focus):not(:hover),.navbar-link.is-active:not(:focus):not(:hover){background-color:rgba(0,0,0,0)}.navbar-item.has-dropdown:focus .navbar-link,.navbar-item.has-dropdown:hover .navbar-link,.navbar-item.has-dropdown.is-active .navbar-link{background-color:#fafafa}}.hero.is-fullheight-with-navbar{min-height:calc(100vh - 3.25rem)}.pagination{font-size:1rem;margin:-.25rem}.pagination.is-small,#documenter .docs-sidebar form.docs-search>input.pagination{font-size:.75rem}.pagination.is-medium{font-size:1.25rem}.pagination.is-large{font-size:1.5rem}.pagination.is-rounded .pagination-previous,#documenter .docs-sidebar form.docs-search>input.pagination .pagination-previous,.pagination.is-rounded .pagination-next,#documenter .docs-sidebar form.docs-search>input.pagination .pagination-next{padding-left:1em;padding-right:1em;border-radius:9999px}.pagination.is-rounded .pagination-link,#documenter .docs-sidebar form.docs-search>input.pagination .pagination-link{border-radius:9999px}.pagination,.pagination-list{align-items:center;display:flex;justify-content:center;text-align:center}.pagination-previous,.pagination-next,.pagination-link,.pagination-ellipsis{font-size:1em;justify-content:center;margin:.25rem;padding-left:.5em;padding-right:.5em;text-align:center}.pagination-previous,.pagination-next,.pagination-link{border-color:#dbdbdb;color:#222;min-width:2.5em}.pagination-previous:hover,.pagination-next:hover,.pagination-link:hover{border-color:#b5b5b5;color:#363636}.pagination-previous:focus,.pagination-next:focus,.pagination-link:focus{border-color:#3c5dcd}.pagination-previous:active,.pagination-next:active,.pagination-link:active{box-shadow:inset 0 1px 2px rgba(10,10,10,0.2)}.pagination-previous[disabled],.pagination-previous.is-disabled,.pagination-next[disabled],.pagination-next.is-disabled,.pagination-link[disabled],.pagination-link.is-disabled{background-color:#dbdbdb;border-color:#dbdbdb;box-shadow:none;color:#6b6b6b;opacity:0.5}.pagination-previous,.pagination-next{padding-left:.75em;padding-right:.75em;white-space:nowrap}.pagination-link.is-current{background-color:#2e63b8;border-color:#2e63b8;color:#fff}.pagination-ellipsis{color:#b5b5b5;pointer-events:none}.pagination-list{flex-wrap:wrap}.pagination-list li{list-style:none}@media screen and (max-width: 768px){.pagination{flex-wrap:wrap}.pagination-previous,.pagination-next{flex-grow:1;flex-shrink:1}.pagination-list li{flex-grow:1;flex-shrink:1}}@media screen and (min-width: 769px),print{.pagination-list{flex-grow:1;flex-shrink:1;justify-content:flex-start;order:1}.pagination-previous,.pagination-next,.pagination-link,.pagination-ellipsis{margin-bottom:0;margin-top:0}.pagination-previous{order:2}.pagination-next{order:3}.pagination{justify-content:space-between;margin-bottom:0;margin-top:0}.pagination.is-centered .pagination-previous{order:1}.pagination.is-centered .pagination-list{justify-content:center;order:2}.pagination.is-centered .pagination-next{order:3}.pagination.is-right .pagination-previous{order:1}.pagination.is-right .pagination-next{order:2}.pagination.is-right .pagination-list{justify-content:flex-end;order:3}}.panel{border-radius:6px;box-shadow:#bbb;font-size:1rem}.panel:not(:last-child){margin-bottom:1.5rem}.panel.is-white .panel-heading{background-color:#fff;color:#0a0a0a}.panel.is-white .panel-tabs a.is-active{border-bottom-color:#fff}.panel.is-white .panel-block.is-active .panel-icon{color:#fff}.panel.is-black .panel-heading{background-color:#0a0a0a;color:#fff}.panel.is-black .panel-tabs a.is-active{border-bottom-color:#0a0a0a}.panel.is-black .panel-block.is-active .panel-icon{color:#0a0a0a}.panel.is-light .panel-heading{background-color:#f5f5f5;color:rgba(0,0,0,0.7)}.panel.is-light .panel-tabs a.is-active{border-bottom-color:#f5f5f5}.panel.is-light .panel-block.is-active .panel-icon{color:#f5f5f5}.panel.is-dark .panel-heading,.content kbd.panel .panel-heading{background-color:#363636;color:#fff}.panel.is-dark .panel-tabs a.is-active,.content kbd.panel .panel-tabs a.is-active{border-bottom-color:#363636}.panel.is-dark .panel-block.is-active .panel-icon,.content kbd.panel .panel-block.is-active .panel-icon{color:#363636}.panel.is-primary .panel-heading,.docstring>section>a.panel.docs-sourcelink .panel-heading{background-color:#4eb5de;color:#fff}.panel.is-primary .panel-tabs a.is-active,.docstring>section>a.panel.docs-sourcelink .panel-tabs a.is-active{border-bottom-color:#4eb5de}.panel.is-primary .panel-block.is-active .panel-icon,.docstring>section>a.panel.docs-sourcelink .panel-block.is-active .panel-icon{color:#4eb5de}.panel.is-link .panel-heading{background-color:#2e63b8;color:#fff}.panel.is-link .panel-tabs a.is-active{border-bottom-color:#2e63b8}.panel.is-link .panel-block.is-active .panel-icon{color:#2e63b8}.panel.is-info .panel-heading{background-color:#209cee;color:#fff}.panel.is-info .panel-tabs a.is-active{border-bottom-color:#209cee}.panel.is-info .panel-block.is-active .panel-icon{color:#209cee}.panel.is-success .panel-heading{background-color:#22c35b;color:#fff}.panel.is-success .panel-tabs a.is-active{border-bottom-color:#22c35b}.panel.is-success .panel-block.is-active .panel-icon{color:#22c35b}.panel.is-warning .panel-heading{background-color:#ffdd57;color:rgba(0,0,0,0.7)}.panel.is-warning .panel-tabs a.is-active{border-bottom-color:#ffdd57}.panel.is-warning .panel-block.is-active .panel-icon{color:#ffdd57}.panel.is-danger .panel-heading{background-color:#da0b00;color:#fff}.panel.is-danger .panel-tabs a.is-active{border-bottom-color:#da0b00}.panel.is-danger .panel-block.is-active .panel-icon{color:#da0b00}.panel-tabs:not(:last-child),.panel-block:not(:last-child){border-bottom:1px solid #ededed}.panel-heading{background-color:#ededed;border-radius:6px 6px 0 0;color:#222;font-size:1.25em;font-weight:700;line-height:1.25;padding:0.75em 1em}.panel-tabs{align-items:flex-end;display:flex;font-size:.875em;justify-content:center}.panel-tabs a{border-bottom:1px solid #dbdbdb;margin-bottom:-1px;padding:0.5em}.panel-tabs a.is-active{border-bottom-color:#4a4a4a;color:#363636}.panel-list a{color:#222}.panel-list a:hover{color:#2e63b8}.panel-block{align-items:center;color:#222;display:flex;justify-content:flex-start;padding:0.5em 0.75em}.panel-block input[type="checkbox"]{margin-right:.75em}.panel-block>.control{flex-grow:1;flex-shrink:1;width:100%}.panel-block.is-wrapped{flex-wrap:wrap}.panel-block.is-active{border-left-color:#2e63b8;color:#363636}.panel-block.is-active .panel-icon{color:#2e63b8}.panel-block:last-child{border-bottom-left-radius:6px;border-bottom-right-radius:6px}a.panel-block,label.panel-block{cursor:pointer}a.panel-block:hover,label.panel-block:hover{background-color:#f5f5f5}.panel-icon{display:inline-block;font-size:14px;height:1em;line-height:1em;text-align:center;vertical-align:top;width:1em;color:#6b6b6b;margin-right:.75em}.panel-icon .fa{font-size:inherit;line-height:inherit}.tabs{-webkit-overflow-scrolling:touch;align-items:stretch;display:flex;font-size:1rem;justify-content:space-between;overflow:hidden;overflow-x:auto;white-space:nowrap}.tabs a{align-items:center;border-bottom-color:#dbdbdb;border-bottom-style:solid;border-bottom-width:1px;color:#222;display:flex;justify-content:center;margin-bottom:-1px;padding:0.5em 1em;vertical-align:top}.tabs a:hover{border-bottom-color:#222;color:#222}.tabs li{display:block}.tabs li.is-active a{border-bottom-color:#2e63b8;color:#2e63b8}.tabs ul{align-items:center;border-bottom-color:#dbdbdb;border-bottom-style:solid;border-bottom-width:1px;display:flex;flex-grow:1;flex-shrink:0;justify-content:flex-start}.tabs ul.is-left{padding-right:0.75em}.tabs ul.is-center{flex:none;justify-content:center;padding-left:0.75em;padding-right:0.75em}.tabs ul.is-right{justify-content:flex-end;padding-left:0.75em}.tabs .icon:first-child{margin-right:.5em}.tabs .icon:last-child{margin-left:.5em}.tabs.is-centered ul{justify-content:center}.tabs.is-right ul{justify-content:flex-end}.tabs.is-boxed a{border:1px solid transparent;border-radius:4px 4px 0 0}.tabs.is-boxed a:hover{background-color:#f5f5f5;border-bottom-color:#dbdbdb}.tabs.is-boxed li.is-active a{background-color:#fff;border-color:#dbdbdb;border-bottom-color:rgba(0,0,0,0) !important}.tabs.is-fullwidth li{flex-grow:1;flex-shrink:0}.tabs.is-toggle a{border-color:#dbdbdb;border-style:solid;border-width:1px;margin-bottom:0;position:relative}.tabs.is-toggle a:hover{background-color:#f5f5f5;border-color:#b5b5b5;z-index:2}.tabs.is-toggle li+li{margin-left:-1px}.tabs.is-toggle li:first-child a{border-top-left-radius:4px;border-bottom-left-radius:4px}.tabs.is-toggle li:last-child a{border-top-right-radius:4px;border-bottom-right-radius:4px}.tabs.is-toggle li.is-active a{background-color:#2e63b8;border-color:#2e63b8;color:#fff;z-index:1}.tabs.is-toggle ul{border-bottom:none}.tabs.is-toggle.is-toggle-rounded li:first-child a{border-bottom-left-radius:9999px;border-top-left-radius:9999px;padding-left:1.25em}.tabs.is-toggle.is-toggle-rounded li:last-child a{border-bottom-right-radius:9999px;border-top-right-radius:9999px;padding-right:1.25em}.tabs.is-small,#documenter .docs-sidebar form.docs-search>input.tabs{font-size:.75rem}.tabs.is-medium{font-size:1.25rem}.tabs.is-large{font-size:1.5rem}.column{display:block;flex-basis:0;flex-grow:1;flex-shrink:1;padding:.75rem}.columns.is-mobile>.column.is-narrow{flex:none;width:unset}.columns.is-mobile>.column.is-full{flex:none;width:100%}.columns.is-mobile>.column.is-three-quarters{flex:none;width:75%}.columns.is-mobile>.column.is-two-thirds{flex:none;width:66.6666%}.columns.is-mobile>.column.is-half{flex:none;width:50%}.columns.is-mobile>.column.is-one-third{flex:none;width:33.3333%}.columns.is-mobile>.column.is-one-quarter{flex:none;width:25%}.columns.is-mobile>.column.is-one-fifth{flex:none;width:20%}.columns.is-mobile>.column.is-two-fifths{flex:none;width:40%}.columns.is-mobile>.column.is-three-fifths{flex:none;width:60%}.columns.is-mobile>.column.is-four-fifths{flex:none;width:80%}.columns.is-mobile>.column.is-offset-three-quarters{margin-left:75%}.columns.is-mobile>.column.is-offset-two-thirds{margin-left:66.6666%}.columns.is-mobile>.column.is-offset-half{margin-left:50%}.columns.is-mobile>.column.is-offset-one-third{margin-left:33.3333%}.columns.is-mobile>.column.is-offset-one-quarter{margin-left:25%}.columns.is-mobile>.column.is-offset-one-fifth{margin-left:20%}.columns.is-mobile>.column.is-offset-two-fifths{margin-left:40%}.columns.is-mobile>.column.is-offset-three-fifths{margin-left:60%}.columns.is-mobile>.column.is-offset-four-fifths{margin-left:80%}.columns.is-mobile>.column.is-0{flex:none;width:0%}.columns.is-mobile>.column.is-offset-0{margin-left:0%}.columns.is-mobile>.column.is-1{flex:none;width:8.33333337%}.columns.is-mobile>.column.is-offset-1{margin-left:8.33333337%}.columns.is-mobile>.column.is-2{flex:none;width:16.66666674%}.columns.is-mobile>.column.is-offset-2{margin-left:16.66666674%}.columns.is-mobile>.column.is-3{flex:none;width:25%}.columns.is-mobile>.column.is-offset-3{margin-left:25%}.columns.is-mobile>.column.is-4{flex:none;width:33.33333337%}.columns.is-mobile>.column.is-offset-4{margin-left:33.33333337%}.columns.is-mobile>.column.is-5{flex:none;width:41.66666674%}.columns.is-mobile>.column.is-offset-5{margin-left:41.66666674%}.columns.is-mobile>.column.is-6{flex:none;width:50%}.columns.is-mobile>.column.is-offset-6{margin-left:50%}.columns.is-mobile>.column.is-7{flex:none;width:58.33333337%}.columns.is-mobile>.column.is-offset-7{margin-left:58.33333337%}.columns.is-mobile>.column.is-8{flex:none;width:66.66666674%}.columns.is-mobile>.column.is-offset-8{margin-left:66.66666674%}.columns.is-mobile>.column.is-9{flex:none;width:75%}.columns.is-mobile>.column.is-offset-9{margin-left:75%}.columns.is-mobile>.column.is-10{flex:none;width:83.33333337%}.columns.is-mobile>.column.is-offset-10{margin-left:83.33333337%}.columns.is-mobile>.column.is-11{flex:none;width:91.66666674%}.columns.is-mobile>.column.is-offset-11{margin-left:91.66666674%}.columns.is-mobile>.column.is-12{flex:none;width:100%}.columns.is-mobile>.column.is-offset-12{margin-left:100%}@media screen and (max-width: 768px){.column.is-narrow-mobile{flex:none;width:unset}.column.is-full-mobile{flex:none;width:100%}.column.is-three-quarters-mobile{flex:none;width:75%}.column.is-two-thirds-mobile{flex:none;width:66.6666%}.column.is-half-mobile{flex:none;width:50%}.column.is-one-third-mobile{flex:none;width:33.3333%}.column.is-one-quarter-mobile{flex:none;width:25%}.column.is-one-fifth-mobile{flex:none;width:20%}.column.is-two-fifths-mobile{flex:none;width:40%}.column.is-three-fifths-mobile{flex:none;width:60%}.column.is-four-fifths-mobile{flex:none;width:80%}.column.is-offset-three-quarters-mobile{margin-left:75%}.column.is-offset-two-thirds-mobile{margin-left:66.6666%}.column.is-offset-half-mobile{margin-left:50%}.column.is-offset-one-third-mobile{margin-left:33.3333%}.column.is-offset-one-quarter-mobile{margin-left:25%}.column.is-offset-one-fifth-mobile{margin-left:20%}.column.is-offset-two-fifths-mobile{margin-left:40%}.column.is-offset-three-fifths-mobile{margin-left:60%}.column.is-offset-four-fifths-mobile{margin-left:80%}.column.is-0-mobile{flex:none;width:0%}.column.is-offset-0-mobile{margin-left:0%}.column.is-1-mobile{flex:none;width:8.33333337%}.column.is-offset-1-mobile{margin-left:8.33333337%}.column.is-2-mobile{flex:none;width:16.66666674%}.column.is-offset-2-mobile{margin-left:16.66666674%}.column.is-3-mobile{flex:none;width:25%}.column.is-offset-3-mobile{margin-left:25%}.column.is-4-mobile{flex:none;width:33.33333337%}.column.is-offset-4-mobile{margin-left:33.33333337%}.column.is-5-mobile{flex:none;width:41.66666674%}.column.is-offset-5-mobile{margin-left:41.66666674%}.column.is-6-mobile{flex:none;width:50%}.column.is-offset-6-mobile{margin-left:50%}.column.is-7-mobile{flex:none;width:58.33333337%}.column.is-offset-7-mobile{margin-left:58.33333337%}.column.is-8-mobile{flex:none;width:66.66666674%}.column.is-offset-8-mobile{margin-left:66.66666674%}.column.is-9-mobile{flex:none;width:75%}.column.is-offset-9-mobile{margin-left:75%}.column.is-10-mobile{flex:none;width:83.33333337%}.column.is-offset-10-mobile{margin-left:83.33333337%}.column.is-11-mobile{flex:none;width:91.66666674%}.column.is-offset-11-mobile{margin-left:91.66666674%}.column.is-12-mobile{flex:none;width:100%}.column.is-offset-12-mobile{margin-left:100%}}@media screen and (min-width: 769px),print{.column.is-narrow,.column.is-narrow-tablet{flex:none;width:unset}.column.is-full,.column.is-full-tablet{flex:none;width:100%}.column.is-three-quarters,.column.is-three-quarters-tablet{flex:none;width:75%}.column.is-two-thirds,.column.is-two-thirds-tablet{flex:none;width:66.6666%}.column.is-half,.column.is-half-tablet{flex:none;width:50%}.column.is-one-third,.column.is-one-third-tablet{flex:none;width:33.3333%}.column.is-one-quarter,.column.is-one-quarter-tablet{flex:none;width:25%}.column.is-one-fifth,.column.is-one-fifth-tablet{flex:none;width:20%}.column.is-two-fifths,.column.is-two-fifths-tablet{flex:none;width:40%}.column.is-three-fifths,.column.is-three-fifths-tablet{flex:none;width:60%}.column.is-four-fifths,.column.is-four-fifths-tablet{flex:none;width:80%}.column.is-offset-three-quarters,.column.is-offset-three-quarters-tablet{margin-left:75%}.column.is-offset-two-thirds,.column.is-offset-two-thirds-tablet{margin-left:66.6666%}.column.is-offset-half,.column.is-offset-half-tablet{margin-left:50%}.column.is-offset-one-third,.column.is-offset-one-third-tablet{margin-left:33.3333%}.column.is-offset-one-quarter,.column.is-offset-one-quarter-tablet{margin-left:25%}.column.is-offset-one-fifth,.column.is-offset-one-fifth-tablet{margin-left:20%}.column.is-offset-two-fifths,.column.is-offset-two-fifths-tablet{margin-left:40%}.column.is-offset-three-fifths,.column.is-offset-three-fifths-tablet{margin-left:60%}.column.is-offset-four-fifths,.column.is-offset-four-fifths-tablet{margin-left:80%}.column.is-0,.column.is-0-tablet{flex:none;width:0%}.column.is-offset-0,.column.is-offset-0-tablet{margin-left:0%}.column.is-1,.column.is-1-tablet{flex:none;width:8.33333337%}.column.is-offset-1,.column.is-offset-1-tablet{margin-left:8.33333337%}.column.is-2,.column.is-2-tablet{flex:none;width:16.66666674%}.column.is-offset-2,.column.is-offset-2-tablet{margin-left:16.66666674%}.column.is-3,.column.is-3-tablet{flex:none;width:25%}.column.is-offset-3,.column.is-offset-3-tablet{margin-left:25%}.column.is-4,.column.is-4-tablet{flex:none;width:33.33333337%}.column.is-offset-4,.column.is-offset-4-tablet{margin-left:33.33333337%}.column.is-5,.column.is-5-tablet{flex:none;width:41.66666674%}.column.is-offset-5,.column.is-offset-5-tablet{margin-left:41.66666674%}.column.is-6,.column.is-6-tablet{flex:none;width:50%}.column.is-offset-6,.column.is-offset-6-tablet{margin-left:50%}.column.is-7,.column.is-7-tablet{flex:none;width:58.33333337%}.column.is-offset-7,.column.is-offset-7-tablet{margin-left:58.33333337%}.column.is-8,.column.is-8-tablet{flex:none;width:66.66666674%}.column.is-offset-8,.column.is-offset-8-tablet{margin-left:66.66666674%}.column.is-9,.column.is-9-tablet{flex:none;width:75%}.column.is-offset-9,.column.is-offset-9-tablet{margin-left:75%}.column.is-10,.column.is-10-tablet{flex:none;width:83.33333337%}.column.is-offset-10,.column.is-offset-10-tablet{margin-left:83.33333337%}.column.is-11,.column.is-11-tablet{flex:none;width:91.66666674%}.column.is-offset-11,.column.is-offset-11-tablet{margin-left:91.66666674%}.column.is-12,.column.is-12-tablet{flex:none;width:100%}.column.is-offset-12,.column.is-offset-12-tablet{margin-left:100%}}@media screen and (max-width: 1055px){.column.is-narrow-touch{flex:none;width:unset}.column.is-full-touch{flex:none;width:100%}.column.is-three-quarters-touch{flex:none;width:75%}.column.is-two-thirds-touch{flex:none;width:66.6666%}.column.is-half-touch{flex:none;width:50%}.column.is-one-third-touch{flex:none;width:33.3333%}.column.is-one-quarter-touch{flex:none;width:25%}.column.is-one-fifth-touch{flex:none;width:20%}.column.is-two-fifths-touch{flex:none;width:40%}.column.is-three-fifths-touch{flex:none;width:60%}.column.is-four-fifths-touch{flex:none;width:80%}.column.is-offset-three-quarters-touch{margin-left:75%}.column.is-offset-two-thirds-touch{margin-left:66.6666%}.column.is-offset-half-touch{margin-left:50%}.column.is-offset-one-third-touch{margin-left:33.3333%}.column.is-offset-one-quarter-touch{margin-left:25%}.column.is-offset-one-fifth-touch{margin-left:20%}.column.is-offset-two-fifths-touch{margin-left:40%}.column.is-offset-three-fifths-touch{margin-left:60%}.column.is-offset-four-fifths-touch{margin-left:80%}.column.is-0-touch{flex:none;width:0%}.column.is-offset-0-touch{margin-left:0%}.column.is-1-touch{flex:none;width:8.33333337%}.column.is-offset-1-touch{margin-left:8.33333337%}.column.is-2-touch{flex:none;width:16.66666674%}.column.is-offset-2-touch{margin-left:16.66666674%}.column.is-3-touch{flex:none;width:25%}.column.is-offset-3-touch{margin-left:25%}.column.is-4-touch{flex:none;width:33.33333337%}.column.is-offset-4-touch{margin-left:33.33333337%}.column.is-5-touch{flex:none;width:41.66666674%}.column.is-offset-5-touch{margin-left:41.66666674%}.column.is-6-touch{flex:none;width:50%}.column.is-offset-6-touch{margin-left:50%}.column.is-7-touch{flex:none;width:58.33333337%}.column.is-offset-7-touch{margin-left:58.33333337%}.column.is-8-touch{flex:none;width:66.66666674%}.column.is-offset-8-touch{margin-left:66.66666674%}.column.is-9-touch{flex:none;width:75%}.column.is-offset-9-touch{margin-left:75%}.column.is-10-touch{flex:none;width:83.33333337%}.column.is-offset-10-touch{margin-left:83.33333337%}.column.is-11-touch{flex:none;width:91.66666674%}.column.is-offset-11-touch{margin-left:91.66666674%}.column.is-12-touch{flex:none;width:100%}.column.is-offset-12-touch{margin-left:100%}}@media screen and (min-width: 1056px){.column.is-narrow-desktop{flex:none;width:unset}.column.is-full-desktop{flex:none;width:100%}.column.is-three-quarters-desktop{flex:none;width:75%}.column.is-two-thirds-desktop{flex:none;width:66.6666%}.column.is-half-desktop{flex:none;width:50%}.column.is-one-third-desktop{flex:none;width:33.3333%}.column.is-one-quarter-desktop{flex:none;width:25%}.column.is-one-fifth-desktop{flex:none;width:20%}.column.is-two-fifths-desktop{flex:none;width:40%}.column.is-three-fifths-desktop{flex:none;width:60%}.column.is-four-fifths-desktop{flex:none;width:80%}.column.is-offset-three-quarters-desktop{margin-left:75%}.column.is-offset-two-thirds-desktop{margin-left:66.6666%}.column.is-offset-half-desktop{margin-left:50%}.column.is-offset-one-third-desktop{margin-left:33.3333%}.column.is-offset-one-quarter-desktop{margin-left:25%}.column.is-offset-one-fifth-desktop{margin-left:20%}.column.is-offset-two-fifths-desktop{margin-left:40%}.column.is-offset-three-fifths-desktop{margin-left:60%}.column.is-offset-four-fifths-desktop{margin-left:80%}.column.is-0-desktop{flex:none;width:0%}.column.is-offset-0-desktop{margin-left:0%}.column.is-1-desktop{flex:none;width:8.33333337%}.column.is-offset-1-desktop{margin-left:8.33333337%}.column.is-2-desktop{flex:none;width:16.66666674%}.column.is-offset-2-desktop{margin-left:16.66666674%}.column.is-3-desktop{flex:none;width:25%}.column.is-offset-3-desktop{margin-left:25%}.column.is-4-desktop{flex:none;width:33.33333337%}.column.is-offset-4-desktop{margin-left:33.33333337%}.column.is-5-desktop{flex:none;width:41.66666674%}.column.is-offset-5-desktop{margin-left:41.66666674%}.column.is-6-desktop{flex:none;width:50%}.column.is-offset-6-desktop{margin-left:50%}.column.is-7-desktop{flex:none;width:58.33333337%}.column.is-offset-7-desktop{margin-left:58.33333337%}.column.is-8-desktop{flex:none;width:66.66666674%}.column.is-offset-8-desktop{margin-left:66.66666674%}.column.is-9-desktop{flex:none;width:75%}.column.is-offset-9-desktop{margin-left:75%}.column.is-10-desktop{flex:none;width:83.33333337%}.column.is-offset-10-desktop{margin-left:83.33333337%}.column.is-11-desktop{flex:none;width:91.66666674%}.column.is-offset-11-desktop{margin-left:91.66666674%}.column.is-12-desktop{flex:none;width:100%}.column.is-offset-12-desktop{margin-left:100%}}@media screen and (min-width: 1216px){.column.is-narrow-widescreen{flex:none;width:unset}.column.is-full-widescreen{flex:none;width:100%}.column.is-three-quarters-widescreen{flex:none;width:75%}.column.is-two-thirds-widescreen{flex:none;width:66.6666%}.column.is-half-widescreen{flex:none;width:50%}.column.is-one-third-widescreen{flex:none;width:33.3333%}.column.is-one-quarter-widescreen{flex:none;width:25%}.column.is-one-fifth-widescreen{flex:none;width:20%}.column.is-two-fifths-widescreen{flex:none;width:40%}.column.is-three-fifths-widescreen{flex:none;width:60%}.column.is-four-fifths-widescreen{flex:none;width:80%}.column.is-offset-three-quarters-widescreen{margin-left:75%}.column.is-offset-two-thirds-widescreen{margin-left:66.6666%}.column.is-offset-half-widescreen{margin-left:50%}.column.is-offset-one-third-widescreen{margin-left:33.3333%}.column.is-offset-one-quarter-widescreen{margin-left:25%}.column.is-offset-one-fifth-widescreen{margin-left:20%}.column.is-offset-two-fifths-widescreen{margin-left:40%}.column.is-offset-three-fifths-widescreen{margin-left:60%}.column.is-offset-four-fifths-widescreen{margin-left:80%}.column.is-0-widescreen{flex:none;width:0%}.column.is-offset-0-widescreen{margin-left:0%}.column.is-1-widescreen{flex:none;width:8.33333337%}.column.is-offset-1-widescreen{margin-left:8.33333337%}.column.is-2-widescreen{flex:none;width:16.66666674%}.column.is-offset-2-widescreen{margin-left:16.66666674%}.column.is-3-widescreen{flex:none;width:25%}.column.is-offset-3-widescreen{margin-left:25%}.column.is-4-widescreen{flex:none;width:33.33333337%}.column.is-offset-4-widescreen{margin-left:33.33333337%}.column.is-5-widescreen{flex:none;width:41.66666674%}.column.is-offset-5-widescreen{margin-left:41.66666674%}.column.is-6-widescreen{flex:none;width:50%}.column.is-offset-6-widescreen{margin-left:50%}.column.is-7-widescreen{flex:none;width:58.33333337%}.column.is-offset-7-widescreen{margin-left:58.33333337%}.column.is-8-widescreen{flex:none;width:66.66666674%}.column.is-offset-8-widescreen{margin-left:66.66666674%}.column.is-9-widescreen{flex:none;width:75%}.column.is-offset-9-widescreen{margin-left:75%}.column.is-10-widescreen{flex:none;width:83.33333337%}.column.is-offset-10-widescreen{margin-left:83.33333337%}.column.is-11-widescreen{flex:none;width:91.66666674%}.column.is-offset-11-widescreen{margin-left:91.66666674%}.column.is-12-widescreen{flex:none;width:100%}.column.is-offset-12-widescreen{margin-left:100%}}@media screen and (min-width: 1408px){.column.is-narrow-fullhd{flex:none;width:unset}.column.is-full-fullhd{flex:none;width:100%}.column.is-three-quarters-fullhd{flex:none;width:75%}.column.is-two-thirds-fullhd{flex:none;width:66.6666%}.column.is-half-fullhd{flex:none;width:50%}.column.is-one-third-fullhd{flex:none;width:33.3333%}.column.is-one-quarter-fullhd{flex:none;width:25%}.column.is-one-fifth-fullhd{flex:none;width:20%}.column.is-two-fifths-fullhd{flex:none;width:40%}.column.is-three-fifths-fullhd{flex:none;width:60%}.column.is-four-fifths-fullhd{flex:none;width:80%}.column.is-offset-three-quarters-fullhd{margin-left:75%}.column.is-offset-two-thirds-fullhd{margin-left:66.6666%}.column.is-offset-half-fullhd{margin-left:50%}.column.is-offset-one-third-fullhd{margin-left:33.3333%}.column.is-offset-one-quarter-fullhd{margin-left:25%}.column.is-offset-one-fifth-fullhd{margin-left:20%}.column.is-offset-two-fifths-fullhd{margin-left:40%}.column.is-offset-three-fifths-fullhd{margin-left:60%}.column.is-offset-four-fifths-fullhd{margin-left:80%}.column.is-0-fullhd{flex:none;width:0%}.column.is-offset-0-fullhd{margin-left:0%}.column.is-1-fullhd{flex:none;width:8.33333337%}.column.is-offset-1-fullhd{margin-left:8.33333337%}.column.is-2-fullhd{flex:none;width:16.66666674%}.column.is-offset-2-fullhd{margin-left:16.66666674%}.column.is-3-fullhd{flex:none;width:25%}.column.is-offset-3-fullhd{margin-left:25%}.column.is-4-fullhd{flex:none;width:33.33333337%}.column.is-offset-4-fullhd{margin-left:33.33333337%}.column.is-5-fullhd{flex:none;width:41.66666674%}.column.is-offset-5-fullhd{margin-left:41.66666674%}.column.is-6-fullhd{flex:none;width:50%}.column.is-offset-6-fullhd{margin-left:50%}.column.is-7-fullhd{flex:none;width:58.33333337%}.column.is-offset-7-fullhd{margin-left:58.33333337%}.column.is-8-fullhd{flex:none;width:66.66666674%}.column.is-offset-8-fullhd{margin-left:66.66666674%}.column.is-9-fullhd{flex:none;width:75%}.column.is-offset-9-fullhd{margin-left:75%}.column.is-10-fullhd{flex:none;width:83.33333337%}.column.is-offset-10-fullhd{margin-left:83.33333337%}.column.is-11-fullhd{flex:none;width:91.66666674%}.column.is-offset-11-fullhd{margin-left:91.66666674%}.column.is-12-fullhd{flex:none;width:100%}.column.is-offset-12-fullhd{margin-left:100%}}.columns{margin-left:-.75rem;margin-right:-.75rem;margin-top:-.75rem}.columns:last-child{margin-bottom:-.75rem}.columns:not(:last-child){margin-bottom:calc(1.5rem - .75rem)}.columns.is-centered{justify-content:center}.columns.is-gapless{margin-left:0;margin-right:0;margin-top:0}.columns.is-gapless>.column{margin:0;padding:0 !important}.columns.is-gapless:not(:last-child){margin-bottom:1.5rem}.columns.is-gapless:last-child{margin-bottom:0}.columns.is-mobile{display:flex}.columns.is-multiline{flex-wrap:wrap}.columns.is-vcentered{align-items:center}@media screen and (min-width: 769px),print{.columns:not(.is-desktop){display:flex}}@media screen and (min-width: 1056px){.columns.is-desktop{display:flex}}.columns.is-variable{--columnGap: 0.75rem;margin-left:calc(-1 * var(--columnGap));margin-right:calc(-1 * var(--columnGap))}.columns.is-variable>.column{padding-left:var(--columnGap);padding-right:var(--columnGap)}.columns.is-variable.is-0{--columnGap: 0rem}@media screen and (max-width: 768px){.columns.is-variable.is-0-mobile{--columnGap: 0rem}}@media screen and (min-width: 769px),print{.columns.is-variable.is-0-tablet{--columnGap: 0rem}}@media screen and (min-width: 769px) and (max-width: 1055px){.columns.is-variable.is-0-tablet-only{--columnGap: 0rem}}@media screen and (max-width: 1055px){.columns.is-variable.is-0-touch{--columnGap: 0rem}}@media screen and (min-width: 1056px){.columns.is-variable.is-0-desktop{--columnGap: 0rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){.columns.is-variable.is-0-desktop-only{--columnGap: 0rem}}@media screen and (min-width: 1216px){.columns.is-variable.is-0-widescreen{--columnGap: 0rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){.columns.is-variable.is-0-widescreen-only{--columnGap: 0rem}}@media screen and (min-width: 1408px){.columns.is-variable.is-0-fullhd{--columnGap: 0rem}}.columns.is-variable.is-1{--columnGap: .25rem}@media screen and (max-width: 768px){.columns.is-variable.is-1-mobile{--columnGap: .25rem}}@media screen and (min-width: 769px),print{.columns.is-variable.is-1-tablet{--columnGap: .25rem}}@media screen and (min-width: 769px) and (max-width: 1055px){.columns.is-variable.is-1-tablet-only{--columnGap: .25rem}}@media screen and (max-width: 1055px){.columns.is-variable.is-1-touch{--columnGap: .25rem}}@media screen and (min-width: 1056px){.columns.is-variable.is-1-desktop{--columnGap: .25rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){.columns.is-variable.is-1-desktop-only{--columnGap: .25rem}}@media screen and (min-width: 1216px){.columns.is-variable.is-1-widescreen{--columnGap: .25rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){.columns.is-variable.is-1-widescreen-only{--columnGap: .25rem}}@media screen and (min-width: 1408px){.columns.is-variable.is-1-fullhd{--columnGap: .25rem}}.columns.is-variable.is-2{--columnGap: .5rem}@media screen and (max-width: 768px){.columns.is-variable.is-2-mobile{--columnGap: .5rem}}@media screen and (min-width: 769px),print{.columns.is-variable.is-2-tablet{--columnGap: .5rem}}@media screen and (min-width: 769px) and (max-width: 1055px){.columns.is-variable.is-2-tablet-only{--columnGap: .5rem}}@media screen and (max-width: 1055px){.columns.is-variable.is-2-touch{--columnGap: .5rem}}@media screen and (min-width: 1056px){.columns.is-variable.is-2-desktop{--columnGap: .5rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){.columns.is-variable.is-2-desktop-only{--columnGap: .5rem}}@media screen and (min-width: 1216px){.columns.is-variable.is-2-widescreen{--columnGap: .5rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){.columns.is-variable.is-2-widescreen-only{--columnGap: .5rem}}@media screen and (min-width: 1408px){.columns.is-variable.is-2-fullhd{--columnGap: .5rem}}.columns.is-variable.is-3{--columnGap: .75rem}@media screen and (max-width: 768px){.columns.is-variable.is-3-mobile{--columnGap: .75rem}}@media screen and (min-width: 769px),print{.columns.is-variable.is-3-tablet{--columnGap: .75rem}}@media screen and (min-width: 769px) and (max-width: 1055px){.columns.is-variable.is-3-tablet-only{--columnGap: .75rem}}@media screen and (max-width: 1055px){.columns.is-variable.is-3-touch{--columnGap: .75rem}}@media screen and (min-width: 1056px){.columns.is-variable.is-3-desktop{--columnGap: .75rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){.columns.is-variable.is-3-desktop-only{--columnGap: .75rem}}@media screen and (min-width: 1216px){.columns.is-variable.is-3-widescreen{--columnGap: .75rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){.columns.is-variable.is-3-widescreen-only{--columnGap: .75rem}}@media screen and (min-width: 1408px){.columns.is-variable.is-3-fullhd{--columnGap: .75rem}}.columns.is-variable.is-4{--columnGap: 1rem}@media screen and (max-width: 768px){.columns.is-variable.is-4-mobile{--columnGap: 1rem}}@media screen and (min-width: 769px),print{.columns.is-variable.is-4-tablet{--columnGap: 1rem}}@media screen and (min-width: 769px) and (max-width: 1055px){.columns.is-variable.is-4-tablet-only{--columnGap: 1rem}}@media screen and (max-width: 1055px){.columns.is-variable.is-4-touch{--columnGap: 1rem}}@media screen and (min-width: 1056px){.columns.is-variable.is-4-desktop{--columnGap: 1rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){.columns.is-variable.is-4-desktop-only{--columnGap: 1rem}}@media screen and (min-width: 1216px){.columns.is-variable.is-4-widescreen{--columnGap: 1rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){.columns.is-variable.is-4-widescreen-only{--columnGap: 1rem}}@media screen and (min-width: 1408px){.columns.is-variable.is-4-fullhd{--columnGap: 1rem}}.columns.is-variable.is-5{--columnGap: 1.25rem}@media screen and (max-width: 768px){.columns.is-variable.is-5-mobile{--columnGap: 1.25rem}}@media screen and (min-width: 769px),print{.columns.is-variable.is-5-tablet{--columnGap: 1.25rem}}@media screen and (min-width: 769px) and (max-width: 1055px){.columns.is-variable.is-5-tablet-only{--columnGap: 1.25rem}}@media screen and (max-width: 1055px){.columns.is-variable.is-5-touch{--columnGap: 1.25rem}}@media screen and (min-width: 1056px){.columns.is-variable.is-5-desktop{--columnGap: 1.25rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){.columns.is-variable.is-5-desktop-only{--columnGap: 1.25rem}}@media screen and (min-width: 1216px){.columns.is-variable.is-5-widescreen{--columnGap: 1.25rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){.columns.is-variable.is-5-widescreen-only{--columnGap: 1.25rem}}@media screen and (min-width: 1408px){.columns.is-variable.is-5-fullhd{--columnGap: 1.25rem}}.columns.is-variable.is-6{--columnGap: 1.5rem}@media screen and (max-width: 768px){.columns.is-variable.is-6-mobile{--columnGap: 1.5rem}}@media screen and (min-width: 769px),print{.columns.is-variable.is-6-tablet{--columnGap: 1.5rem}}@media screen and (min-width: 769px) and (max-width: 1055px){.columns.is-variable.is-6-tablet-only{--columnGap: 1.5rem}}@media screen and (max-width: 1055px){.columns.is-variable.is-6-touch{--columnGap: 1.5rem}}@media screen and (min-width: 1056px){.columns.is-variable.is-6-desktop{--columnGap: 1.5rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){.columns.is-variable.is-6-desktop-only{--columnGap: 1.5rem}}@media screen and (min-width: 1216px){.columns.is-variable.is-6-widescreen{--columnGap: 1.5rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){.columns.is-variable.is-6-widescreen-only{--columnGap: 1.5rem}}@media screen and (min-width: 1408px){.columns.is-variable.is-6-fullhd{--columnGap: 1.5rem}}.columns.is-variable.is-7{--columnGap: 1.75rem}@media screen and (max-width: 768px){.columns.is-variable.is-7-mobile{--columnGap: 1.75rem}}@media screen and (min-width: 769px),print{.columns.is-variable.is-7-tablet{--columnGap: 1.75rem}}@media screen and (min-width: 769px) and (max-width: 1055px){.columns.is-variable.is-7-tablet-only{--columnGap: 1.75rem}}@media screen and (max-width: 1055px){.columns.is-variable.is-7-touch{--columnGap: 1.75rem}}@media screen and (min-width: 1056px){.columns.is-variable.is-7-desktop{--columnGap: 1.75rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){.columns.is-variable.is-7-desktop-only{--columnGap: 1.75rem}}@media screen and (min-width: 1216px){.columns.is-variable.is-7-widescreen{--columnGap: 1.75rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){.columns.is-variable.is-7-widescreen-only{--columnGap: 1.75rem}}@media screen and (min-width: 1408px){.columns.is-variable.is-7-fullhd{--columnGap: 1.75rem}}.columns.is-variable.is-8{--columnGap: 2rem}@media screen and (max-width: 768px){.columns.is-variable.is-8-mobile{--columnGap: 2rem}}@media screen and (min-width: 769px),print{.columns.is-variable.is-8-tablet{--columnGap: 2rem}}@media screen and (min-width: 769px) and (max-width: 1055px){.columns.is-variable.is-8-tablet-only{--columnGap: 2rem}}@media screen and (max-width: 1055px){.columns.is-variable.is-8-touch{--columnGap: 2rem}}@media screen and (min-width: 1056px){.columns.is-variable.is-8-desktop{--columnGap: 2rem}}@media screen and (min-width: 1056px) and (max-width: 1215px){.columns.is-variable.is-8-desktop-only{--columnGap: 2rem}}@media screen and (min-width: 1216px){.columns.is-variable.is-8-widescreen{--columnGap: 2rem}}@media screen and (min-width: 1216px) and (max-width: 1407px){.columns.is-variable.is-8-widescreen-only{--columnGap: 2rem}}@media screen and (min-width: 1408px){.columns.is-variable.is-8-fullhd{--columnGap: 2rem}}.tile{align-items:stretch;display:block;flex-basis:0;flex-grow:1;flex-shrink:1;min-height:min-content}.tile.is-ancestor{margin-left:-.75rem;margin-right:-.75rem;margin-top:-.75rem}.tile.is-ancestor:last-child{margin-bottom:-.75rem}.tile.is-ancestor:not(:last-child){margin-bottom:.75rem}.tile.is-child{margin:0 !important}.tile.is-parent{padding:.75rem}.tile.is-vertical{flex-direction:column}.tile.is-vertical>.tile.is-child:not(:last-child){margin-bottom:1.5rem !important}@media screen and (min-width: 769px),print{.tile:not(.is-child){display:flex}.tile.is-1{flex:none;width:8.33333337%}.tile.is-2{flex:none;width:16.66666674%}.tile.is-3{flex:none;width:25%}.tile.is-4{flex:none;width:33.33333337%}.tile.is-5{flex:none;width:41.66666674%}.tile.is-6{flex:none;width:50%}.tile.is-7{flex:none;width:58.33333337%}.tile.is-8{flex:none;width:66.66666674%}.tile.is-9{flex:none;width:75%}.tile.is-10{flex:none;width:83.33333337%}.tile.is-11{flex:none;width:91.66666674%}.tile.is-12{flex:none;width:100%}}.hero{align-items:stretch;display:flex;flex-direction:column;justify-content:space-between}.hero .navbar{background:none}.hero .tabs ul{border-bottom:none}.hero.is-white{background-color:#fff;color:#0a0a0a}.hero.is-white a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),.hero.is-white strong{color:inherit}.hero.is-white .title{color:#0a0a0a}.hero.is-white .subtitle{color:rgba(10,10,10,0.9)}.hero.is-white .subtitle a:not(.button),.hero.is-white .subtitle strong{color:#0a0a0a}@media screen and (max-width: 1055px){.hero.is-white .navbar-menu{background-color:#fff}}.hero.is-white .navbar-item,.hero.is-white .navbar-link{color:rgba(10,10,10,0.7)}.hero.is-white a.navbar-item:hover,.hero.is-white a.navbar-item.is-active,.hero.is-white .navbar-link:hover,.hero.is-white .navbar-link.is-active{background-color:#f2f2f2;color:#0a0a0a}.hero.is-white .tabs a{color:#0a0a0a;opacity:0.9}.hero.is-white .tabs a:hover{opacity:1}.hero.is-white .tabs li.is-active a{color:#fff !important;opacity:1}.hero.is-white .tabs.is-boxed a,.hero.is-white .tabs.is-toggle a{color:#0a0a0a}.hero.is-white .tabs.is-boxed a:hover,.hero.is-white .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}.hero.is-white .tabs.is-boxed li.is-active a,.hero.is-white .tabs.is-boxed li.is-active a:hover,.hero.is-white .tabs.is-toggle li.is-active a,.hero.is-white .tabs.is-toggle li.is-active a:hover{background-color:#0a0a0a;border-color:#0a0a0a;color:#fff}.hero.is-white.is-bold{background-image:linear-gradient(141deg, #e8e3e4 0%, #fff 71%, #fff 100%)}@media screen and (max-width: 768px){.hero.is-white.is-bold .navbar-menu{background-image:linear-gradient(141deg, #e8e3e4 0%, #fff 71%, #fff 100%)}}.hero.is-black{background-color:#0a0a0a;color:#fff}.hero.is-black a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),.hero.is-black strong{color:inherit}.hero.is-black .title{color:#fff}.hero.is-black .subtitle{color:rgba(255,255,255,0.9)}.hero.is-black .subtitle a:not(.button),.hero.is-black .subtitle strong{color:#fff}@media screen and (max-width: 1055px){.hero.is-black .navbar-menu{background-color:#0a0a0a}}.hero.is-black .navbar-item,.hero.is-black .navbar-link{color:rgba(255,255,255,0.7)}.hero.is-black a.navbar-item:hover,.hero.is-black a.navbar-item.is-active,.hero.is-black .navbar-link:hover,.hero.is-black .navbar-link.is-active{background-color:#000;color:#fff}.hero.is-black .tabs a{color:#fff;opacity:0.9}.hero.is-black .tabs a:hover{opacity:1}.hero.is-black .tabs li.is-active a{color:#0a0a0a !important;opacity:1}.hero.is-black .tabs.is-boxed a,.hero.is-black .tabs.is-toggle a{color:#fff}.hero.is-black .tabs.is-boxed a:hover,.hero.is-black .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}.hero.is-black .tabs.is-boxed li.is-active a,.hero.is-black .tabs.is-boxed li.is-active a:hover,.hero.is-black .tabs.is-toggle li.is-active a,.hero.is-black .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#0a0a0a}.hero.is-black.is-bold{background-image:linear-gradient(141deg, #000 0%, #0a0a0a 71%, #181616 100%)}@media screen and (max-width: 768px){.hero.is-black.is-bold .navbar-menu{background-image:linear-gradient(141deg, #000 0%, #0a0a0a 71%, #181616 100%)}}.hero.is-light{background-color:#f5f5f5;color:rgba(0,0,0,0.7)}.hero.is-light a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),.hero.is-light strong{color:inherit}.hero.is-light .title{color:rgba(0,0,0,0.7)}.hero.is-light .subtitle{color:rgba(0,0,0,0.9)}.hero.is-light .subtitle a:not(.button),.hero.is-light .subtitle strong{color:rgba(0,0,0,0.7)}@media screen and (max-width: 1055px){.hero.is-light .navbar-menu{background-color:#f5f5f5}}.hero.is-light .navbar-item,.hero.is-light .navbar-link{color:rgba(0,0,0,0.7)}.hero.is-light a.navbar-item:hover,.hero.is-light a.navbar-item.is-active,.hero.is-light .navbar-link:hover,.hero.is-light .navbar-link.is-active{background-color:#e8e8e8;color:rgba(0,0,0,0.7)}.hero.is-light .tabs a{color:rgba(0,0,0,0.7);opacity:0.9}.hero.is-light .tabs a:hover{opacity:1}.hero.is-light .tabs li.is-active a{color:#f5f5f5 !important;opacity:1}.hero.is-light .tabs.is-boxed a,.hero.is-light .tabs.is-toggle a{color:rgba(0,0,0,0.7)}.hero.is-light .tabs.is-boxed a:hover,.hero.is-light .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}.hero.is-light .tabs.is-boxed li.is-active a,.hero.is-light .tabs.is-boxed li.is-active a:hover,.hero.is-light .tabs.is-toggle li.is-active a,.hero.is-light .tabs.is-toggle li.is-active a:hover{background-color:rgba(0,0,0,0.7);border-color:rgba(0,0,0,0.7);color:#f5f5f5}.hero.is-light.is-bold{background-image:linear-gradient(141deg, #dfd8d9 0%, #f5f5f5 71%, #fff 100%)}@media screen and (max-width: 768px){.hero.is-light.is-bold .navbar-menu{background-image:linear-gradient(141deg, #dfd8d9 0%, #f5f5f5 71%, #fff 100%)}}.hero.is-dark,.content kbd.hero{background-color:#363636;color:#fff}.hero.is-dark a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),.content kbd.hero a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),.hero.is-dark strong,.content kbd.hero strong{color:inherit}.hero.is-dark .title,.content kbd.hero .title{color:#fff}.hero.is-dark .subtitle,.content kbd.hero .subtitle{color:rgba(255,255,255,0.9)}.hero.is-dark .subtitle a:not(.button),.content kbd.hero .subtitle a:not(.button),.hero.is-dark .subtitle strong,.content kbd.hero .subtitle strong{color:#fff}@media screen and (max-width: 1055px){.hero.is-dark .navbar-menu,.content kbd.hero .navbar-menu{background-color:#363636}}.hero.is-dark .navbar-item,.content kbd.hero .navbar-item,.hero.is-dark .navbar-link,.content kbd.hero .navbar-link{color:rgba(255,255,255,0.7)}.hero.is-dark a.navbar-item:hover,.content kbd.hero a.navbar-item:hover,.hero.is-dark a.navbar-item.is-active,.content kbd.hero a.navbar-item.is-active,.hero.is-dark .navbar-link:hover,.content kbd.hero .navbar-link:hover,.hero.is-dark .navbar-link.is-active,.content kbd.hero .navbar-link.is-active{background-color:#292929;color:#fff}.hero.is-dark .tabs a,.content kbd.hero .tabs a{color:#fff;opacity:0.9}.hero.is-dark .tabs a:hover,.content kbd.hero .tabs a:hover{opacity:1}.hero.is-dark .tabs li.is-active a,.content kbd.hero .tabs li.is-active a{color:#363636 !important;opacity:1}.hero.is-dark .tabs.is-boxed a,.content kbd.hero .tabs.is-boxed a,.hero.is-dark .tabs.is-toggle a,.content kbd.hero .tabs.is-toggle a{color:#fff}.hero.is-dark .tabs.is-boxed a:hover,.content kbd.hero .tabs.is-boxed a:hover,.hero.is-dark .tabs.is-toggle a:hover,.content kbd.hero .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}.hero.is-dark .tabs.is-boxed li.is-active a,.content kbd.hero .tabs.is-boxed li.is-active a,.hero.is-dark .tabs.is-boxed li.is-active a:hover,.hero.is-dark .tabs.is-toggle li.is-active a,.content kbd.hero .tabs.is-toggle li.is-active a,.hero.is-dark .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#363636}.hero.is-dark.is-bold,.content kbd.hero.is-bold{background-image:linear-gradient(141deg, #1f191a 0%, #363636 71%, #46403f 100%)}@media screen and (max-width: 768px){.hero.is-dark.is-bold .navbar-menu,.content kbd.hero.is-bold .navbar-menu{background-image:linear-gradient(141deg, #1f191a 0%, #363636 71%, #46403f 100%)}}.hero.is-primary,.docstring>section>a.hero.docs-sourcelink{background-color:#4eb5de;color:#fff}.hero.is-primary a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),.docstring>section>a.hero.docs-sourcelink a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),.hero.is-primary strong,.docstring>section>a.hero.docs-sourcelink strong{color:inherit}.hero.is-primary .title,.docstring>section>a.hero.docs-sourcelink .title{color:#fff}.hero.is-primary .subtitle,.docstring>section>a.hero.docs-sourcelink .subtitle{color:rgba(255,255,255,0.9)}.hero.is-primary .subtitle a:not(.button),.docstring>section>a.hero.docs-sourcelink .subtitle a:not(.button),.hero.is-primary .subtitle strong,.docstring>section>a.hero.docs-sourcelink .subtitle strong{color:#fff}@media screen and (max-width: 1055px){.hero.is-primary .navbar-menu,.docstring>section>a.hero.docs-sourcelink .navbar-menu{background-color:#4eb5de}}.hero.is-primary .navbar-item,.docstring>section>a.hero.docs-sourcelink .navbar-item,.hero.is-primary .navbar-link,.docstring>section>a.hero.docs-sourcelink .navbar-link{color:rgba(255,255,255,0.7)}.hero.is-primary a.navbar-item:hover,.docstring>section>a.hero.docs-sourcelink a.navbar-item:hover,.hero.is-primary a.navbar-item.is-active,.docstring>section>a.hero.docs-sourcelink a.navbar-item.is-active,.hero.is-primary .navbar-link:hover,.docstring>section>a.hero.docs-sourcelink .navbar-link:hover,.hero.is-primary .navbar-link.is-active,.docstring>section>a.hero.docs-sourcelink .navbar-link.is-active{background-color:#39acda;color:#fff}.hero.is-primary .tabs a,.docstring>section>a.hero.docs-sourcelink .tabs a{color:#fff;opacity:0.9}.hero.is-primary .tabs a:hover,.docstring>section>a.hero.docs-sourcelink .tabs a:hover{opacity:1}.hero.is-primary .tabs li.is-active a,.docstring>section>a.hero.docs-sourcelink .tabs li.is-active a{color:#4eb5de !important;opacity:1}.hero.is-primary .tabs.is-boxed a,.docstring>section>a.hero.docs-sourcelink .tabs.is-boxed a,.hero.is-primary .tabs.is-toggle a,.docstring>section>a.hero.docs-sourcelink .tabs.is-toggle a{color:#fff}.hero.is-primary .tabs.is-boxed a:hover,.docstring>section>a.hero.docs-sourcelink .tabs.is-boxed a:hover,.hero.is-primary .tabs.is-toggle a:hover,.docstring>section>a.hero.docs-sourcelink .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}.hero.is-primary .tabs.is-boxed li.is-active a,.docstring>section>a.hero.docs-sourcelink .tabs.is-boxed li.is-active a,.hero.is-primary .tabs.is-boxed li.is-active a:hover,.hero.is-primary .tabs.is-toggle li.is-active a,.docstring>section>a.hero.docs-sourcelink .tabs.is-toggle li.is-active a,.hero.is-primary .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#4eb5de}.hero.is-primary.is-bold,.docstring>section>a.hero.is-bold.docs-sourcelink{background-image:linear-gradient(141deg, #1bc7de 0%, #4eb5de 71%, #5fa9e7 100%)}@media screen and (max-width: 768px){.hero.is-primary.is-bold .navbar-menu,.docstring>section>a.hero.is-bold.docs-sourcelink .navbar-menu{background-image:linear-gradient(141deg, #1bc7de 0%, #4eb5de 71%, #5fa9e7 100%)}}.hero.is-link{background-color:#2e63b8;color:#fff}.hero.is-link a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),.hero.is-link strong{color:inherit}.hero.is-link .title{color:#fff}.hero.is-link .subtitle{color:rgba(255,255,255,0.9)}.hero.is-link .subtitle a:not(.button),.hero.is-link .subtitle strong{color:#fff}@media screen and (max-width: 1055px){.hero.is-link .navbar-menu{background-color:#2e63b8}}.hero.is-link .navbar-item,.hero.is-link .navbar-link{color:rgba(255,255,255,0.7)}.hero.is-link a.navbar-item:hover,.hero.is-link a.navbar-item.is-active,.hero.is-link .navbar-link:hover,.hero.is-link .navbar-link.is-active{background-color:#2958a4;color:#fff}.hero.is-link .tabs a{color:#fff;opacity:0.9}.hero.is-link .tabs a:hover{opacity:1}.hero.is-link .tabs li.is-active a{color:#2e63b8 !important;opacity:1}.hero.is-link .tabs.is-boxed a,.hero.is-link .tabs.is-toggle a{color:#fff}.hero.is-link .tabs.is-boxed a:hover,.hero.is-link .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}.hero.is-link .tabs.is-boxed li.is-active a,.hero.is-link .tabs.is-boxed li.is-active a:hover,.hero.is-link .tabs.is-toggle li.is-active a,.hero.is-link .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#2e63b8}.hero.is-link.is-bold{background-image:linear-gradient(141deg, #1b6098 0%, #2e63b8 71%, #2d51d2 100%)}@media screen and (max-width: 768px){.hero.is-link.is-bold .navbar-menu{background-image:linear-gradient(141deg, #1b6098 0%, #2e63b8 71%, #2d51d2 100%)}}.hero.is-info{background-color:#209cee;color:#fff}.hero.is-info a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),.hero.is-info strong{color:inherit}.hero.is-info .title{color:#fff}.hero.is-info .subtitle{color:rgba(255,255,255,0.9)}.hero.is-info .subtitle a:not(.button),.hero.is-info .subtitle strong{color:#fff}@media screen and (max-width: 1055px){.hero.is-info .navbar-menu{background-color:#209cee}}.hero.is-info .navbar-item,.hero.is-info .navbar-link{color:rgba(255,255,255,0.7)}.hero.is-info a.navbar-item:hover,.hero.is-info a.navbar-item.is-active,.hero.is-info .navbar-link:hover,.hero.is-info .navbar-link.is-active{background-color:#1190e3;color:#fff}.hero.is-info .tabs a{color:#fff;opacity:0.9}.hero.is-info .tabs a:hover{opacity:1}.hero.is-info .tabs li.is-active a{color:#209cee !important;opacity:1}.hero.is-info .tabs.is-boxed a,.hero.is-info .tabs.is-toggle a{color:#fff}.hero.is-info .tabs.is-boxed a:hover,.hero.is-info .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}.hero.is-info .tabs.is-boxed li.is-active a,.hero.is-info .tabs.is-boxed li.is-active a:hover,.hero.is-info .tabs.is-toggle li.is-active a,.hero.is-info .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#209cee}.hero.is-info.is-bold{background-image:linear-gradient(141deg, #05a6d6 0%, #209cee 71%, #3287f5 100%)}@media screen and (max-width: 768px){.hero.is-info.is-bold .navbar-menu{background-image:linear-gradient(141deg, #05a6d6 0%, #209cee 71%, #3287f5 100%)}}.hero.is-success{background-color:#22c35b;color:#fff}.hero.is-success a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),.hero.is-success strong{color:inherit}.hero.is-success .title{color:#fff}.hero.is-success .subtitle{color:rgba(255,255,255,0.9)}.hero.is-success .subtitle a:not(.button),.hero.is-success .subtitle strong{color:#fff}@media screen and (max-width: 1055px){.hero.is-success .navbar-menu{background-color:#22c35b}}.hero.is-success .navbar-item,.hero.is-success .navbar-link{color:rgba(255,255,255,0.7)}.hero.is-success a.navbar-item:hover,.hero.is-success a.navbar-item.is-active,.hero.is-success .navbar-link:hover,.hero.is-success .navbar-link.is-active{background-color:#1ead51;color:#fff}.hero.is-success .tabs a{color:#fff;opacity:0.9}.hero.is-success .tabs a:hover{opacity:1}.hero.is-success .tabs li.is-active a{color:#22c35b !important;opacity:1}.hero.is-success .tabs.is-boxed a,.hero.is-success .tabs.is-toggle a{color:#fff}.hero.is-success .tabs.is-boxed a:hover,.hero.is-success .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}.hero.is-success .tabs.is-boxed li.is-active a,.hero.is-success .tabs.is-boxed li.is-active a:hover,.hero.is-success .tabs.is-toggle li.is-active a,.hero.is-success .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#22c35b}.hero.is-success.is-bold{background-image:linear-gradient(141deg, #12a02c 0%, #22c35b 71%, #1fdf83 100%)}@media screen and (max-width: 768px){.hero.is-success.is-bold .navbar-menu{background-image:linear-gradient(141deg, #12a02c 0%, #22c35b 71%, #1fdf83 100%)}}.hero.is-warning{background-color:#ffdd57;color:rgba(0,0,0,0.7)}.hero.is-warning a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),.hero.is-warning strong{color:inherit}.hero.is-warning .title{color:rgba(0,0,0,0.7)}.hero.is-warning .subtitle{color:rgba(0,0,0,0.9)}.hero.is-warning .subtitle a:not(.button),.hero.is-warning .subtitle strong{color:rgba(0,0,0,0.7)}@media screen and (max-width: 1055px){.hero.is-warning .navbar-menu{background-color:#ffdd57}}.hero.is-warning .navbar-item,.hero.is-warning .navbar-link{color:rgba(0,0,0,0.7)}.hero.is-warning a.navbar-item:hover,.hero.is-warning a.navbar-item.is-active,.hero.is-warning .navbar-link:hover,.hero.is-warning .navbar-link.is-active{background-color:#ffd83e;color:rgba(0,0,0,0.7)}.hero.is-warning .tabs a{color:rgba(0,0,0,0.7);opacity:0.9}.hero.is-warning .tabs a:hover{opacity:1}.hero.is-warning .tabs li.is-active a{color:#ffdd57 !important;opacity:1}.hero.is-warning .tabs.is-boxed a,.hero.is-warning .tabs.is-toggle a{color:rgba(0,0,0,0.7)}.hero.is-warning .tabs.is-boxed a:hover,.hero.is-warning .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}.hero.is-warning .tabs.is-boxed li.is-active a,.hero.is-warning .tabs.is-boxed li.is-active a:hover,.hero.is-warning .tabs.is-toggle li.is-active a,.hero.is-warning .tabs.is-toggle li.is-active a:hover{background-color:rgba(0,0,0,0.7);border-color:rgba(0,0,0,0.7);color:#ffdd57}.hero.is-warning.is-bold{background-image:linear-gradient(141deg, #ffae24 0%, #ffdd57 71%, #fffa71 100%)}@media screen and (max-width: 768px){.hero.is-warning.is-bold .navbar-menu{background-image:linear-gradient(141deg, #ffae24 0%, #ffdd57 71%, #fffa71 100%)}}.hero.is-danger{background-color:#da0b00;color:#fff}.hero.is-danger a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),.hero.is-danger strong{color:inherit}.hero.is-danger .title{color:#fff}.hero.is-danger .subtitle{color:rgba(255,255,255,0.9)}.hero.is-danger .subtitle a:not(.button),.hero.is-danger .subtitle strong{color:#fff}@media screen and (max-width: 1055px){.hero.is-danger .navbar-menu{background-color:#da0b00}}.hero.is-danger .navbar-item,.hero.is-danger .navbar-link{color:rgba(255,255,255,0.7)}.hero.is-danger a.navbar-item:hover,.hero.is-danger a.navbar-item.is-active,.hero.is-danger .navbar-link:hover,.hero.is-danger .navbar-link.is-active{background-color:#c10a00;color:#fff}.hero.is-danger .tabs a{color:#fff;opacity:0.9}.hero.is-danger .tabs a:hover{opacity:1}.hero.is-danger .tabs li.is-active a{color:#da0b00 !important;opacity:1}.hero.is-danger .tabs.is-boxed a,.hero.is-danger .tabs.is-toggle a{color:#fff}.hero.is-danger .tabs.is-boxed a:hover,.hero.is-danger .tabs.is-toggle a:hover{background-color:rgba(10,10,10,0.1)}.hero.is-danger .tabs.is-boxed li.is-active a,.hero.is-danger .tabs.is-boxed li.is-active a:hover,.hero.is-danger .tabs.is-toggle li.is-active a,.hero.is-danger .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#da0b00}.hero.is-danger.is-bold{background-image:linear-gradient(141deg, #a70013 0%, #da0b00 71%, #f43500 100%)}@media screen and (max-width: 768px){.hero.is-danger.is-bold .navbar-menu{background-image:linear-gradient(141deg, #a70013 0%, #da0b00 71%, #f43500 100%)}}.hero.is-small .hero-body,#documenter .docs-sidebar form.docs-search>input.hero .hero-body{padding:1.5rem}@media screen and (min-width: 769px),print{.hero.is-medium .hero-body{padding:9rem 4.5rem}}@media screen and (min-width: 769px),print{.hero.is-large .hero-body{padding:18rem 6rem}}.hero.is-halfheight .hero-body,.hero.is-fullheight .hero-body,.hero.is-fullheight-with-navbar .hero-body{align-items:center;display:flex}.hero.is-halfheight .hero-body>.container,.hero.is-fullheight .hero-body>.container,.hero.is-fullheight-with-navbar .hero-body>.container{flex-grow:1;flex-shrink:1}.hero.is-halfheight{min-height:50vh}.hero.is-fullheight{min-height:100vh}.hero-video{overflow:hidden}.hero-video video{left:50%;min-height:100%;min-width:100%;position:absolute;top:50%;transform:translate3d(-50%, -50%, 0)}.hero-video.is-transparent{opacity:0.3}@media screen and (max-width: 768px){.hero-video{display:none}}.hero-buttons{margin-top:1.5rem}@media screen and (max-width: 768px){.hero-buttons .button{display:flex}.hero-buttons .button:not(:last-child){margin-bottom:0.75rem}}@media screen and (min-width: 769px),print{.hero-buttons{display:flex;justify-content:center}.hero-buttons .button:not(:last-child){margin-right:1.5rem}}.hero-head,.hero-foot{flex-grow:0;flex-shrink:0}.hero-body{flex-grow:1;flex-shrink:0;padding:3rem 1.5rem}@media screen and (min-width: 769px),print{.hero-body{padding:3rem 3rem}}.section{padding:3rem 1.5rem}@media screen and (min-width: 1056px){.section{padding:3rem 3rem}.section.is-medium{padding:9rem 4.5rem}.section.is-large{padding:18rem 6rem}}.footer{background-color:#fafafa;padding:3rem 1.5rem 6rem}h1 .docs-heading-anchor,h1 .docs-heading-anchor:hover,h1 .docs-heading-anchor:visited,h2 .docs-heading-anchor,h2 .docs-heading-anchor:hover,h2 .docs-heading-anchor:visited,h3 .docs-heading-anchor,h3 .docs-heading-anchor:hover,h3 .docs-heading-anchor:visited,h4 .docs-heading-anchor,h4 .docs-heading-anchor:hover,h4 .docs-heading-anchor:visited,h5 .docs-heading-anchor,h5 .docs-heading-anchor:hover,h5 .docs-heading-anchor:visited,h6 .docs-heading-anchor,h6 .docs-heading-anchor:hover,h6 .docs-heading-anchor:visited{color:#222}h1 .docs-heading-anchor-permalink,h2 .docs-heading-anchor-permalink,h3 .docs-heading-anchor-permalink,h4 .docs-heading-anchor-permalink,h5 .docs-heading-anchor-permalink,h6 .docs-heading-anchor-permalink{visibility:hidden;vertical-align:middle;margin-left:0.5em;font-size:0.7rem}h1 .docs-heading-anchor-permalink::before,h2 .docs-heading-anchor-permalink::before,h3 .docs-heading-anchor-permalink::before,h4 .docs-heading-anchor-permalink::before,h5 .docs-heading-anchor-permalink::before,h6 .docs-heading-anchor-permalink::before{font-family:"Font Awesome 6 Free";font-weight:900;content:"\f0c1"}h1:hover .docs-heading-anchor-permalink,h2:hover .docs-heading-anchor-permalink,h3:hover .docs-heading-anchor-permalink,h4:hover .docs-heading-anchor-permalink,h5:hover .docs-heading-anchor-permalink,h6:hover .docs-heading-anchor-permalink{visibility:visible}.docs-dark-only{display:none !important}pre{position:relative;overflow:hidden}pre code,pre code.hljs{padding:0 .75rem !important;overflow:auto;display:block}pre code:first-of-type,pre code.hljs:first-of-type{padding-top:0.5rem !important}pre code:last-of-type,pre code.hljs:last-of-type{padding-bottom:0.5rem !important}pre .copy-button{opacity:0.2;transition:opacity 0.2s;position:absolute;right:0em;top:0em;padding:0.5em;width:2.5em;height:2.5em;background:transparent;border:none;font-family:"Font Awesome 6 Free";color:#222;cursor:pointer;text-align:center}pre .copy-button:focus,pre .copy-button:hover{opacity:1;background:rgba(34,34,34,0.1);color:#2e63b8}pre .copy-button.success{color:#259a12;opacity:1}pre .copy-button.error{color:#cb3c33;opacity:1}pre:hover .copy-button{opacity:1}.admonition{background-color:#b5b5b5;border-style:solid;border-width:1px;border-color:#363636;border-radius:4px;font-size:1rem}.admonition strong{color:currentColor}.admonition.is-small,#documenter .docs-sidebar form.docs-search>input.admonition{font-size:.75rem}.admonition.is-medium{font-size:1.25rem}.admonition.is-large{font-size:1.5rem}.admonition.is-default{background-color:#b5b5b5;border-color:#363636}.admonition.is-default>.admonition-header{background-color:#363636;color:#fff}.admonition.is-default>.admonition-body{color:#fff}.admonition.is-info{background-color:#def0fc;border-color:#209cee}.admonition.is-info>.admonition-header{background-color:#209cee;color:#fff}.admonition.is-info>.admonition-body{color:rgba(0,0,0,0.7)}.admonition.is-success{background-color:#bdf4d1;border-color:#22c35b}.admonition.is-success>.admonition-header{background-color:#22c35b;color:#fff}.admonition.is-success>.admonition-body{color:rgba(0,0,0,0.7)}.admonition.is-warning{background-color:#fff3c5;border-color:#ffdd57}.admonition.is-warning>.admonition-header{background-color:#ffdd57;color:rgba(0,0,0,0.7)}.admonition.is-warning>.admonition-body{color:rgba(0,0,0,0.7)}.admonition.is-danger{background-color:#ffaba7;border-color:#da0b00}.admonition.is-danger>.admonition-header{background-color:#da0b00;color:#fff}.admonition.is-danger>.admonition-body{color:rgba(0,0,0,0.7)}.admonition.is-compat{background-color:#bdeff5;border-color:#1db5c9}.admonition.is-compat>.admonition-header{background-color:#1db5c9;color:#fff}.admonition.is-compat>.admonition-body{color:rgba(0,0,0,0.7)}.admonition-header{color:#fff;background-color:#363636;align-items:center;font-weight:700;justify-content:space-between;line-height:1.25;padding:0.5rem .75rem;position:relative}.admonition-header:before{font-family:"Font Awesome 6 Free";font-weight:900;margin-right:.75rem;content:"\f06a"}details.admonition.is-details>.admonition-header{list-style:none}details.admonition.is-details>.admonition-header:before{font-family:"Font Awesome 6 Free";font-weight:900;content:"\f055"}details.admonition.is-details[open]>.admonition-header:before{font-family:"Font Awesome 6 Free";font-weight:900;content:"\f056"}.admonition-body{color:#222;padding:0.5rem .75rem}.admonition-body pre{background-color:#f5f5f5}.admonition-body code{background-color:rgba(0,0,0,0.05)}.docstring{margin-bottom:1em;background-color:rgba(0,0,0,0);border:1px solid #dbdbdb;box-shadow:2px 2px 3px rgba(10,10,10,0.1);max-width:100%}.docstring>header{cursor:pointer;display:flex;flex-grow:1;align-items:stretch;padding:0.5rem .75rem;background-color:#f5f5f5;box-shadow:0 0.125em 0.25em rgba(10,10,10,0.1);box-shadow:none;border-bottom:1px solid #dbdbdb;overflow:auto}.docstring>header code{background-color:transparent}.docstring>header .docstring-article-toggle-button{min-width:1.1rem;padding:0.2rem 0.2rem 0.2rem 0}.docstring>header .docstring-binding{margin-right:0.3em}.docstring>header .docstring-category{margin-left:0.3em}.docstring>section{position:relative;padding:.75rem .75rem;border-bottom:1px solid #dbdbdb}.docstring>section:last-child{border-bottom:none}.docstring>section>a.docs-sourcelink{transition:opacity 0.3s;opacity:0;position:absolute;right:.375rem;bottom:.375rem}.docstring>section>a.docs-sourcelink:focus{opacity:1 !important}.docstring:hover>section>a.docs-sourcelink{opacity:0.2}.docstring:focus-within>section>a.docs-sourcelink{opacity:0.2}.docstring>section:hover a.docs-sourcelink{opacity:1}.documenter-example-output{background-color:#fff}.outdated-warning-overlay{position:fixed;top:0;left:0;right:0;box-shadow:0 0 10px rgba(0,0,0,0.3);z-index:999;background-color:#ffaba7;color:rgba(0,0,0,0.7);border-bottom:3px solid #da0b00;padding:10px 35px;text-align:center;font-size:15px}.outdated-warning-overlay .outdated-warning-closer{position:absolute;top:calc(50% - 10px);right:18px;cursor:pointer;width:12px}.outdated-warning-overlay a{color:#2e63b8}.outdated-warning-overlay a:hover{color:#363636}.content pre{border:1px solid #dbdbdb}.content code{font-weight:inherit}.content a code{color:#2e63b8}.content h1 code,.content h2 code,.content h3 code,.content h4 code,.content h5 code,.content h6 code{color:#222}.content table{display:block;width:initial;max-width:100%;overflow-x:auto}.content blockquote>ul:first-child,.content blockquote>ol:first-child,.content .admonition-body>ul:first-child,.content .admonition-body>ol:first-child{margin-top:0}pre,code{font-variant-ligatures:no-contextual}.breadcrumb a.is-disabled{cursor:default;pointer-events:none}.breadcrumb a.is-disabled,.breadcrumb a.is-disabled:hover{color:#222}.hljs{background:initial !important}.katex .katex-mathml{top:0;right:0}.katex-display,mjx-container,.MathJax_Display{margin:0.5em 0 !important}html{-moz-osx-font-smoothing:auto;-webkit-font-smoothing:auto}li.no-marker{list-style:none}#documenter .docs-main>article{overflow-wrap:break-word}#documenter .docs-main>article .math-container{overflow-x:auto;overflow-y:hidden}@media screen and (min-width: 1056px){#documenter .docs-main{max-width:52rem;margin-left:20rem;padding-right:1rem}}@media screen and (max-width: 1055px){#documenter .docs-main{width:100%}#documenter .docs-main>article{max-width:52rem;margin-left:auto;margin-right:auto;margin-bottom:1rem;padding:0 1rem}#documenter .docs-main>header,#documenter .docs-main>nav{max-width:100%;width:100%;margin:0}}#documenter .docs-main header.docs-navbar{background-color:#fff;border-bottom:1px solid #dbdbdb;z-index:2;min-height:4rem;margin-bottom:1rem;display:flex}#documenter .docs-main header.docs-navbar .breadcrumb{flex-grow:1;overflow-x:hidden}#documenter .docs-main header.docs-navbar .docs-sidebar-button{display:block;font-size:1.5rem;padding-bottom:0.1rem;margin-right:1rem}#documenter .docs-main header.docs-navbar .docs-right{display:flex;white-space:nowrap;gap:1rem;align-items:center}#documenter .docs-main header.docs-navbar .docs-right .docs-icon,#documenter .docs-main header.docs-navbar .docs-right .docs-label{display:inline-block}#documenter .docs-main header.docs-navbar .docs-right .docs-label{padding:0;margin-left:0.3em}@media screen and (max-width: 1055px){#documenter .docs-main header.docs-navbar .docs-right .docs-navbar-link{margin-left:0.4rem;margin-right:0.4rem}}#documenter .docs-main header.docs-navbar>*{margin:auto 0}@media screen and (max-width: 1055px){#documenter .docs-main header.docs-navbar{position:sticky;top:0;padding:0 1rem;transition-property:top, box-shadow;-webkit-transition-property:top, box-shadow;transition-duration:0.3s;-webkit-transition-duration:0.3s}#documenter .docs-main header.docs-navbar.headroom--not-top{box-shadow:.2rem 0rem .4rem #bbb;transition-duration:0.7s;-webkit-transition-duration:0.7s}#documenter .docs-main header.docs-navbar.headroom--unpinned.headroom--not-top.headroom--not-bottom{top:-4.5rem;transition-duration:0.7s;-webkit-transition-duration:0.7s}}#documenter .docs-main section.footnotes{border-top:1px solid #dbdbdb}#documenter .docs-main section.footnotes li .tag:first-child,#documenter .docs-main section.footnotes li .docstring>section>a.docs-sourcelink:first-child,#documenter .docs-main section.footnotes li .content kbd:first-child,.content #documenter .docs-main section.footnotes li kbd:first-child{margin-right:1em;margin-bottom:0.4em}#documenter .docs-main .docs-footer{display:flex;flex-wrap:wrap;margin-left:0;margin-right:0;border-top:1px solid #dbdbdb;padding-top:1rem;padding-bottom:1rem}@media screen and (max-width: 1055px){#documenter .docs-main .docs-footer{padding-left:1rem;padding-right:1rem}}#documenter .docs-main .docs-footer .docs-footer-nextpage,#documenter .docs-main .docs-footer .docs-footer-prevpage{flex-grow:1}#documenter .docs-main .docs-footer .docs-footer-nextpage{text-align:right}#documenter .docs-main .docs-footer .flexbox-break{flex-basis:100%;height:0}#documenter .docs-main .docs-footer .footer-message{font-size:0.8em;margin:0.5em auto 0 auto;text-align:center}#documenter .docs-sidebar{display:flex;flex-direction:column;color:#0a0a0a;background-color:#f5f5f5;border-right:1px solid #dbdbdb;padding:0;flex:0 0 18rem;z-index:5;font-size:1rem;position:fixed;left:-18rem;width:18rem;height:100%;transition:left 0.3s}#documenter .docs-sidebar.visible{left:0;box-shadow:.4rem 0rem .8rem #bbb}@media screen and (min-width: 1056px){#documenter .docs-sidebar.visible{box-shadow:none}}@media screen and (min-width: 1056px){#documenter .docs-sidebar{left:0;top:0}}#documenter .docs-sidebar .docs-logo{margin-top:1rem;padding:0 1rem}#documenter .docs-sidebar .docs-logo>img{max-height:6rem;margin:auto}#documenter .docs-sidebar .docs-package-name{flex-shrink:0;font-size:1.5rem;font-weight:700;text-align:center;white-space:nowrap;overflow:hidden;padding:0.5rem 0}#documenter .docs-sidebar .docs-package-name .docs-autofit{max-width:16.2rem}#documenter .docs-sidebar .docs-package-name a,#documenter .docs-sidebar .docs-package-name a:hover{color:#0a0a0a}#documenter .docs-sidebar .docs-version-selector{border-top:1px solid #dbdbdb;display:none;padding:0.5rem}#documenter .docs-sidebar .docs-version-selector.visible{display:flex}#documenter .docs-sidebar ul.docs-menu{flex-grow:1;user-select:none;border-top:1px solid #dbdbdb;padding-bottom:1.5rem}#documenter .docs-sidebar ul.docs-menu>li>.tocitem{font-weight:bold}#documenter .docs-sidebar ul.docs-menu>li li{font-size:.95rem;margin-left:1em;border-left:1px solid #dbdbdb}#documenter .docs-sidebar ul.docs-menu input.collapse-toggle{display:none}#documenter .docs-sidebar ul.docs-menu ul.collapsed{display:none}#documenter .docs-sidebar ul.docs-menu input:checked~ul.collapsed{display:block}#documenter .docs-sidebar ul.docs-menu label.tocitem{display:flex}#documenter .docs-sidebar ul.docs-menu label.tocitem .docs-label{flex-grow:2}#documenter .docs-sidebar ul.docs-menu label.tocitem .docs-chevron{display:inline-block;font-style:normal;font-variant:normal;text-rendering:auto;line-height:1;font-size:.75rem;margin-left:1rem;margin-top:auto;margin-bottom:auto}#documenter .docs-sidebar ul.docs-menu label.tocitem .docs-chevron::before{font-family:"Font Awesome 6 Free";font-weight:900;content:"\f054"}#documenter .docs-sidebar ul.docs-menu input:checked~label.tocitem .docs-chevron::before{content:"\f078"}#documenter .docs-sidebar ul.docs-menu .tocitem{display:block;padding:0.5rem 0.5rem}#documenter .docs-sidebar ul.docs-menu .tocitem,#documenter .docs-sidebar ul.docs-menu .tocitem:hover{color:#0a0a0a;background:#f5f5f5}#documenter .docs-sidebar ul.docs-menu a.tocitem:hover,#documenter .docs-sidebar ul.docs-menu label.tocitem:hover{color:#0a0a0a;background-color:#ebebeb}#documenter .docs-sidebar ul.docs-menu li.is-active{border-top:1px solid #dbdbdb;border-bottom:1px solid #dbdbdb;background-color:#fff}#documenter .docs-sidebar ul.docs-menu li.is-active .tocitem,#documenter .docs-sidebar ul.docs-menu li.is-active .tocitem:hover{background-color:#fff;color:#0a0a0a}#documenter .docs-sidebar ul.docs-menu li.is-active ul.internal .tocitem:hover{background-color:#ebebeb;color:#0a0a0a}#documenter .docs-sidebar ul.docs-menu>li.is-active:first-child{border-top:none}#documenter .docs-sidebar ul.docs-menu ul.internal{margin:0 0.5rem 0.5rem;border-top:1px solid #dbdbdb}#documenter .docs-sidebar ul.docs-menu ul.internal li{font-size:.85rem;border-left:none;margin-left:0;margin-top:0.5rem}#documenter .docs-sidebar ul.docs-menu ul.internal .tocitem{width:100%;padding:0}#documenter .docs-sidebar ul.docs-menu ul.internal .tocitem::before{content:"⚬";margin-right:0.4em}#documenter .docs-sidebar form.docs-search{margin:auto;margin-top:0.5rem;margin-bottom:0.5rem}#documenter .docs-sidebar form.docs-search>input{width:14.4rem}#documenter .docs-sidebar #documenter-search-query{color:#707070;width:14.4rem;box-shadow:inset 0 1px 2px rgba(10,10,10,0.1)}@media screen and (min-width: 1056px){#documenter .docs-sidebar ul.docs-menu{overflow-y:auto;-webkit-overflow-scroll:touch}#documenter .docs-sidebar ul.docs-menu::-webkit-scrollbar{width:.3rem;background:none}#documenter .docs-sidebar ul.docs-menu::-webkit-scrollbar-thumb{border-radius:5px 0px 0px 5px;background:#e0e0e0}#documenter .docs-sidebar ul.docs-menu::-webkit-scrollbar-thumb:hover{background:#ccc}}@media screen and (max-width: 1055px){#documenter .docs-sidebar{overflow-y:auto;-webkit-overflow-scroll:touch}#documenter .docs-sidebar::-webkit-scrollbar{width:.3rem;background:none}#documenter .docs-sidebar::-webkit-scrollbar-thumb{border-radius:5px 0px 0px 5px;background:#e0e0e0}#documenter .docs-sidebar::-webkit-scrollbar-thumb:hover{background:#ccc}}kbd.search-modal-key-hints{border-radius:0.25rem;border:1px solid rgba(0,0,0,0.6);box-shadow:0 2px 0 1px rgba(0,0,0,0.6);cursor:default;font-size:0.9rem;line-height:1.5;min-width:0.75rem;text-align:center;padding:0.1rem 0.3rem;position:relative;top:-1px}.search-min-width-50{min-width:50%}.search-min-height-100{min-height:100%}.search-modal-card-body{max-height:calc(100vh - 15rem)}.search-result-link{border-radius:0.7em;transition:all 300ms}.search-result-link:hover,.search-result-link:focus{background-color:rgba(0,128,128,0.1)}.search-result-link .property-search-result-badge,.search-result-link .search-filter{transition:all 300ms}.property-search-result-badge,.search-filter{padding:0.15em 0.5em;font-size:0.8em;font-style:italic;text-transform:none !important;line-height:1.5;color:#f5f5f5;background-color:rgba(51,65,85,0.501961);border-radius:0.6rem}.search-result-link:hover .property-search-result-badge,.search-result-link:hover .search-filter,.search-result-link:focus .property-search-result-badge,.search-result-link:focus .search-filter{color:#f1f5f9;background-color:#333}.search-filter{color:#333;background-color:#f5f5f5;transition:all 300ms}.search-filter:hover,.search-filter:focus{color:#333}.search-filter-selected{color:#f5f5f5;background-color:rgba(139,0,139,0.5)}.search-filter-selected:hover,.search-filter-selected:focus{color:#f5f5f5}.search-result-highlight{background-color:#ffdd57;color:black}.search-divider{border-bottom:1px solid #dbdbdb}.search-result-title{width:85%;color:#333}.search-result-code-title{font-size:0.875rem;font-family:"JuliaMono","SFMono-Regular","Menlo","Consolas","Liberation Mono","DejaVu Sans Mono",monospace}#search-modal .modal-card-body::-webkit-scrollbar,#search-modal .filter-tabs::-webkit-scrollbar{height:10px;width:10px;background-color:transparent}#search-modal .modal-card-body::-webkit-scrollbar-thumb,#search-modal .filter-tabs::-webkit-scrollbar-thumb{background-color:gray;border-radius:1rem}#search-modal .modal-card-body::-webkit-scrollbar-track,#search-modal .filter-tabs::-webkit-scrollbar-track{-webkit-box-shadow:inset 0 0 6px rgba(0,0,0,0.6);background-color:transparent}.w-100{width:100%}.gap-2{gap:0.5rem}.gap-4{gap:1rem}.gap-8{gap:2rem}.ansi span.sgr1{font-weight:bolder}.ansi span.sgr2{font-weight:lighter}.ansi span.sgr3{font-style:italic}.ansi span.sgr4{text-decoration:underline}.ansi span.sgr7{color:#fff;background-color:#222}.ansi span.sgr8{color:transparent}.ansi span.sgr8 span{color:transparent}.ansi span.sgr9{text-decoration:line-through}.ansi span.sgr30{color:#242424}.ansi span.sgr31{color:#a7201f}.ansi span.sgr32{color:#066f00}.ansi span.sgr33{color:#856b00}.ansi span.sgr34{color:#2149b0}.ansi span.sgr35{color:#7d4498}.ansi span.sgr36{color:#007989}.ansi span.sgr37{color:gray}.ansi span.sgr40{background-color:#242424}.ansi span.sgr41{background-color:#a7201f}.ansi span.sgr42{background-color:#066f00}.ansi span.sgr43{background-color:#856b00}.ansi span.sgr44{background-color:#2149b0}.ansi span.sgr45{background-color:#7d4498}.ansi span.sgr46{background-color:#007989}.ansi span.sgr47{background-color:gray}.ansi span.sgr90{color:#616161}.ansi span.sgr91{color:#cb3c33}.ansi span.sgr92{color:#0e8300}.ansi span.sgr93{color:#a98800}.ansi span.sgr94{color:#3c5dcd}.ansi span.sgr95{color:#9256af}.ansi span.sgr96{color:#008fa3}.ansi span.sgr97{color:#f5f5f5}.ansi span.sgr100{background-color:#616161}.ansi span.sgr101{background-color:#cb3c33}.ansi span.sgr102{background-color:#0e8300}.ansi span.sgr103{background-color:#a98800}.ansi span.sgr104{background-color:#3c5dcd}.ansi span.sgr105{background-color:#9256af}.ansi span.sgr106{background-color:#008fa3}.ansi span.sgr107{background-color:#f5f5f5}code.language-julia-repl>span.hljs-meta{color:#066f00;font-weight:bolder}/*! + Theme: Default + Description: Original highlight.js style + Author: (c) Ivan Sagalaev + Maintainer: @highlightjs/core-team + Website: https://highlightjs.org/ + License: see project LICENSE + Touched: 2021 +*/pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}.hljs{background:#F3F3F3;color:#444}.hljs-comment{color:#697070}.hljs-tag,.hljs-punctuation{color:#444a}.hljs-tag .hljs-name,.hljs-tag .hljs-attr{color:#444}.hljs-keyword,.hljs-attribute,.hljs-selector-tag,.hljs-meta .hljs-keyword,.hljs-doctag,.hljs-name{font-weight:bold}.hljs-type,.hljs-string,.hljs-number,.hljs-selector-id,.hljs-selector-class,.hljs-quote,.hljs-template-tag,.hljs-deletion{color:#880000}.hljs-title,.hljs-section{color:#880000;font-weight:bold}.hljs-regexp,.hljs-symbol,.hljs-variable,.hljs-template-variable,.hljs-link,.hljs-selector-attr,.hljs-operator,.hljs-selector-pseudo{color:#ab5656}.hljs-literal{color:#695}.hljs-built_in,.hljs-bullet,.hljs-code,.hljs-addition{color:#397300}.hljs-meta{color:#1f7199}.hljs-meta .hljs-string{color:#38a}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:bold}.gap-4{gap:1rem} diff --git a/v0.18.15/assets/themeswap.js b/v0.18.15/assets/themeswap.js new file mode 100644 index 0000000000..9f5eebe6aa --- /dev/null +++ b/v0.18.15/assets/themeswap.js @@ -0,0 +1,84 @@ +// Small function to quickly swap out themes. Gets put into the tag.. +function set_theme_from_local_storage() { + // Initialize the theme to null, which means default + var theme = null; + // If the browser supports the localstorage and is not disabled then try to get the + // documenter theme + if (window.localStorage != null) { + // Get the user-picked theme from localStorage. May be `null`, which means the default + // theme. + theme = window.localStorage.getItem("documenter-theme"); + } + // Check if the users preference is for dark color scheme + var darkPreference = + window.matchMedia("(prefers-color-scheme: dark)").matches === true; + // Initialize a few variables for the loop: + // + // - active: will contain the index of the theme that should be active. Note that there + // is no guarantee that localStorage contains sane values. If `active` stays `null` + // we either could not find the theme or it is the default (primary) theme anyway. + // Either way, we then need to stick to the primary theme. + // + // - disabled: style sheets that should be disabled (i.e. all the theme style sheets + // that are not the currently active theme) + var active = null; + var disabled = []; + var primaryLightTheme = null; + var primaryDarkTheme = null; + for (var i = 0; i < document.styleSheets.length; i++) { + var ss = document.styleSheets[i]; + // The tag of each style sheet is expected to have a data-theme-name attribute + // which must contain the name of the theme. The names in localStorage much match this. + var themename = ss.ownerNode.getAttribute("data-theme-name"); + // attribute not set => non-theme stylesheet => ignore + if (themename === null) continue; + // To distinguish the default (primary) theme, it needs to have the data-theme-primary + // attribute set. + if (ss.ownerNode.getAttribute("data-theme-primary") !== null) { + primaryLightTheme = themename; + } + // Check if the theme is primary dark theme so that we could store its name in darkTheme + if (ss.ownerNode.getAttribute("data-theme-primary-dark") !== null) { + primaryDarkTheme = themename; + } + // If we find a matching theme (and it's not the default), we'll set active to non-null + if (themename === theme) active = i; + // Store the style sheets of inactive themes so that we could disable them + if (themename !== theme) disabled.push(ss); + } + var activeTheme = null; + if (active !== null) { + // If we did find an active theme, we'll (1) add the theme--$(theme) class to + document.getElementsByTagName("html")[0].className = "theme--" + theme; + activeTheme = theme; + } else { + // If we did _not_ find an active theme, then we need to fall back to the primary theme + // which can either be dark or light, depending on the user's OS preference. + var activeTheme = darkPreference ? primaryDarkTheme : primaryLightTheme; + // In case it somehow happens that the relevant primary theme was not found in the + // preceding loop, we abort without doing anything. + if (activeTheme === null) { + console.error("Unable to determine primary theme."); + return; + } + // When switching to the primary light theme, then we must not have a class name + // for the tag. That's only for non-primary or the primary dark theme. + if (darkPreference) { + document.getElementsByTagName("html")[0].className = + "theme--" + activeTheme; + } else { + document.getElementsByTagName("html")[0].className = ""; + } + } + for (var i = 0; i < document.styleSheets.length; i++) { + var ss = document.styleSheets[i]; + // The tag of each style sheet is expected to have a data-theme-name attribute + // which must contain the name of the theme. The names in localStorage much match this. + var themename = ss.ownerNode.getAttribute("data-theme-name"); + // attribute not set => non-theme stylesheet => ignore + if (themename === null) continue; + // we'll disable all the stylesheets, except for the active one + ss.disabled = !(themename == activeTheme); + } +} +set_theme_from_local_storage(); diff --git a/v0.18.15/assets/warner.js b/v0.18.15/assets/warner.js new file mode 100644 index 0000000000..3f6f5d0083 --- /dev/null +++ b/v0.18.15/assets/warner.js @@ -0,0 +1,52 @@ +function maybeAddWarning() { + // DOCUMENTER_NEWEST is defined in versions.js, DOCUMENTER_CURRENT_VERSION and DOCUMENTER_STABLE + // in siteinfo.js. + // If either of these are undefined something went horribly wrong, so we abort. + if ( + window.DOCUMENTER_NEWEST === undefined || + window.DOCUMENTER_CURRENT_VERSION === undefined || + window.DOCUMENTER_STABLE === undefined + ) { + return; + } + + // Current version is not a version number, so we can't tell if it's the newest version. Abort. + if (!/v(\d+\.)*\d+/.test(window.DOCUMENTER_CURRENT_VERSION)) { + return; + } + + // Current version is newest version, so no need to add a warning. + if (window.DOCUMENTER_NEWEST === window.DOCUMENTER_CURRENT_VERSION) { + return; + } + + // Add a noindex meta tag (unless one exists) so that search engines don't index this version of the docs. + if (document.body.querySelector('meta[name="robots"]') === null) { + const meta = document.createElement("meta"); + meta.name = "robots"; + meta.content = "noindex"; + + document.getElementsByTagName("head")[0].appendChild(meta); + } + + const div = document.createElement("div"); + div.classList.add("outdated-warning-overlay"); + const closer = document.createElement("button"); + closer.classList.add("outdated-warning-closer", "delete"); + closer.addEventListener("click", function () { + document.body.removeChild(div); + }); + const href = window.documenterBaseURL + "/../" + window.DOCUMENTER_STABLE; + div.innerHTML = + 'This documentation is not for the latest stable release, but for either the development version or an older release.
Click here to go to the documentation for the latest stable release.'; + div.appendChild(closer); + document.body.appendChild(div); +} + +if (document.readyState === "loading") { + document.addEventListener("DOMContentLoaded", maybeAddWarning); +} else { + maybeAddWarning(); +} diff --git a/v0.18.15/assets/youtube.css b/v0.18.15/assets/youtube.css new file mode 100644 index 0000000000..bf93bab32b --- /dev/null +++ b/v0.18.15/assets/youtube.css @@ -0,0 +1,17 @@ +.video-container { + position: relative; + padding-bottom: 56.25%; + padding-top: 0; + height: 0; + overflow: hidden; +} + +.video-container iframe, +.video-container object, +.video-container embed { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; +} diff --git a/v0.18.15/development/client_libraries/index.html b/v0.18.15/development/client_libraries/index.html new file mode 100644 index 0000000000..cc744e9ce7 --- /dev/null +++ b/v0.18.15/development/client_libraries/index.html @@ -0,0 +1,2 @@ + +Client Libraries · metal-stack
diff --git a/v0.18.15/development/contributing/index.html b/v0.18.15/development/contributing/index.html new file mode 100644 index 0000000000..dcb489f7b7 --- /dev/null +++ b/v0.18.15/development/contributing/index.html @@ -0,0 +1,2 @@ + +Contributing · metal-stack

Contributing

This document describes the way we want to contribute code to the projects of metal-stack, which are hosted on github.com/metal-stack.

The document is meant to be understood as a general guideline for contributions, but not as burden to be placed on a developer. Use your best judgment when contributing code. Try to be as clean and precise as possible when writing code and try to make your code as maintainable and understandable as possible for other people.

Even if it should go without saying, we live an open culture of discussion, in which everybody is welcome to participate. We treat every contribution with respect and objectiveness with the general aim to write software of quality.

If you want, feel free to propose changes to this document in a pull request.

How Can I Contribute?

Open a Github issue in the project you would like to contribute. Within the issue, your idea can be discussed. It is also possible to directly create a pull request when the set of changes is relatively small.

Pull Requests

The process described here has several goals:

  • Maintain quality
  • Enable a sustainable system to review contributions
  • Enable documented and reproducible addition of contributions
  1. Create a meaningful issue describing the WHY? of your contribution
  2. Create a repository fork within the context of that issue.
  3. Create a Draft Pull Request to the master branch of the target repository.
  4. Develop, document and test your contribution (try not to solve more than one issue in a single pull request)
  5. Ask for merging your contribution by removing the draft marker
  6. If code owners are defined, try to assign the request to a code owner

General Objectives

This section contains language-agnostic topics that all metal-stack projects are trying to follow.

Code Ownership

The code base is owned by the entire team and every member is allowed to contribute changes to any of the projects. This is considered as collective code ownership[1].

As a matter of fact, there are persons in a project, which already have experience with the sources. These are defined directly in the repository's CODEOWNERS file. If you want to merge changes into the master branch, it is advisable to include code owners into the proecess of discussion and merging.

Microservices

One major ambition of metal-stack is to follow the idea of microservices. This way, we want to achieve that we can

  • adapt to changes faster than with monolithic architectures,
  • be free of restrictions due to certain choices of technology,
  • leverage powerful traits of cloud infrastructures (e.g. high-scalability, high-availability, ...).

Programming Languages

We are generally open to write code in any language that fits best to the function of the software. However, we encourage golang to be the main language of metal-stack as we think that it makes development faster when not establishing too many different languages in our architecture. Reason for this is that we are striving for consistent behavior of the microservices, similar to what has been described for the Twelve-Factor App (see 12 Factor). We help enforcing unified behavior by allowing a small layer of shared code for every programming language. We will refer to this shared code as "libraries" for the rest of this document.

Artifacts

Artifacts are always produced by a CI process (Github Actions).

Docker images are published on the Github Container Registry of the metal-stack organization.

Binary artifacts or OS images can be uploaded to images.metal-stack.io if necessary.

When building Docker images, please consider our build tool docker-make or the specific docker-make action respectively.

APIs

We are currently making use of Swagger when we exposing traditional REST APIs for end-users. This helps us with being technology-agnostic as we can generate clients in almost any language using go-swagger. Swagger additionally simplifies the documentation of our APIs.

Most APIs though are not required to be user-facing but are of technical nature. These are preferred to be implemented using grpc.

Versioning

Artifacts are versioned by tagging the respective repository with a tag starting with the letter v. After the letter, there stands a valid semantic version.

Documentation

In order to make it easier for others to understand a project, we document general information and usage instructions in a README.md in any project.

In addition to that, we document a microservice in the docs repository. The documentation should contain the reasoning why this service exists and why it was being implemented the way it was being implemented. The aim of this procedure is to reduce the time for contributors to comprehend architectural decisions that were made during the process of writing the software and to clarify the general purpose of this service in the entire context of the software.

Guidelines

This chapter describes general guidelines on how to develop and contribute code for a certain programming language.

Golang

Development follows the official guide to:

Development Decisions

  • Dependency Management by using Go modules
  • Build and Test Automation by using GNU Make.
  • End-user APIs should consider using go-swagger and Go-Restful Technical APIs should consider using grpc

Libraries

metal-stack maintains several libraries that you should utilize in your project in order unify common behavior. Some of these projects are:

Error Handling with Generated Swagger Clients

From the server-side you should ensure that you are returning the common error json struct in case of an error as defined in the metal-lib/httperrors. Ensure you are using go-restful >= v2.9.1 and go-restful-openapi >= v0.13.1 (allows default responses with error codes other than 200).

Documentation

We want to share knowledge and keep things simple. If things cannot kept simple we want enable everybody to understand them by:

  • Document in short sentences[4].
  • Do not explain the HOW (this is already documented by your code and documenting the obvious is considered a defect).
  • Explain the WHY. Add a "to" in your documentation line to force yourself to explain the reasonning (e.g. "<THE WHAT> to <THE TO>").

Python

Development follows the official guide to:

  • Style Guide for Python Code (PEP 8)[5]
    • The use of an IDE like PyCharm helps to write compliant code easily
  • Consider setuptools for packaging
  • If you want to add a Python microservice to the mix, consider pyinstaller on Alpine to achieve small image sizes
diff --git a/v0.18.15/development/proposals/MEP1/Distributed-API-Working.png b/v0.18.15/development/proposals/MEP1/Distributed-API-Working.png new file mode 100644 index 0000000000000000000000000000000000000000..899e223d25919d8ec5a2c2cacd2099f8731ff1ee GIT binary patch literal 53600 zcmeFZ2T;>r_cw@$3U)z7RKP+JK_HYQfb^w6fB)Pfwd&)icobx&7hUsBY2lk%a z%f!TVKuc52fQgBP%EZJR$GRK5ljyUCWnyAGKvXv)y8Al1xH&NKOR8@F#V;Z5Oz4god=JIGE~!84SiRsRI7ealw;(!EawA+!`(=1pZR? z@Njc5b+ARd5TWss2vJEm^cA$Gk**HEgev&k%?0NGexV%fa0KWp-gp}i@JrR%i{S1; zatB{S$cT!IO3Fw{iy~zH`2>9BfB(LrjiZg1%YRu0qSMF0%iD#3-zF0#Au25j+a}0? zXydf~E*$Tu1=n>$Xc8UGWF)ZmUNQ*f?J-0@4~OkB_6|NSc3@2jeo1w}VS5)FCodcD zY~n6|If#SV!XzYga0G;fy|yVuP0G|75C;uMnE2?}d3sB!>xtU{l2s%O)iEw)A5A<) z2PS(~6eAV5gQAC6fUJ9oL=ukJb$GPg-z->|PaAlOUrXk$k-Vm>4 zgc0|l_<)(nc$6O)W-dWAG%}!&^$1e>WF*B`5~WJk#()ppu%^bQhAMVsJ3l`uGee@S zxtX)Gqcn!7qCtR5!%2oFp3=r@%BHFo9>%VQC>?WOG}^@pMxi(%O#Eb|%}q36o=&cg z>bhQj>R25#(NRVfCV{drl_X;|!1N~esu-9L#X{Lt+}*^^&c_`oC4qE=I~eI|`d9!i zYe+cY>@j#r54emj(aZ~@=4Y<&0Mtpv#X;B4#*ZK)>5Iqdqs^2tw)T*A7&+VONt4vv zwGAx1ZShz?6rSR01Bbh7>S$8%YFhTTdd4cgx}IuU-iEfGb`UFd@UE^7es)*{S=t

*#5l_~}a_O?}C}WCN6`r#iyi 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

aHDI zU`V}O^e7;?N>C{W+nYMj`#(5ADpN$v(1Ps~b~3P!d#Xp!)xDM%>sSgNDs~zE2fKAx zg*CpSFCBt9s#l)C&!NsK%1;AX;PK9~nzcNa`?qTdQ>y?*;I5vMEKrAP4!fWPt&44= z@HY)4RNZVDu+lICTH_q|KToKztn^AZ&^gb`5wQH>vg3!2MBC)CX*|fs&gha?b-SQ! zY^#>ENXYhXKXW*%h2wD#IWr@9e149=&z_ zLq`(7^vN&xMVxhC4XW-SRE8jzk-o|~%jy1N1Jo-fECNKtOmB$KtHpW>RQ_(Pz7112 z1JyRqpvhb42#}QI89P$obGhYy$`J05^w3)qOuC2%sL{^Ig>hz0-W};w5hOaxX%U-( zh-$LfPba$okoI9UTuuH&^+tn;4ye-2>{L_4KD(To3Va%G##<7?OnDf#a2kOtAkp)E zy`>UoneXg)oE}T3w%uveQZKp&J3)L>wsimA3>vd}cTSc=L8W zio6lk1$qO;FZ%UWWQZx6;`B3sr#Ryzu_Z*5u; z|K3K%GgEFj`-iLJHiH|;K^@G+UYiA=_HmgttovvPYlcLJyaYr&s#Cy$)=l1Dd5$1T z3FqlENdzSM{B|Rp*mx~F0ImSK73o0Tc32Bd)B{Te_5STh-T-s&lG5_^_}Zxadj(zM zXJGh;>#`TTAB7sn4ApCtTA~&~x|7VlSBi`kAwORP^-7sUudAGb3fnWfx=rlvpGD8e zf)sRERQlwoF6n@qVn7ur)8nkUrhq;aqoltIQvDKvQxZrv#a=vX&g+~^0ecRv`-sS6{F!Jq>r~8%Q2u$0GdoMpm7YVBQ zy3*sVD#BScW{ND`P*sCHu-T5ZHS6;mi%T?!Lae5R9m968 z)+~pNYNOx*xai**>uG7A9%+R+iC#M^!Hdl67EnhAQa4ec!6i~*9^w}wS2V9q`wOa~% z2a}R}%FySt=>cLRFFlO~w*Knlqh<(Ohw-3}Jy}FA zRYcJY=#S+n3up;&=4hqfc#H?c%m}*xBV}2Vn(MM5R$@hCZZBtQ^JJlkDL+g*BAr2I_c zumRK|Dl}>-kBld(!Z>v%DL(^Taoz*yoxg$fidD2Y1t+7XA&Gh&s6H?(s${#RfY`G9 ztd=-s0IrW(oh&QF>LT1{fsR0pq+(Du4)Avrsyt)J_qO5Wb$Hzx&J#GiVh1z9@&GN) zwgKv+IO!@Fgf=9tU^yrOccyna`Fg*9b-=XYDW&N$4(rv|tcUQ9B%N~JAdLm-!Je#^ zN=wUhlDru@UFOcPFF@DjZy(H*nr4|HRO-Cyc724K*zhmvR%B@gCq~m&UQcZL;(alI zbRAQ1h>+ZUdH?M)#3W`lR_ReZ=2i=4D+ax97D8RY%i4$Cy^3HK47y7ImHdUHziTy4R#0BG|n-n?K0k;a=sN>=!iJ)mq++^0)%g})vIAXOPL9;_wex=^# z=vr~6g3AULCm+*7Pn2i(1u6{^0a~I#_^YIa8)XF&L24ZU&6BR5K(d4y%*o;gVe3mi zL}#2k=ZWd4-l?q>pdVP|d^T~%oG-%uY0ghZyQhXguAW#N3l=!=XV;*aZXGI{&Dr7X zJf0P5D2lOqwsK$u%hKrFsDKbS2Af7A5KnDyBs`A znk1NCZ1c*`#>PIPKo~tMh&GVe z;Pzti*?C6C!0B%1hgb1A?QokumE1=Kf(07Ux3*C-(eY^Ncw-kC`E<(R;bv3^VW)a=-hgEai~k7eNF+-zqpZF?JsG(Zq|D=EzXh4lZr z!0lg0`A@L+Cs_L}bM_~-_9sjG|NSiO@OyWAGjnqZFI^u2DnP$+@boO{o*cGhRVq81 z{a*ql3Oyk50ZsWX2c*CW=k<*pa6tAd9ajQ`)PM41X#vTB`}r%t3L`te z{?M_*I{pWp_RoX=8Sy`+@*9c$&*B8z&Hs}U|7TbEvycBdfc~`*<x%n3R~+4~t`w73jo z_Y!U?F|YUqcF*u@VpJ`-iH`aHBKwZ($*w%mX}^1x?;QNU{#T288NGT`eJ%&#D@_6Z OQ@^ZpDgWZNd;b?C)@Qc> literal 0 HcmV?d00001 diff --git a/v0.18.15/development/proposals/MEP1/Distributed-API.png b/v0.18.15/development/proposals/MEP1/Distributed-API.png new file mode 100644 index 0000000000000000000000000000000000000000..688c7c2e1bf9d75f570cddf3a92fe9d4b8ee0072 GIT binary patch literal 49935 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 literal 0 HcmV?d00001 diff --git a/v0.18.15/development/proposals/MEP1/Distributed-Deployment.png b/v0.18.15/development/proposals/MEP1/Distributed-Deployment.png new file mode 100644 index 0000000000000000000000000000000000000000..8bba51b8d0495141d02b68797ae1b51d466f45c6 GIT binary patch literal 34547 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 literal 0 HcmV?d00001 diff --git a/v0.18.15/development/proposals/MEP1/Distributed.drawio b/v0.18.15/development/proposals/MEP1/Distributed.drawio new file mode 100644 index 0000000000..f7c6fe7922 --- /dev/null +++ b/v0.18.15/development/proposals/MEP1/Distributed.drawio @@ -0,0 +1 @@ +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 \ No newline at end of file diff --git a/v0.18.15/development/proposals/MEP1/Distributed.png b/v0.18.15/development/proposals/MEP1/Distributed.png new file mode 100644 index 0000000000000000000000000000000000000000..d96ca216b2fe23de6ecacca6544f5b0d0ef86778 GIT binary patch literal 31547 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 hmmM2l{(kv|4&bHO44$rjF6*2UngC#G9S8sb literal 0 HcmV?d00001 diff --git a/v0.18.15/development/proposals/MEP1/README/index.html b/v0.18.15/development/proposals/MEP1/README/index.html new file mode 100644 index 0000000000..c231cf53df --- /dev/null +++ b/v0.18.15/development/proposals/MEP1/README/index.html @@ -0,0 +1,2 @@ + +Distributed Metal Control Plane · metal-stack diff --git a/v0.18.15/development/proposals/MEP10/README/index.html b/v0.18.15/development/proposals/MEP10/README/index.html new file mode 100644 index 0000000000..bfbda931d6 --- /dev/null +++ b/v0.18.15/development/proposals/MEP10/README/index.html @@ -0,0 +1,87 @@ + +SONiC Support · metal-stack

SONiC Support

As writing this proposal, metal-stack only supports Cumulus on Broadcom ASICs. Unfortunately, after the acquisition of Cumulus Networks by Nvidia, Broadcom decided to cut its relationship with Cumulus, and therefore Cumulus 4.2 is the last version that supports Broadcom ASICs. Since trashing the existing hardware is not a solution, adding support for a different network operating system is necessary.

One of the remaining big players is SONiC, which Microsoft created to scale the network of Azure. It's an open-source project and is now part of the Linux Foundation.

For a general introduction to SONiC, please follow the Architecture official documentation.

ConfigDB

On a cold start, the content of /etc/sonic/config_db.json will be loaded into the Redis database CONFIG_DB, and both contain the switch's configuration except the BGP unnumbered configuration, which still has to be configured directly by the frr configuration files. The SONiC community is working to remove this exception, but no release date is known.

BGP Configuration

Frr runs inside a container, and a shell script configured it on the container startup. For BGP unnumbered, we must set the configuration variable docker_routing_config_mode to split to prevent SONiC from overwriting our configuration files created by metal-core. But by using the split mode, the integrated configuration mode of frr is deactivated, and we have to write our BGP configuration to the daemon-specific files bgp.conf, staticd.conf, and zebra.conf instead to frr.conf.

elif [ "$CONFIG_TYPE" == "split" ]; then
+    echo "no service integrated-vtysh-config" > /etc/frr/vtysh.conf
+    rm -f /etc/frr/frr.conf

Reference: docker-init

Adding support for the integrated configuration mode, we must at least adjust the startup shell script and the supervisor configuration:

{% if DEVICE_METADATA.localhost.docker_routing_config_mode is defined and DEVICE_METADATA.localhost.docker_routing_config_mode == "unified" %}
+[program:vtysh_b]
+command=/usr/bin/vtysh -b

Reference: supervisord.conf

Non-BGP Configuration

For the Non-BGP configuration we have to write it into the Redis database directly or via one of the following interfaces:

  • config replace <file>
  • the Mgmt Framework
  • the SONiC restapi

Directly writing into the Redis database isn't a stable interface, and we must determine the create, delete, and update operations on our own. The last point is also valid for the Mgmt Framework and the SONiC restapi. Furthermore, the Mgmt Framework doesn't start anymore for several months, and a potential fix is still not merged. And the SONiC restapi isn't enabled by default, and we must build and maintain our own SONiC images.

Using config replace would reduce the complexity in the metal-core codebase because we don't have to determine the actual changes between the running and the desired configuration. The approach's drawbacks are using a version of SONiC that contains the PR Yang support for VXLAN, and we must provide the whole new startup configuration to prevent unwanted deconfiguration.

Configure Loopback interface and activate VXLAN

{
+ "LOOPBACK_INTERFACE": {
+  "Loopback0": {},
+  "Loopback0|<loopback address/32>": {}
+ },
+ "VXLAN_TUNNEL": {
+  "vtep": {
+   "src_ip": "<loopback address>"
+  }
+ }
+}

Configure MTU

{
+ "PORT": {
+  "Ethernet0": {
+   "mtu": "9000"
+  }
+ }
+}

Configure PXE Vlan

{
+ "VLAN": {
+  "Vlan4000": {
+   "vlanid": "4000"
+  }
+ },
+ "VLAN_INTERFACE": {
+  "Vlan4000": {},
+  "Vlan4000|<metal core cidr>": {}
+ },
+ "VLAN_MEMBER": {
+  "Vlan4000|<interface>": {
+   "tagging_mode": "untagged"
+  }
+ },
+ "VXLAN_TUNNEL_MAP": {
+  "vtep|map_104000_Vlan4000": {
+   "vlan": "Vlan4000",
+   "vni": "104000"
+  }
+ }
+}

Configure VRF

{
+ "INTERFACE": {
+  "Ethernet0": {
+   "vrf_name": "vrf104001"
+  }
+ },
+ "VLAN": {
+  "Vlan4001": {
+   "vlanid": "4001"
+  }
+ },
+ "VLAN_INTERFACE": {
+  "Vlan4001": {
+   "vrf_name": "vrf104001"
+  }
+ },
+ "VRF": {
+  "vrf104001": {
+   "vni": "104001"
+  }
+ },
+ "VXLAN_TUNNEL_MAP": {
+  "vtep|map_104001_Vlan4001": {
+   "vlan": "Vlan4001",
+   "vni": "104001"
+  }
+ }
+}

DHCP Relay

The DHCP relay container only starts if DEVICE_METADATA.localhost.type is equal to ToRRouter.

LLDP

SONiC always uses the local port subtype for LLDP and sets it to some freely configurable alias field of the interface.

# Get the port alias. If None or empty string, use port name instead
+port_alias = port_table_dict.get("alias")
+if not port_alias:
+    self.log_info("Unable to retrieve port alias for port '{}'. Using port name instead.".format(port_name))
+    port_alias = port_name
+
+lldpcli_cmd = "lldpcli configure ports {0} lldp portidsubtype local {1}".format(port_name, port_alias)

Reference: lldpmgr

Mgmt Interface

The mgmt interface is eth0. To configure a static IP address and activate the Mgmt VRF, use:

{
+ "MGMT_INTERFACE": {
+  "eth0|<mgmt cidr>": {
+   "gwaddr": "<mgmt gateway>"
+  }
+ },
+ "MGMT_VRF_CONFIG": {
+  "vrf_global": {
+   "mgmtVrfEnabled": "true"
+  }
+ }
+}

IP forwarding is deactivated on eth0, and no IP Masquerade is configured.

diff --git a/v0.18.15/development/proposals/MEP11/README/index.html b/v0.18.15/development/proposals/MEP11/README/index.html new file mode 100644 index 0000000000..6bad6d565f --- /dev/null +++ b/v0.18.15/development/proposals/MEP11/README/index.html @@ -0,0 +1,2 @@ + +Auditing of metal-stack resources · metal-stack

Auditing of metal-stack resources

Currently no logs of the ownership of resources like machines, networks, ips and volumes are generated or kept. Though due to legal requirements data centers are required to keep track of this ownership over time to prevent liability issues when opening the platform for external users.

In this proposal we want to introduce a flexible and low-maintenance approach for auditing on top of Meilisearch.

Overview

In general our auditing logs will be collected by a request interceptor or middleware. Every request and response will be processed and eventually logged to Meilisearch. Meilisearch will be configured to regularly create chunks of the auditing logs. These finished chunks will be backed up to a S3 compatible storage with a read-only option enabled.

Of course sensitive data like session keys or passwords will be redacted before logging. We want to track relevant requests and responses. If auditing the request fails, the request itself will be aborted and will not be processed further. The requests and responses that will be audited will be annotated with a correlation id.

Transferring the meilisearch auditing data chunks to the S3 compatible storage will be done by a sidecar cronjob that is executed periodically. To avoid data manipulation the S3 compatible storage will be configured to be read-only.

Whitelisting

To reduce the amount of unnecessary logs we want to introduce a whitelist of resources and operations on those that should be logged. Other requests will be passed directly to the next middleware or web service without any further processing.

As we are only interested in mutating endpoints, we ignore all GET requests. The whitelist includes all POST, PUT, PATCH and DELETE endpoints of the HTTP middleware except for the following (non-manipulating) route suffixes:

  • /find
  • /notify
  • /try and /match
  • /capacity
  • /from-hardware

Regarding GRPC audit trails, they are not so interesting because only internal clients are using this API. However, we can log the trails of the Boot service, which can be interesting to revise the machine lifecycle.

Chunking in Meilisearch

We want our data to be chunked in Meilisearch. To accomplish this, we rotate the index identifier on a scheduled basis. The index identifiers will be derived from the current date and time.

To keep things simple, we only support hourly, daily and monthly rotation. The eventually prefixed index names will only include relevant parts of date and time like 2021-01, 2021-01-01 or 2021-01-01_13.

The metal-api will only write to the current index and switches to the new index on rotation. The metal-api will never read or update data in any indices.

Moving chunks to S3 compatible storage

As Meilisearch will be filled with data over time, we want to move completed chunks to a S3 compatible storage. This will be done by a sidecar cronjob that is executed periodically. Note that the periods of the index rotation and the cronjob execution don't have to match.

When the backup process gets started, it initiates a Meilisearch dump of the whole database across all indices. Once the returned task is finished, the dump must be copied from a Meilisearch volume to the S3 compatible storage. After a successful copy, the dump can be deleted.

Now we want to remove all indices from Meilisearch, except the most recent one. For this, we get all indices, sort them and delete each index except the most recent one to avoid data loss.

For the actual implementation, we can build upon backup-restore-sidecar. But due to the index rotation and the fact, that older indices need to be deleted, this probably does not fit into the mentioned sidecar.

S3 compatible storage

The dumps of chunks should automatically deleted after a certain amount of time, once we are either no longer allowed or required to keep them. The default retention time will be 6 months. Ideally already uploaded chunks should be read-only to prevent data manipulation.

A candidate for the S3 compatible storage is Google Cloud Storage, which allows to configure automatic expiration of objects through a lifecycle rule.

Affected components

  • metal-api grpc server needs an auditing interceptor
  • metal-api web server needs an auditing filter chain / middleware
  • metal-api needs new command line arguments to configure the auditing
  • mini-lab needs a Meilisearch instance
  • mini-lab may need a local S3 compatible storage
  • we need a sidecar to implement the backup to S3 compatible storage
  • Consider auditing of volume allocations and freeings outside of metal-stack

Alternatives considered

Instead of using Meilisearch we investigated using an immutable database like immudb. But immudb does not support chunking of data and due to its immutable nature, we will never be able to free up space of expired data. Even if we are legally allowed or required to delete data, we will not be able to do so with immudb.

In another variant of the Meilisearch approach the metal-api would also be responsible for copying chunks to the S3 compatible storage and deleting old indices. But separating the concerns allows completely different implementations for every deployment stage.

diff --git a/v0.18.15/development/proposals/MEP12/README/index.html b/v0.18.15/development/proposals/MEP12/README/index.html new file mode 100644 index 0000000000..15418ffef6 --- /dev/null +++ b/v0.18.15/development/proposals/MEP12/README/index.html @@ -0,0 +1,7 @@ + +Rack Spreading · metal-stack

Rack Spreading

Currently, when creating a machine through the metal-api, the machine is placed randomly inside a partition. This algorithm does not consider spreading machines across different racks and different chassis. This may lead to the situation that a group of machines (that for example form a cluster) can end up being placed in the same rack and the same chassis.

Spreading a group of machines across racks can enhance availability for scenarios like a rack loosing power or a chassis meltdown.

So, instead of just randomly deciding the placement of a machine candidate, we want to propose a placement strategy that attempts to spread machine candidates across the racks inside a partition.

Furthermore a followup improvement to guarantee that machines are really spread across multiple racks, even if multiple machines are ordered in parallel, was implemented with PR490.

Placement Strategy

Machines in the project are spread across all available racks evenly within a partition (best effort). For this, an additional request to the datastore has to be made in order to find allocated machines within the project in the partition.

The algorithm will then figure out the least occupied racks and elect a machine candidate randomly from those racks.

The user can optionally pass placement tags which will be considered for spreading the machines as well (this will for example allow spreading by a cluster id tag inside the same project).

API

// service/v1/machine.go
+
+type MachineAllocation struct {
+    // existing fields are omitted for readability
+    PlacementTags []string `json:"placement_tags" description:"by default machines are spread across the racks inside a partition for every project. if placement tags are provided, the machine candidate has an additional anti-affinity to other machines having the same tags"`
+}
diff --git a/v0.18.15/development/proposals/MEP12/partitioning-1.svg b/v0.18.15/development/proposals/MEP12/partitioning-1.svg new file mode 100644 index 0000000000..ff9274fbe0 --- /dev/null +++ b/v0.18.15/development/proposals/MEP12/partitioning-1.svg @@ -0,0 +1 @@ +
Partition A
Partition A
c1-xlarge-x86
c1-xlarge-x86
c1-xlarge-x86
c1-xlarge-x86
partition-a-rack-02
partition-a-rack-02
Partition C
Partition C
Partition B
Partition B
c1-xlarge-x86
c1-xlarge-x86
c1-xlarge-x86
c1-xlarge-x86
n1-medium-x86
n1-medium-x86
n1-medium-x86
n1-medium-x86
partition-b-rack-01
partition-b-rack-01
c1-xlarge-x86
c1-xlarge-x86
c1-xlarge-x86
c1-xlarge-x86
n1-medium-x86
n1-medium-x86
n1-medium-x86
n1-medium-x86
partition-a-rack-01
partition-a-rack-01
c1-xlarge-x86
c1-xlarge-x86
c1-xlarge-x86
c1-xlarge-x86
partition-c-rack-01
partition-c-rack-01
10.88.0.0/14
10.88.0.0/14
10.92.0.0/14
10.92.0.0/14
10.96.0.0/14
10.96.0.0/14
storage cluster
storage clus...
storage cluster
storage clus...
storage cluster
storage clus...
Text is not SVG - cannot display
\ No newline at end of file diff --git a/v0.18.15/development/proposals/MEP12/partitioning-2.svg b/v0.18.15/development/proposals/MEP12/partitioning-2.svg new file mode 100644 index 0000000000..e05b59ed77 --- /dev/null +++ b/v0.18.15/development/proposals/MEP12/partitioning-2.svg @@ -0,0 +1 @@ +
Partition A
Partition A
c1-xlarge-x86
c1-xlarge-x86
c1-xlarge-x86
c1-xlarge-x86
partition-a-rack-02
partition-a-rack-02
Partition C
Partition C
Partition B
Partition B
c1-xlarge-x86
c1-xlarge-x86
c1-xlarge-x86
c1-xlarge-x86
n1-medium-x86
n1-medium-x86
n1-medium-x86
n1-medium-x86
partition-b-rack-01
partition-b-rack-01
c1-xlarge-x86
c1-xlarge-x86
c1-xlarge-x86
c1-xlarge-x86
n1-medium-x86
n1-medium-x86
n1-medium-x86
n1-medium-x86
partition-a-rack-01
partition-a-rack-01
c1-xlarge-x86
c1-xlarge-x86
c1-xlarge-x86
c1-xlarge-x86
partition-c-rack-01
partition-c-rack-01
10.88.0.0/14
10.88.0.0/14
10.92.0.0/14
10.92.0.0/14
10.96.0.0/14
10.96.0.0/14
storage cluster
storage clus...
storage cluster
storage clus...
storage cluster
storage clus...
rand(machine(
  partition,
  size
))
rand(machine(...
Partition A
c1-xlarge-x86
Partition A...
Text is not SVG - cannot display
\ No newline at end of file diff --git a/v0.18.15/development/proposals/MEP12/partitioning-3.svg b/v0.18.15/development/proposals/MEP12/partitioning-3.svg new file mode 100644 index 0000000000..bd62468688 --- /dev/null +++ b/v0.18.15/development/proposals/MEP12/partitioning-3.svg @@ -0,0 +1 @@ +
Partition A
Partition A
c1-xlarge-x86
c1-xlarge-x86
c1-xlarge-x86
c1-xlarge-x86
partition-a-rack-02
partition-a-rack-02
c1-xlarge-x86
c1-xlarge-x86
c1-xlarge-x86
c1-xlarge-x86
n1-medium-x86
n1-medium-x86
n1-medium-x86
n1-medium-x86
partition-a-rack-01
partition-a-rack-01
c1-xlarge-x86
c1-xlarge-x86
c1-xlarge-x86
c1-xlarge-x86
partition-a-rack-04
partition-a-rack-04
c1-xlarge-x86
c1-xlarge-x86
c1-xlarge-x86
c1-xlarge-x86
n1-medium-x86
n1-medium-x86
n1-medium-x86
n1-medium-x86
partition-a-rack-03
partition-a-rack-03
rand(machine(
  partition,
  size
))
rand(machine(...
Partition A
c1-xlarge-x86
Partition A...
10.96.0.0/14
10.96.0.0/14
storage cluster
storage clus...
Text is not SVG - cannot display
\ No newline at end of file diff --git a/v0.18.15/development/proposals/MEP12/partitioning.drawio.svg b/v0.18.15/development/proposals/MEP12/partitioning.drawio.svg new file mode 100644 index 0000000000..62a32cded3 --- /dev/null +++ b/v0.18.15/development/proposals/MEP12/partitioning.drawio.svg @@ -0,0 +1,486 @@ + + + + + + + + + + +
+
+
+ Partition A +
+
+
+
+ + Partition A + +
+
+ + + + +
+
+
+ + c1-xlarge-x86 + +
+
+
+
+ + c1-xlarge-x86 + +
+
+ + + + + + + + + + + +
+
+
+ + c1-xlarge-x86 + +
+
+
+
+ + c1-xlarge-x86 + +
+
+ + + +
+
+
+ + partition-a-rack-02 + +
+
+
+
+ + partition-a-rack-02 + +
+
+ + + + + +
+
+
+ + c1-xlarge-x86 + +
+
+
+
+ + c1-xlarge-x86 + +
+
+ + + + + + + + + + + + + + + + + +
+
+
+ + c1-xlarge-x86 + +
+
+
+
+ + c1-xlarge-x86 + +
+
+ + + +
+
+
+ + n1-medium-x86 + +
+
+
+
+ + n1-medium-x86 + +
+
+ + + +
+
+
+ + n1-medium-x86 + +
+
+
+
+ + n1-medium-x86 + +
+
+ + + +
+
+
+ + partition-a-rack-01 + +
+
+
+
+ + partition-a-rack-01 + +
+
+ + + + +
+
+
+ + c1-xlarge-x86 + +
+
+
+
+ + c1-xlarge-x86 + +
+
+ + + + + + + + + + + +
+
+
+ + c1-xlarge-x86 + +
+
+
+
+ + c1-xlarge-x86 + +
+
+ + + +
+
+
+ + partition-a-rack-04 + +
+
+
+
+ + partition-a-rack-04 + +
+
+ + + + + +
+
+
+ + c1-xlarge-x86 + +
+
+
+
+ + c1-xlarge-x86 + +
+
+ + + + + + + + + + + + + + + + + +
+
+
+ + c1-xlarge-x86 + +
+
+
+
+ + c1-xlarge-x86 + +
+
+ + + +
+
+
+ + n1-medium-x86 + +
+
+
+
+ + n1-medium-x86 + +
+
+ + + +
+
+
+ + n1-medium-x86 + +
+
+
+
+ + n1-medium-x86 + +
+
+ + + +
+
+
+ + partition-a-rack-03 + +
+
+
+
+ + partition-a-rack-03 + +
+
+ + + + + + +
+
+
+
+ + + rand + + + + ( + + + + machine + + + + ( + +
+
+ + partition, + +
+
+ + size + +
+
+ + )) + +
+
+
+
+
+ + rand(machine(... + +
+
+ + + + +
+
+
+ + Partition A +
+ c1-xlarge-x86 +
+
+
+
+
+
+ + Partition A... + +
+
+ + + + + + + + + +
+
+
+ 10.96.0.0/14 +
+
+
+
+ + 10.96.0.0/14 + +
+
+ + + + + +
+
+
+ + storage cluster + +
+
+
+
+ + storage clus... + +
+
+
+ + + + + Text is not SVG - cannot display + + + +
diff --git a/v0.18.15/development/proposals/MEP12/partitioning/index.html b/v0.18.15/development/proposals/MEP12/partitioning/index.html new file mode 100644 index 0000000000..9b5bfef1d2 --- /dev/null +++ b/v0.18.15/development/proposals/MEP12/partitioning/index.html @@ -0,0 +1,2 @@ + +Multi-Partition-Layout · metal-stack

marp: true theme: metal-stack paginate: true footer: Gerrit Schwerthelm – x-cellent technologies GmbH — metal-stack Training backgroundImage: url("https://metal-stack.io/images/shape/banner.png") –- <!– _class: cover lead –>

h:200px


<!– _class: cover lead –>

Multi-Partition-Layout


<!– _class: lead _backgroundColor: #1f1f1f _backgroundImage: _footer: "" –> bg contain


<!– _class: lead _backgroundColor: #1f1f1f _backgroundImage: _footer: "" –> bg contain


<style>section { font-size: 30px; }</style>

Multi-Partition-Layout Properties

  • Fully independent locations with own storage and own node networks
  • Clusters can only be created independent in every location
    • Failover mechanism for deployed applications requires duplicated deployments, which can serve independently
    • Failover through BGP
  • If cluster nodes are spread across partitions (not implemented yet), nodes will not be able to reach each other
    • Would require an overlay network for inter-node-communication

<!– _class: cover lead –>

Single-Partition-Layout


<!– _class: lead _backgroundColor: #1f1f1f _backgroundImage: _footer: "" –> bg contain


<style>section { font-size: 30px; }</style>

Single-Partition-Layout Properties

  • Multiple groups of racks at multiple locations but connected to same CLOS topology
  • All racks can connect to the same storage network
  • Nodes in private networks can communicate
  • When creating a cluster, nodes will be randomly spread across the racks
    • Possible improvement of this situation, see MEP-12: Rack Spreading

MEP-12: Rack Spreading

  • Instead of selecting a machine from a machine pool randomly
  • Get all existing machines in the same project and count to which rack they belong
  • Place machine on the rack with the least amount of machines already allocated
  • Best effort only
diff --git a/v0.18.15/development/proposals/MEP14/README/index.html b/v0.18.15/development/proposals/MEP14/README/index.html new file mode 100644 index 0000000000..09d165336c --- /dev/null +++ b/v0.18.15/development/proposals/MEP14/README/index.html @@ -0,0 +1,2 @@ + +Independence from external sources · metal-stack

Independence from external sources

In certain situations some customers may need to operate and create machines without making use of external services like DNS or NTP through the internet. To make this possible, all metal-stack components reaching external services need to be configurable with custom endpoints.

So far, the following components have been identified as requiring changes:

  • pixiecore
  • metal-hammer
  • metal-images

More components are likely to be added to the list during processing.

pixiecore

A NTP server endpoint need to be configured on the pixiecore. This can be achieved by providing it through environment variables on start up.

metal-hammer

If using a self-deployed NTP server, also the metal-hammer need to be configured with it. For backward compatibility, default values from pool.ntp.org and time.google.com are used.

metal-images

Configurations for the metal-images are different for machines and firewalls.

The implementation of this MEP will make metal-stack possible to create and maintain machines without requiring an internet connection.

diff --git a/v0.18.15/development/proposals/MEP2/README/index.html b/v0.18.15/development/proposals/MEP2/README/index.html new file mode 100644 index 0000000000..394430a192 --- /dev/null +++ b/v0.18.15/development/proposals/MEP2/README/index.html @@ -0,0 +1,2 @@ + +Two Factor Authentication · metal-stack diff --git a/v0.18.15/development/proposals/MEP3/README/index.html b/v0.18.15/development/proposals/MEP3/README/index.html new file mode 100644 index 0000000000..6c4edf0269 --- /dev/null +++ b/v0.18.15/development/proposals/MEP3/README/index.html @@ -0,0 +1,2 @@ + +Machine Re-Installation · metal-stack

Machine Re-Installation

In the current metal-api only machine installations are possible, performing a machine upgrade is only possible by creating a new machine and delete the old one. This has the drawback that in case a lot of data is stored on the local disks, a full restore of the original data must be performed.

To prevent this, we will introduce a new metal-api endpoint to reinstall the machine with a new image, without actually deleting the data stored on the additional hard disks.

Storage is a difficult task to get right and reliable. A short analysis of our different storage requirements lead to 3 different scenarios.

  • Storage for the etcd pvs in the seed cluster of every partition. This is the most important storage in our setup because these etcd pods serve as configuration backend for all customer kubernetes clusters. If they fail, the cluster is down. However gardener deploys a backup and restore sidecar into the etcd pod of every customer kubernetes control plane, and if this sidecar detects a corrupt or missing etcd database file(s) it starts automatic restore from the configured backup location. This will take some minutes. If for example a node dies, and gardener creates a new node instead, the csi-lvm created pv is not present on that node. Kubernetes will not schedule the missing etcd pod on this node because it has a local PV configured and is therefore tainted to run only on that node. To let kubernetes create that pod anyhow, someone has to either remove the taint, or delete the pod. If this is done, the pod starts and the restore of the etcd data can start as well. You can see this is a bit too complicated and will take the customer cluster down for a while (not measured yet but in the range of 5-10 minutes).
  • Storage in customer clusters. This was not promised in 2020. We have a intermediate solution with the provisioning of csi-lvm by default into all customer clusters. Albeit this is only local storage and will get deleted if a node dies.
  • S3 Storage. We have two possibilities to cope with storage:
    • In place update of the OS with a daemonset This will be fast and simple, but might fail because the packages being installed are broken right now, or a filesystem gets full, or any other failure you can think of during a os update. Another drawback is that metal-api does not reflect the updated os image.
    • metal-api get a machine reinstall endpoint With this approach we leverage from existing and already proven mechanisms. Reinstall must keep all data except the sata-dom. Gardener currently is not able to do an update with this approach because it can only do rolling updates. Therefore a additional osupdatestrategy has to be implemented for metal and other providers in gardener to be able to leverage the metal reinstall on the same machineID approach.

If reinstall is implemented, we should focus on the same technology for all scenarios and put ceph via rook.io into the kubernetes clusters as additional StorageClass. It has to be checked whether to use the raw disk or a PV as the underlay block device where ceph stores its data.

API and behavior

The API will get an new endpoint "reinstall" this endpoint takes two arguments:

  • machineID
  • image

No other aspects of the machine can be modified during the re-installation. All data stored in the existing allocation will be preserved, only the image will be modified. Once this endpoint was called, the machine will get a reboot signal with the boot order set to PXE instead of HDD and the network interfaces on the leaf are set to PXE as well. Then the normal installation process starts:

  • unchanged: PXE boot with metal-hammer
  • changed: metal-hammer first checks with the machineID in the metal-api (through metal-core) if there is already a allocation present
  • changed: if a allocation is present and the allocation has set reinstall: true, wipe disk is only executed for the root disk, all other disks are untouched.
  • unchanged: the specified image is downloaded and burned, /install.sh is executed
  • unchanged: successful installation is reported back, network is set the the vrf, boot order is set to HDD.
  • unchanged: distribution kernel is booted via kexec

We can see that the allocation requires one additional parameter: reinstall and metal-hammer must check for already existing allocation at an earlier stage.

Components which requires modifications (first guess):

  • metal-hammer:
    • check for allocation present earlier
    • evaluation of reinstall flag set
    • wipe of disks depends on that flag
    • Bonus: move configuration of disk layout and primary disk detection algorithm (PDDA) from metal-hammer into metal-api. metal-api MUST reject reinstallation if the disk found by PDDA does not have the /etc/metal directory!
  • metal-core:
    • probably nothing
  • metal-api:
    • new endpoint /machine/reinstall
    • add Reinstall bool to data model of allocation
    • make sure to reset Reinstall after reinstallation to prevent endless reinstallation loop
  • metalctl:
    • implement reinstall
  • metal-go:
    • implement reinstall
  • gardener (longterm):
    • add the OSUpgradeStrategy reinstall
diff --git a/v0.18.15/development/proposals/MEP4/README/index.html b/v0.18.15/development/proposals/MEP4/README/index.html new file mode 100644 index 0000000000..000f2c387c --- /dev/null +++ b/v0.18.15/development/proposals/MEP4/README/index.html @@ -0,0 +1,14 @@ + +Multi-Tenancy for the metal-api · metal-stack

Multi-Tenancy for the metal-api

Info

This document is work in progress.

In the past we decided to treat the metal-api as a "low-level API", i.e. the API does not specifically deal with projects and tenants. A user with editor access can for example assign machines to every project he desires, he can see all the machines available and can control them. We tried to keep the metal-api code base as small as possible and we added resource scoping to a "higher-level APIs". From there, a user would be able to only see his own clusters and IP addresses.

As time passed metal-stack has become an open-source project and people are willing to adopt. Adopters who want to put their own technologies on top of the metal-stack infrastructure don't have those "higher-level APIs" that we implemented closed-source for our user base. So, external adopters most likely need to implement resource scoping on their own.

Introducing multi-tenancy to the metal-api is a serious chance of making our product better and more successful as it opens the door for:

  • Becoming a "fully-featured" API
  • Narrowing down attack surfaces and possibility of unintended resource modification produced by bugs or human errors
  • Discouraging people to implement their own scoping layers in front of the metal-stack
  • Gaining performance through resource scopes
  • Letting untrusted / third-parties work with the API

Table of Contents

Requirements

These are some general requirements / higher objectives that MEP-4 has to fulfill.

  • Should be able to run with mini-lab without requiring to setup complex auth backends (dex, LDAP, keycloak, ...)
    • Simple to start with, more complex options for production setups
  • Should utilize auth mechanisms that we have already in place to best possible degree
  • Fine-grained access permissions (every endpoint maps to a permission)
  • Tenant scoping (disallow resource access to resources of other tenants)
  • Project scoping (disallow resource access to resources of other projects)
  • Access tokens in self-service for technical user access

Implementation

We gathered a lot of knowledge while implementing a multi-tenancy-capable backend for metalstack.cloud. The goal is now to use the same technology and adopt that to the metal-api, this includes:

  • gRPC in combination with connectrpc
  • OPA for making auth decisions
  • REST HTTP only for OIDC login flows

API Definitions

The API definitions should be located on a separate Github repository separate from the server implementation. The proposed repository location is: https://github.com/metal-stack/api.

This repository contains the proto3 specification of the exposed metal-stack api. This includes the messages, simple validations, services and the access permission to these services. The input parameters for the authorization in the backend are generated from the proto3 annotations.

Client implementations for the most relevant languages (go, python) are generated automatically.

This api is divided into end-user and admin access at the top level. The proposed APIs are:

  • api.v2: For end-user facing services
  • admin.v2: For operators and controllers which need access to unscoped entities

The methods of the API can have different role scopes (and can be narrowed down further with fine-grained method permissions):

  • tenant: Tenant-scoped methods, e.g. project creation (tenant needs to be provided in the request payload)
    • Available roles: VIEWER, EDITOR, OWNER
  • project: Project-scoped methods, e.g. machine creation (tenant needs to be provided in the request payload)
    • Available roles: VIEWER, EDITOR, OWNER
  • admin Admin-scoped methods, e.g. unscoped tenant list or switch register
    • Available roles: VIEWER, EDITOR

And has methods with different visibility scopes:

  • self: Methods that only the logged in user can access, e.g. show permissions with the presented token
  • public: Methods that do not require any specific authorization
  • private: Methods that are not exposed

API

The API server implements the services defined in the API and validates access to a method using OPA with the JWT tokens passed in the requests. The server is implemented using the connectrpc.com framework.

The API server implements the login flow through OIDC. After successful authentication, the API server derives user permissions from the OIDC provider and issues a new JWT token which is passed on to the user. The tokens including the permissions are stored in a redis compatible backend.

With these tokens, users can create Access Tokens for CI/CD or other use cases.

JWT Tokens can be revoked by admins and the user itself.

API Server

Is put into a new github repo which implements the services defined in the api repository. It opens a https endpoints where the grpc (via connectrpc.com) and oidc servives are exposed.

Migration of the Consumers

To allow consumers to migrate to the v2 API gradually, both apis, the new and the old, are deployed in parallel. In the control-plane both apis are deployed side-by-side behind the ingress. api.example.com is forwarded to metal-api and metal.example.com is forwarded to the new api-server.

The api-server will talk to the existing metal-api during the process of migration services away to the new grpc api.

The migration process can be done in the following manner:

for each resource in the metal-api:

  • create a new proto3 based definition in the api repo.
  • implement at least a small wrapper service in the api-server which asks the metal-api for this resource an maps the response back the caller in the grpc format.
  • identify all consumers of this resource and replace them to use the grpc instead of the rest api
  • move the business logic incl. the backend calls to ipam, metal-db, masterdata-ap, nsq for this resource from the metal-api to the api-server

We will try to migrate the rethinkdb backend implementation to a generic approach during this effort.

There are a lot of consumers of metal-api, which need to be migrated:

  • ansible
  • firewall-controller
  • firewall-controller-manager
  • gardener-extension-auth
  • gardener-extension-provider-metal
    • Do not point the secret bindings to a the shared provider secret in the seed anymore. Instead, use individual provider-secret containing project-scoped API access tokens in the Gardener project namespaces.
  • machine-controller-manager-provider-metal
  • metal-ccm
  • metal-console
  • metal-bmc
  • metal-core
  • metal-hammer
  • metal-image-cache-sync
  • metal-images
  • metal-metrics-exporter
  • metal-networker
  • metalctl
  • pixie

User Scenarios

This section gathers a collection of workflows from the perspective of a user that we want to provide with the implementation of this proposal.

Machine Creation

A regular user wants to create a machine resource.

Requirements: Project was created, permissions are present

  • The user can see networks that were provided by the admin.

    $ metalctl network ls
    +ID                                      NAME                     PROJECT     PARTITION       NAT     SHARED  PREFIXES         IPS
    +internet                                Internet Network                                     true    false   212.34.83.0/27    ●
    +tenant-super-network-fra-equ01          Project Super Network                fra-equ01       false   false   10.128.0.0/14     ●
    +underlay-fra-equ01                      Underlay Network                     fra-equ01       false   false   10.0.0.0/16       ●
  • The user has to set the project scope first or provide --project flags for all commands.

    $ metalctl project set 793bb6cd-8b46-479d-9209-0fedca428fe1
    +You are now acting on project 793bb6cd-8b46-479d-9209-0fedca428fe1.
  • The user can create the child network required for machine allocation.

    $ metalctl network allocate --partition fra-equ01 --name test
  • Now, the user sees his own child network.

    $ metalctl network ls
    +ID                                      NAME                    PROJECT                                 PARTITION       NAT     SHARED  PREFIXES         IPS
    +internet                                Internet Network                                                                true    false   212.34.83.0/27    ●
    +tenant-super-network-fra-equ01          Project Super Network                                           fra-equ01       false   false   10.128.0.0/14     ●
    +└─╴08b9114b-ec47-4697-b402-a11421788dc6 test                    793bb6cd-8b46-479d-9209-0fedca428fe1    fra-equ01       false   false   10.128.64.0/22    ●
    +underlay-fra-equ01                      Underlay Network                                                fra-equ01       false   false   10.0.0.0/16       ●
  • The user does not see any machines yet.

    $ metalctl machine ls
  • The user can create a machine.

    $ metalctl machine create --networks internet,08b9114b-ec47-4697-b402-a11421788dc6 --name test --hostname test --image ubuntu-20.04 --partition fra-equ01 --size c1-xlarge-x86`
  • The machine will now be provisioned.

    $ metalctl machine ls
    +ID                                     LAST EVENT      WHEN    AGE      HOSTNAME   PROJECT                                 SIZE            IMAGE                   PARTITION
    +00000000-0000-0000-0000-ac1f6b7befb2   Phoned Home     20s     50d 4h   test       793bb6cd-8b46-479d-9209-0fedca428fe1    c1-xlarge-x86   Ubuntu 20.04 20210415   fra-equ01
Warning

A user cannot list all allocated machines for all projects. The user must always switch project context first and can only view the machines inside this project. Only admins can see all machines at once.

Scopes for Resources

The admins / operators of the metal-stack should be able to provide global resources that users are able to use along with their own resources. In particular, users can view and use global resources, but they are not allowed to create, modify or delete them.

Info

When a project ID field is empty on a resource, the resource is considered global.

Where possible, users should be capable of creating their own resource entities.

ResourceUserGlobal
File System Layoutyesyes
Firewallyes
Firmwareyes
OS Imageyes
Machineyes
Network (Base)yes
Network (Children)yes
IPyes
Partitionyes
Projectyes
Project Tokenyes
Sizeyes
Switch
Tenantyes
Info

Example: A user can make use of the file system layouts provided by the admins, but can also create own layouts. Same applies for images. As soon as a user creates own resources, the user takes over the responsibility for the machine provisioning to succeed.

diff --git a/v0.18.15/development/proposals/MEP5/README/index.html b/v0.18.15/development/proposals/MEP5/README/index.html new file mode 100644 index 0000000000..d07f54ec21 --- /dev/null +++ b/v0.18.15/development/proposals/MEP5/README/index.html @@ -0,0 +1,2 @@ + +Shared Networks · metal-stack

Shared Networks

Why are shared networks needed

For special purpose machines that serve shared services with performance critical workloads to all machines of a partition (like persistent storage) it would be good to have kind of a "shared network" that is easily accessible. They do not necessarily need another firewall. This would avoid having two firewalls in the datapath between a machine in a private network and the machines of a shared service.

Constraints that need to hold

  • a shared network is usable from all machines that have a firewall in front, that uses it
  • a shared network is only usable within a single partition (currently we are constrained in bandwidth and have no routing of 10.0.0.0/8 addresses btw. partitions and failure domain should be the partition but this constraint might get lifted in the future)
  • networks may be marked as shared after network allocation (but there should be no way back from shared to unshared)
  • neither machines nor firewalls may have multiple private, unshared networks configured
  • machines must have a single primary network configured
    • this might be a shared network
    • OR a plain, unshared private network
  • firewalls may participate in multiple shared networks
  • machines can be allocated with a primary network using auto IP allocation or with noauto and a specific IP

Should shared networks be private

Alternative 1: If we implemented shared networks by extending functions around plain, private networks we would not have to manage another CIDR (mini point) and it would be possible to create a k8s cluster with a private network, mark the network as shared and produce shared services from this k8s cluster.

Alternative 2: If shared networks are implemented as first class networks we could customize the VRF and also accomplish an other goal of our roadmap: being able to create machines directly in an external network.

Together with @majst01 and @Gerrit91 we decided to continue to implement Alternative 1.

Firewalls accessing a shared network

Firewalls that access shared networks need to:

  • hide the private network behind an ip address of the shared network if the shared network was configured with nat=true.
  • import the prefixes of the shared VRF to the private VRF and import the prefixes of the private VRF to the shared VRF so that the communication between the two is working in both directions. As long as no nat=true was set on the shared VRF, the original machine ips are visible in both communication directions.

Setup with shared networks and single consumer

Simple Setup

Setup with single shared network and multiple consumers

Advanced Setup

Getting internet access

Machines contained in a shared network can access the internet with different scenarios:

  • if they have an own firewall: this is internet accessibility, as common (check whether all traffic gets routed through it!)
  • if they don't have an own firewall, an external HTTP proxy is needed that has an endpoint exposed as Service Type NodePort
diff --git a/v0.18.15/development/proposals/MEP5/shared.drawio b/v0.18.15/development/proposals/MEP5/shared.drawio new file mode 100644 index 0000000000..aa7af0455c --- /dev/null +++ b/v0.18.15/development/proposals/MEP5/shared.drawio @@ -0,0 +1,121 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/v0.18.15/development/proposals/MEP5/shared.png b/v0.18.15/development/proposals/MEP5/shared.png new file mode 100644 index 0000000000000000000000000000000000000000..b0b47f0324545ec159effc46f153a9b5b0c2450b GIT binary patch literal 49790 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 literal 0 HcmV?d00001 diff --git a/v0.18.15/development/proposals/MEP5/shared_advanced.drawio b/v0.18.15/development/proposals/MEP5/shared_advanced.drawio new file mode 100644 index 0000000000..6f96eca09f --- /dev/null +++ b/v0.18.15/development/proposals/MEP5/shared_advanced.drawio @@ -0,0 +1,187 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/v0.18.15/development/proposals/MEP5/shared_advanced.png b/v0.18.15/development/proposals/MEP5/shared_advanced.png new file mode 100644 index 0000000000000000000000000000000000000000..da9899157d390e82e60b50211bfff24637e8dfb2 GIT binary patch literal 90372 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[(x6a8Kj(S={1$nwWsT3GSX5e>C`kg1B{EQ?t7`4_{+2Uo3u zy4P$;zs<9gMi3(?Nd6d06y?y*`7agAe|_T7E^$|K*|KyGLu`sa9dTqgZ{hM;!q7hi z!Dc1mC-u-J*-Mtz_}GNJ*ZDfX=++!5o#$`ZBFvG#+0~hs$#pFJ;AnCw`uE7cFm&l) zK(&75>&@L8=!fksh3|e7@D~|7y}%S9w&ZIlFZ3(^Kfgq!p@hM;RBHae|Hk7G*ayhS zFTVBAPK`vO=9;nnAy|FXjsw1ove`WVOolIdq=IVHi;$acK& zz8CTz?{h_=VIg71iP#N5L+{^BAtCmon0^SH;%!i%rvNQ{(7_+RQ(c%}z3m2;QCMfv z(hrMsJvsZLL(+fw;x?q8RY_r(33<_ai3QKukvD%;12Bddkxe`K%KK>6LiXEF-qp~` zs1_`FlQhKuy#z{qICda_z}bpvc#K(z77!ossw1ZfDyMvm-B8lT;PAM$|4H_u3=-sS zD$eZ#5XE-bWNfv8V@sCL1Kbzzh8aR7ispUZ2!xJHfQ#=+^{e2Qjlbdwx^4am7>Cg{=2ifM@I}ovoNlYp5z+moF z0#M1{3(9zOd+2b+2!r9I2iVcFE1QlKZQetAn@F_PaUJD1TEu5aof9ZCsL7~0wa(be z`Y-MQv)dVVKjA5v05L!v`7{Sm7Hp(1&#Z8ZN=X?IfFzVeOd^;O7r7wzTbe#OSSiRf zH`)$xt0bP)>7-Fr@fMKs7%gJey$mLvkpYQNYrN^zbL+PTRnKvOs>=(DRGxu6$@!1? zps8kSIxhgML7NoCifu-8;T8@EggB(UqT>j_BG9YA#j+_d@@x|1QMe_8v4En5AfNDs zzdTdfBt{1S3eXK|fcHtGS)A@$Y&E>e0tf~+YMD46)1L7a>hIkqC1L@DdwtGVrx^mm zo8E%x8Ma|{(8*E?YMLQ}`*0g*M83?T73^gR=%Ydi4qwwHI2FzfHlYbMUoAEvV=^Uu zZ^4rT|3-;GNU|Gn%n;GURpr@mKF&HDYC7RB#?m4dCidY)3juOp&0~UK_#rUnw(D2> z%QjwIP+#8ltH#F{YT@3z3^3v4;Z0v&zA$4|egP@GM10W8>q_`E!5G@~u5vw8KWlzw zNL&>*aOI2-B>v(9Tyj%N+(<`!;qKkq5xjHlyLHYwUxkp#$vwik z1GoE&;e))x?ssN)5a=LfI6TxtBq7Qq>AHEhk!BRj+5Yd|{flkwmC#>}*n$2p3wQ4Y z^Y9tYPE z5dZ3e-=gucHgWM4!H~8p zz-RQk=8UtzN_Ee};uYiO9h-2aYA}a%qgWJN_&J+@GA=>&;R@AqTeFMtl!&xk56@?i zgf3A`+XKdk*#ufctR2Cbl*JSNYX=?z5Q(Ul#b%8W@s%&dTVgI*A_zAG(R8;*iibl& ziS7}ek=8@wFVeDHLD#bx;J=Bu&?hrm6m~^z@_Z4k-6^V-6w(ws1@f)&*%=w(|9hZw zK?0ESlAeuZOA*2*KS1%-mPr&~h9?hCyae!mnP2w*CRapGAC!L%BwSGKU$Rs>O^Ma8 zc1Hp5h4{hE#L+Pl@v_<$Sld(wS%MA^*30#t|b3 zoY~N2K)--;kPBrK8z5FKcI8~|uYD-{Yaf28&?~>*SpA=QLn)SL8jlih8iw`*YVr2_ zZ>^QbFZVV=oMV=!HY;zQ?|QXR@hor z#M_?}>lnu0&|&IZ4`g^+I{J3DP%I;EqC}D8I{)YxM9xvxCD+Bf6M5V3!Fi|`Zvn|i z7jrNb7}w(QC!0z?Q4#^7?7csojt0Q>9NypD)x~<5%~d_yU7NsgQlQx#7(X9EHbkxJ z%u{Rp-I#1CzAWc-Ecwwkfw?=^k_Pq}lx{Ur+{uo}HWl@KrHb-0wo@aDRLaNPZ{3jq z4Hr5?gFa9M7R&!ZNu^kB@DlWQfMe+-Y)|_JsvFu*-joi3;WIb4LH9rSNM`II!E*U} zCNS%&369Yyw3Gyr&1JR9PVw5{ZM}At>n$k&OI*iT<>ojgaD3zuo>{^;K?I0`Iz?8W zzM`YiEXIUQtw@;!P>1v{U)I%j^j&u>d8hyuKRH4ut}U++vO zR2Y3Dv*2?&J*?|!i^nzz38AmcItbu)*O9yKB=v z;-&wmFq$`j`q@pkGDWSAZk!8M1j~M){mg(o`O4ACE?87V0_5W<&DGze1Vc~Ksko1L zIJ@c&A3#1IV6Y)uy9K-fk_n~>05LP0dxLm5;mkpAWB}kSjrQ3!8R_{61-76>kvbAA zQF|XGPgV<**Yf)=AfW|Y+QTuZCNMQD)U!@vJ?L^cW>y0rC3*9paSe*L2zJ_Igtzb9 z*l>2%Cgrfqqh;(bD`ikp_YE)!^Ho)L&(6e7yEEd{<{Gd&V$UE=@>W~&r-yC^*ZW=M zw=Z9(M7cFUr#0z4Lu)pr4{-4G%EBEP4&7~gahQ@*g4!<6nRs0Xb=JS)HHbxf+5)J6 zh?P0D*;Eh6DqChwLYT_LT2qRYs2)#+${Itah0#T;V;(*NQabcMu287jVqWl~{ejw1 z$@y)a{wB~2;Ytb|yh?r>wZWDmgj*W|bsm`w(@ve$7s68@Z{~}4pz=&(uhg(nXry~F z8zG#`V=#w9mn+q;Iv^6tG?oq#W`ET4qgu^}a>@OUWj)*oukDkB?}=-{(u%{s0WdIDevDZg_(Z9pn)c8-`iT z_C#YIMSKzaE^R$OD4dJ6#y9hYzgrbT9u0rXH0s?r&np9_ICEI&+>j{JUdMYn&@o!~ zY!2AHO96%$MUyOomS-EP3G3NNZDtk5?e^MCQBr%|bK@A!et((F!LchM9ah1!7^9^a zi>nMF8K93Y7F9#Py(G1qjb$*yr>xiS?)uo-aAuIKr2nA@9&-`*3%}y%k?i+l?vtE* z>!8yHOTuC~jw8sbYI;MtJ`z3XBqb#CXx|Z?4{cXhBZ=$+geijB1ysq0yXq)-6ZG!& zyFMA1cF|H;9P{a@&dJi6X*D7Ug&xDu9CF)8XN9ec=SSo)?+a-N!74O)hWjzjp^n$f zg(aI!Q5#2MUl^IL%qV54P{37^(`pd*2#R6DP03G@JdrYMkT#kSV*F@&O zrxf#B2r1GFb7f6Nk=4|XqQe?W`ST7%zSD=pc^qRKBR8*%ym z(uYoeNb%pk=KrXoL=(LV2A(#gX!V%T={ynb$}4>*L4zHgYnr%_nq-k=pBN_Jm&kL! z!;wj1t(m$~>zvh%;=uQ}do{l?X(d0Px0SH9tT?}GXoe?q`>F*kmsNK~%!0wiVfhhJ z%(Lv1jZW?hdwq7rHLR-$UWKw~Az7QU7IA?aBBQAh^Y)Jx*-WZk6#AMK=xF63xC=NR61qV#4IG^n1SD`&tUx4G*h3?N%7EEMlY z_FAR3mk?((Vx=a;4KkkjQ;$@c$I0{g@)pyGcfBsv#UI8s&?8`u%F2C^)Cvc;oeeLd zCXF$A%g5}w<>QJDG>KmKPszxAta>Z=4oT1vyN4^8F0Yq;KvK$RHb1;5e@QS~KsmlW zO!hMQQ_wE>_!mdLdWtqg6-z?Md?d2xuzb_%cHLW3EBAUNmq@#2%q+!1`9)eg0*l#I z&MC(ah>x@c#mwy2h>qC!N&~y5(={VPm>0n_x?KSIO9EUd5Z*Mk z65i{x{MKx~PV8ekLi5OPBnczW$`aJ}z>}2NGLxieJgsnHCBObMhBIB){T|Cjkd~Q$ z(~=KTrQE}7wS5i@2F%D!jinKrEEq9Q&VzYYKM^!y#r5#Wgu>?2y%f>rabogFVjp#+ z?TB}(x$4pLP}!KZL1MTE!J=V6BvEWq{>Sx4+BL&W-N#!}3#rA2;wrf0DHl>DibMIx zk_r$1uPat2H6QU*`nqHUp3i4pT?}T0gn>Ttf3b@PG@2YxgXh+Wrj>nrr2yA_<#nS_ zXz)a}v{X^Pc-}t~+Tiv#0_t$CBvFyA+CxOzFS!^zq5u!94Mo z(~6k-z`f0h0(wlAd9N8cF?h!S!JZVWB(M8AP&~!fq%&sdU_h@@37XE7XHHdL$RDEb z9P}Iav_u|bV;?GG%)x+4C1hVMLz)U7vI1>_YrX{hY#Z4i)2_?PW-m(hV%{sxf1_rO zbdv%bj89u#lIpN#zS~;08>Ds(%&@$)WNhw*SdWV6$z5R%jLcMe|D}2IG*#l;b8qUm zkWWx&5p;+B32{AV_qw&6fOvW=v&zeBcQ>aSbVJ?WtHk#b%0kJ{%+B|JvsXMIAnRUC zJoL_?=2j?|I8?YP5wl8YmP01`B4~_2$p#S3r#BDMZdjmB{?sF_YJZ>iq~|CE?>1Jr z=6MZ45q>p+D*;lAY0UQ^6O6??EYIJ*vK}IOgBno}5v#hD{N`>PL0|KaLP7IoHk9QFZaXz3EI5QyEoUB;6Li=sHo7^o@|^Bp#P1ByeEb@QMA}w0 z2xy`^z&N0yQB~w<(6xE>qLk_%|f>3*Jrz@i(wElsE28 zBL8n3@$9LTv7nIv;=r3VpPv7Q3xDC^rNrO~B965Gk!PFoC!9KSRS5$MA(l+d0*(Kx zkG~p)wH|pvzPmOR)u&(-0+tlNlJ#Fau375OW__ULM^mN$hFUDhLAF7;YlN`G_M85x zv_!xUsee)co$mE7YIi|w?UU$iWz_zh_bkz?TVTWKEt2+VhB!kZG2485Ty)j;kko zGgCU7G#8P)tA?^4DQA;EbZ-NDlg0~~Dr~QdgB5Z&CAJg|>VOtCigwdLR`Dt3Atyw` zsSDp-#gEiIOky3(PK}PR*8Y>1sEQxy&c4VGx9bQdGS+N*HwO#ZKfY2HmHW1A-TQ8P zE>3v6O?iKDU$J`oNtbZlDbffvkHc1JU^uPs$@~-C_#NV)KAUQ5rDIseaqUbLk6pa1 zzGJtKFRw&k8RL}w6lS+1JsO)gvCmfSNEICF&Kx|05{hMwxWDcn>VLTR;&#h-ue}%w zRJpZCtK2BOYWybK=Ql%5$J(|Q)>HA;s9Y+Oz-9673`r8FJ}=1>u<+v{qui%gJYY~S zwEl2+cK11LvCCHp7U_o!o>QjyWx0JSub&K?;Sx3twm#do#$_P3hrlem7%jrz=;tph z?h0p6IXu!)cMm5(V}j$NsKgoHdNY$Hq5bjT{l#|KX`)ClVVOgBQm&IWo#ZfZBJA4d zuDN%^x+jGIKp3ZSMfoO~qWP|DS+VoxVeTwubQ{rdY?!79yv|#l2VorO#V?*F}(aY+FS@DsE6GGP$ zGcbfCTrQ^nCqr2fzfwmXl^$9N9^WJW>9!n2K=HY`gFRnqP@Nep#rK@b46_mCn*;mR zO1b=iRr-}N$~K-bf-y6Tv8pMvPuQdcS2`z;d2yso+uxvR2oj7ZCpM6E z*vME$1J%#fpMOh54=V9HXh~DK-SZ_K%yG@kGpRbi(3>15P=pNPlU0l@9X4@#h#bFf z8BB`+uYG8e-&w<@4NtbwCK=m2!A%8tO8neqpxnOw-?9kkf5s&WU9vFWlIBXSv%%@K7b`TNx)O zhfec-ne1REcxZ@ju?mLMz~Z^kpRzI@Ho%GGge1UJxmQZpuK&616QCG{awTA|?!C#ubI%Hm|9yqSKva|(5x^HHzb46XPVCkf9l*z!NAnfB3?gZlhbXfd4i1# z0MjmuHZV?#eQT$@O}7FOZVrgUWyzr%ja+}=RZ}%Rt-5=fw$u(xh9E7_5&VN?9uvcSYG7?40Nq`YCQYzDOYMZK&|Uauge$}O zHsy85qThPe(3mb4GVOK9>Za$YxNvs_)bee*()#;Rz!o~PB-426l7i-UO9D*|R>Sl= zfAZHhY#cLd1duwt@C*tLRcLE{S$IFX(v?NIS&pRlfa9vN^7SSZ--4xJX-6T{`R$bV zd1$h=3RVX~TI?U3jwYHvi+4#|3AywA{g7{QuR{(8tg83=KtmU=&I76ATesOnrPyljT~ EUl$_QPyhe` literal 0 HcmV?d00001 diff --git a/v0.18.15/development/proposals/MEP6/README/index.html b/v0.18.15/development/proposals/MEP6/README/index.html new file mode 100644 index 0000000000..a606e8371e --- /dev/null +++ b/v0.18.15/development/proposals/MEP6/README/index.html @@ -0,0 +1,38 @@ + +DMZ Networks · metal-stack

DMZ Networks

Reasoning

To fulfill higher levels of security measures the standard metal-stack approach with a single firewall in front of a set of machines might be insufficient. There are cases where two physically distinct firewalls in front of application workload are mandatory. In traditional network terms this is known as DMZ approach.

For Kubernetes workloads it makes sense to use the front cluster for ingress, WAF purposes and as outgoing proxy. The clusters may be used for application workload.

DMZ network

  • Use a separate DMZ network prefix for every tenant
  • This is used as intermediate network btw. private networks of a tenant and the internet
  • For every partition a distinct DMZ firewall/cluster is needed for a tenant
  • For Gardener orchestrated Kubernetes clusters this network must be a publicly reachable internet prefix because shoot clusters need a vpn service that is used for instrumentation from the seed cluster - this will be a requirement as long as the inverse vpn tunnel feature Konnectivity is not available to us.

Approach 1: DMZ with publicly reachable internet prefix

DMZ Internet

A DMZ network with publicly reachable internet prefix will look like this in the metal-api:

---
+description: DMZ-Network
+destinationprefixes:
+- 0.0.0.0/0
+id: dmz
+labels:
+  network.metal-stack.io/default-external: ""
+name: DMZ-Network
+parentnetworkid: null
+partitionid: ""
+prefixes:
+- 212.90.30.128/25
+privatesuper: false
+projectid: ""
+vrf: 104007
+vrfshared: false
+nat: true
+shared: false
+underlay: false

DMZ firewall

The firewall of the DMZ will intersect its private network for attached machines, the DMZ network and the public internet.

  • The private network of the project needs to import
    • the default route from the internet network
    • the DMZ network
  • The internet network must import the DMZ network
  • The DMZ network provides the default route for tenant's clusters in a partition. It imports the default route from the internet network

Application Firewall

The firewall of application workloads intersects its private network for attached machines and the DMZ network.

This is currently supported by the metal-networker and needs no further changes!

Approach 2: DMZ with private IPs

DMZ Internet

A DMZ network with private IPs will look like this in the metal-api:

---
+description: DMZ-Network
+destinationprefixes:
+- 0.0.0.0/0
+id: dmz
+labels:
+  network.metal-stack.io/default-external: ""
+name: DMZ-Network
+parentnetworkid: tenant-super-network-fra-equ01
+partitionid: fra-equ01
+prefixes:
+- 10.90.30.128/25
+privatesuper: false
+projectid: ""
+vrf: 4711
+vrfshared: false
+nat: true
+shared: true # it's usable from multiple projects
+underlay: false

DMZ firewall

The firewall of the DMZ will intersect its private network for attached machines, the DMZ network and the public internet.

  • The private network of the project needs to import
    • the default route from the internet network
    • the DMZ network
  • The internet network must import the DMZ network (only locally, no-export)
  • The DMZ network provides the default route for tenant's clusters in a partition. It imports the default route from the internet network

Application Firewall

The firewall of application workloads intersects its private network for attached machines and the DMZ network.

Code Changes / Implications

  • metal-networker and metal-ccm assume that there is only one network providing the default-route
  • metal-networker needs to
    • import the default route from the internet network to the dmz network (DMZ Firewall)
    • import the DMZ network to the internet network and adjusting NAT rules (DMZ Firewall)
    • import destination prefixes of the DMZ network to the private primary network (DMZ Firewall, Application Firewall)
    • import DMZ-IPs of the private primary network to the DMZ network (DMZ Firewall, Application Firewall)
  • metal-api: destination prefixes of private networks need to be configurable (allocateNetwork)
  • gardener-extension-provider-metal: needs to be able to delete DMZ clusters (but skip the network deletion part)
  • the application firewall is not publicly reachable - for debugging purposes a hop over the DMZ firewall is needed

Decision

We decided to follow the second approach with private DMZ networks.

diff --git a/v0.18.15/development/proposals/MEP6/dmz-internet_private.drawio b/v0.18.15/development/proposals/MEP6/dmz-internet_private.drawio new file mode 100644 index 0000000000..7b83bbfc2d --- /dev/null +++ b/v0.18.15/development/proposals/MEP6/dmz-internet_private.drawio @@ -0,0 +1,178 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/v0.18.15/development/proposals/MEP6/dmz-internet_private.svg b/v0.18.15/development/proposals/MEP6/dmz-internet_private.svg new file mode 100644 index 0000000000..6d70dc6ed3 --- /dev/null +++ b/v0.18.15/development/proposals/MEP6/dmz-internet_private.svg @@ -0,0 +1 @@ +
Machine
Machine
Firewall DMZ
Firewall DMZ
DMZ VRF
DMZ VRF
Machine
Machine
Firewall A
Firewall A
Private VRF A
Private VRF A
10.0.0.2
10.90.30.129
/0 via Firewall A
10.0.0.2...
VRF A 10.0.0.1
VRF A 10.0.0.1
DMZ Network
10.90.30.128/25
DMZ Network...
Private Network
10.0.0.0/24
Private Network...
import /0
import /0
import 10.0.0.0/24
import 10.0.0.0/24
Machine
Machine
Firewall B
Firewall B
Private VRF B
Private VRF B
10.0.1.2
/0 via Firewall B
10.0.1.2...
VRF B 10.0.1.1
VRF B 10.0.1.1
Private Network
10.0.1.0/24
Private Network...
import /0
import /0
import 10.0.1.0/24
import 10.0.1.0/24
10.90.30.129 is reachable
/0 via Firewall DMZ
10.0.0.0/24 is reachable
10.0.1.0/24 is reachable
10.90.30.129 is reachable...
Internet
212.1.1.0/27
Internet...
SNAT to 212.1.1.1
SNAT to 212.1.1.1
Internet VRF
Internet VRF
import /0
import /0

import 10.0.0.0/24 no export
import 10.0.1.0/24 no export
import 10.90.30.128/25 no export
import 10.0.0.0/24 no exp...
Viewer does not support full SVG 1.1
\ No newline at end of file diff --git a/v0.18.15/development/proposals/MEP6/dmz-internet_public.drawio b/v0.18.15/development/proposals/MEP6/dmz-internet_public.drawio new file mode 100644 index 0000000000..544939e50f --- /dev/null +++ b/v0.18.15/development/proposals/MEP6/dmz-internet_public.drawio @@ -0,0 +1,184 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/v0.18.15/development/proposals/MEP6/dmz-internet_public.svg b/v0.18.15/development/proposals/MEP6/dmz-internet_public.svg new file mode 100644 index 0000000000..98c5e02102 --- /dev/null +++ b/v0.18.15/development/proposals/MEP6/dmz-internet_public.svg @@ -0,0 +1 @@ +
Machine
Machine
Firewall DMZ
Firewall DMZ
DMZ VRF
DMZ VRF
Machine
Machine
Firewall A
Firewall A
Private VRF A
Private VRF A
10.0.0.2
212.1.2.3
/0 via Firewall A
10.0.0.2...
VRF A 10.0.0.1
VRF A 10.0.0.1
DMZ Network
212.1.2.0/27
DMZ Network...
Private Network
10.0.0.0/24
Private Network...
import /0
import /0
import 10.0.0.0/24
import 10.0.0.0/24
Machine
Machine
Firewall B
Firewall B
Private VRF B
Private VRF B
10.0.1.2
/0 via Firewall B
10.0.1.2...
VRF B 10.0.1.1
VRF B 10.0.1.1
Private Network
10.0.1.0/24
Private Network...
import /0
import /0
import 10.0.1.0/24
import 10.0.1.0/24
212.1.2.3 is reachable
/0 via Firewall DMZ
212.1.2.3 is reachable...
Internet
212.1.1.0/27 212.1.2.0/27
Internet...
SNAT to 212.1.1.1
SNAT to 212.1.1.1
Internet VRF
Internet VRF
import /0
import /0
import 212.1.2.0/27
import 10.0.0.0/24 no redistribute
import 10.0.1.0/24 no redistribute

import 212.1.2.0/27...
SNAT to
212.1.2.1
SNAT to...
SNAT to
212.1.2.2
SNAT to...
Viewer does not support full SVG 1.1
\ No newline at end of file diff --git a/v0.18.15/development/proposals/MEP8/README/index.html b/v0.18.15/development/proposals/MEP8/README/index.html new file mode 100644 index 0000000000..83f919c932 --- /dev/null +++ b/v0.18.15/development/proposals/MEP8/README/index.html @@ -0,0 +1,367 @@ + +Configurable Filesystem layout for Machine Allocation · metal-stack

Configurable Filesystem layout for Machine Allocation

The current implementation uses a hard coded filesystem layout depending on the specified size and image. This is done in the metal-hammer. This worked well in the past because we had a small amount of sizes and images. But we reached a point where this is to restricted for all use cases we have to fulfill. It also forces us to modify the metal-hammer source code to support a new filesystem layout.

This proposal tries to address this issue by introducing a filesystem layout struct in the metal-api which is then configurable per machine allocation. The original behavior of automatic filesystem layout decision must still be present, because there must be no API change for existing API consumers. It should be a additional feature during machine allocation.

API and behavior

The API will get a new endpoint filesystemlayoutsto create/update/delete a set of available filesystemlayouts.

Constraints

In order to keep the actual machine allocation api compatible, there must be no difference while allocating a machine. To achieve this every filesystemlayout defines constraints which specifies for which combination of sizes and images this layout should be used by default. The specified constraints over all filesystemlayouts therefore must be collision free, to be more specific, there must be exactly one layout outcome for every possible combination of sizes and images.

The size constraint must be a list of the exact size ids, the image constraint must be a map of os to semver compatible version constraint. For example:

  • debian: ">= 10.20210101" or debian: "< 10.20210101"

The general form of a image constraint is a map from os to versionconstraint where:

os must match the first part of the image without the version. versionconstraint must be the comparator, a space and the version, or simply * to match all versions of this os. The comparator must be one of: "=", "!=", ">", "<", ">=", "=>", "<=", "=<", "~", "~>", "^"

It must also be possible to have a filesystemlayout in development or for other special purposes, which can be specified during the machine allocation. To have such a layout, both constraints sizes and imagesmust be empty list.

Reinstall

The current reinstall implementation the metal-hammer detects during the installation on which disk the OS was installed and reports back to the metal-api the Report struct which has two properties primarydisk and ospartition. Both fields are not required anymore because the logic is now shifted to the filesystemlayout definition. If Disk.WipeOnReinstall is set to true, this disk will be wiped, default is false and is preserved.

Handling of s2-xlarge machines

These machines are a bit special compared to our c1-* machines because they have rotating hard disks for the mass storage purpose. The downside is that the on board SATA-DOM has the same naming as the HDDs and can not be specified as the first /dev/sda disk because all HDDs are also /dev/sd* disks. Therefore we had a special SATA-DOM detection algorithm inside metal-hammer which simply checks for the smallest /dev/sd disk and took this to install the OS.

This is not possible with the current approach, but we figured out that the SATA-DOM is always /dev/sde. So we can create a special filesystemlayout where the installations is made on this disk.

Possible Filesystemlayout hierarchies

It is only possible to create a filesystem on top of a block device. The creation of a block device can be done on multiple ways, depending on the requirements regarding performance, space and redundancy of the filesystem. It also depends on the disks available on the server.

The current approach implements the following hierarchies:

filesystems

Implementation

// FilesystemLayout to be created on the given machine
+type FilesystemLayout struct {
+  // ID unique layout identifier
+  ID          string
+  // Description is human readable
+  Description string
+  // Filesystems to create on the server
+  Filesystems []Filesystem
+  // Disks to configure in the server with their partitions
+  Disks       []Disk
+  // Raid if not empty, create raid arrays out of the individual disks, to place filesystems onto
+  Raid        []Raid
+  // VolumeGroups to create
+  VolumeGroups []VolumeGroup
+  // LogicalVolumes to create on top of VolumeGroups
+  LogicalVolumes []LogicalVolume
+  // Constraints which must match to select this Layout
+  Constraints FilesystemLayoutConstraints
+}
+
+type FilesystemLayoutConstraints struct {
+  // Sizes defines the list of sizes this layout applies to
+  Sizes []string
+  // Images defines a map from os to versionconstraint
+  // the combination of os and versionconstraint per size must be conflict free over all filesystemlayouts
+  Images map[string]string
+}
+
+type RaidLevel string
+type Format string
+type GPTType string
+
+// Filesystem defines a single filesystem to be mounted
+type Filesystem struct {
+  // Path defines the mountpoint, if nil, it will not be mounted
+  Path           *string
+  // Device where the filesystem is created on, must be the full device path seen by the OS
+  Device         string
+  // Format is the type of filesystem should be created
+  Format         Format
+  // Label is optional enhances readability
+  Label          *string
+  // MountOptions which might be required
+  MountOptions   []string
+  // CreateOptions during filesystem creation
+  CreateOptions  []string
+}
+
+// Disk represents a single block device visible from the OS, required
+type Disk struct {
+  // Device is the full device path
+  Device          string
+  // Partitions to create on this device
+  Partitions      []Partition
+  // WipeOnReinstall, if set to true the whole disk will be erased if reinstall happens
+  // during fresh install all disks are wiped
+  WipeOnReinstall bool
+}
+
+// Raid is optional, if given the devices must match.
+// TODO inherit GPTType from underlay device ?
+type Raid struct {
+  // ArryName of the raid device, most often this will be /dev/md0 and so forth
+  ArryName    string
+  // Devices the devices to form a raid device
+  Devices []Device
+  // Level the raidlevel to use, can be one of 0,1,5,10 
+  // TODO what should be support
+  Level   RaidLevel
+  // CreateOptions required during raid creation, example: --metadata=1.0 for uefi boot partition
+  CreateOptions []string
+  // Spares defaults to 0
+  Spares  int
+}
+
+
+// VolumeGroup is optional, if given the devices must match.
+type VolumeGroup struct {
+  // Name of the volumegroup without the /dev prefix
+  Name string
+  // Devices the devices to form a volumegroup device
+  Devices []string
+  // Tags to attach to the volumegroup
+  Tags []string
+}
+
+// LogicalVolume is a block devices created with lvm on top of a volumegroup
+type LogicalVolume struct {
+  // Name the name of the logical volume, without /dev prefix, will be accessible at /dev/vgname/lvname
+  Name string
+  // VolumeGroup the name of the volumegroup
+  VolumeGroup string
+  // Size of this LV in mebibytes (MiB)
+  Size uint64
+  // LVMType can be either striped or raid1
+  LVMType LVMType
+}
+
+// Partition is a single partition on a device, only GPT partition types are supported
+type Partition struct {
+  // Number of this partition, will be added to the device once partitioned
+  Number    int
+  // Label to enhance readability
+  Label     *string
+  // Size given in MebiBytes (MiB)
+  // if "0" is given the rest of the device will be used, this requires Number to be the highest in this partition
+  Size      string
+  // GPTType defines the GPT partition type
+  GPTType   *GPTType
+}
+
+const (
+  // VFAT is used for the UEFI boot partition
+  VFAT = Format("vfat")
+  // EXT3 is usually only used for /boot
+  EXT3 = Format("ext3")
+  // EXT4 is the default fs
+  EXT4 = Format("ext4")
+  // SWAP is for the swap partition
+  SWAP = Format("swap")
+  // None
+  NONE = Format("none")
+
+  // GPTBoot EFI Boot Partition
+  GPTBoot = GPTType("ef00")
+  // GPTLinux Linux Partition
+  GPTLinux = GPTType("8300")
+  // GPTLinuxRaid Linux Raid Partition
+  GPTLinuxRaid = GPTType("fd00")
+  // GPTLinux Linux Partition
+  GPTLinuxLVM = GPTType("8e00")
+
+  // LVMTypeLinear append across all physical volumes
+  LVMTypeLinear = LVMType("linear")
+  // LVMTypeStriped stripe across all physical volumes
+  LVMTypeStriped = LVMType("striped")
+  // LVMTypeStripe mirror with raid across all physical volumes
+  LVMTypeRaid1 = LVMType("raid1")
+)

Example metalctl outputs:

$ metalctl filesystemlayouts ls
+ID             DESCRIPTION         SIZES                         IMAGES
+default        default fs layout   c1-large-x86, c1-xlarge-x86   debian >=10, ubuntu >=20.04, centos >=7
+ceph           fs layout for ceph  s2-large-x86, s2-xlarge-x86   debian >=10, ubuntu >=20.04
+firewall       firewall fs layout  c1-large-x86, c1-xlarge-x86   firewall >=2
+storage        storage fs layout   s3-large-x86                  centos >=7
+s3             storage fs layout   s2-xlarge-x86                 debian >=10, ubuntu >=20.04, >=firewall-2
+default-devel  devel fs layout 

The default layout reflects what is actually implemented in metal-hammer to guarantee backward compatibility.

---
+id: default
+constraints:
+  sizes:
+    - c1-large-x86
+    - c1-xlarge-x86
+  images:
+    debian: ">=10"
+    ubuntu: ">=20.04"
+    centos: ">=7"
+filesystems:
+  - path: "/boot/efi"
+    device: "/dev/sda1"
+    format: "vfat"
+    options: "-F 32"
+    label: "efi" # required to be compatible with old images
+  - path: "/"
+    device: "/dev/sda2"
+    format: "ext4"
+    label: "root" # required to be compatible with old images
+  - path: "/var/lib"
+    device: "/dev/sda3"
+    format: "ext4"
+    label: "varlib" # required to be compatible with old images
+  - path: "/tmp"
+    device: "tmpfs"
+    format: "tmpfs"
+    mountoptions: ["defaults","noatime","nosuid","nodev","noexec","mode=1777","size=512M"]
+disks:
+  - device: "/dev/sda"
+    wipe: true
+    partitions:
+      - number: 1
+        label: "efi"
+        size: 500
+        type: GPTBoot
+      - number: 2
+        label: "root"
+        size: 5000
+        type: GPTLinux
+      - number: 3
+        label: "varlib"
+        size: 0 # to end of partition
+        type: GPTLinux

The firewall layout reuses the built in nvme disk to store the logs, which is way faster and larger than what the sata-dom ssd provides.

---
+id: firewall
+constraints:
+  sizes:
+    - c1-large-x86
+    - c1-xlarge-x86
+  images:
+    firewall: ">=2"
+filesystems:
+  - path: "/boot/efi"
+    device: "/dev/sda1"
+    format: "vfat"
+    options: "-F 32"
+  - path: "/"
+    device: "/dev/sda2"
+    format: "ext4"
+  - path: "/var"
+    device: "/dev/nvme0n1p1"
+    format: "ext4"
+disks:
+  - device: "/dev/sda"
+    wipe: true
+    partitions:
+      - number: 1
+        label: "efi"
+        size: 500
+        type: GPTBoot
+      - number: 2
+        label: "root"
+        size: 5000
+        type: GPTLinux
+  - device: "/dev/nvme0n1"
+    wipe: true
+    partitions:
+      - number: 1
+        label: "var"
+        size: 0
+        type: GPTLinux

The storage layout will be used for the storage servers, which must have mirrored boot disks.

---
+id: storage
+constraints:
+  sizes:
+    - s3-large-x86
+  images:
+    centos: ">=7"
+filesystems:
+  - path: "/boot/efi"
+    device: "/dev/md1"
+    format: "vfat"
+    options: "-F32"
+  - path: "/"
+    device: "/dev/md2"
+    format: "ext4"
+disks:
+  - device: "/dev/sda"
+    wipe: true
+    partitions:
+      - number: 1
+        label: "efi"
+        size: 500
+        type: GPTLinuxRaid
+      - number: 2
+        label: "root"
+        size: 5000
+        type: GPTLinuxRaid
+  - device: "/dev/sdb"
+    wipe: true
+    partitions:
+      - number: 1
+        label: "efi"
+        size: 500
+        type: GPTLinuxRaid
+      - number: 2
+        label: "root"
+        size: 5000
+        type: GPTLinuxRaid
+raid:
+  - name: "/dev/md1"
+    level: 1
+    devices:
+      - "/dev/sda1"
+      - "/dev/sdb1"
+    options: "--metadata=1.0"
+  - name: "/dev/md2"
+    level: 1
+    devices:
+      - "/dev/sda2"
+      - "/dev/sdb2"
+    options: "--metadata=1.0"

The s3-storage layout matches the special situation on the s2-xlarge machines.

---
+id: s3-storage
+constraints:
+  sizes:
+    - c1-large-x86
+    - s2-xlarge-x86
+  images:
+    debian: ">=10"
+    ubuntu: ">=20.04"
+    centos: ">=7"
+filesystems:
+  - path: "/boot/efi"
+    device: "/dev/sde1"
+    format: "vfat"
+    options: "-F 32"
+  - path: "/"
+    device: "/dev/sde2"
+    format: "ext4"
+  - path: "/var/lib"
+    device: "/dev/sde3"
+    format: "ext4"
+disks:
+  - device: "/dev/sde"
+    wipe: true
+    partitions:
+      - number: 1
+        label: "efi"
+        size: 500
+        type: GPTBoot
+      - number: 2
+        label: "root"
+        size: 5000
+        type: GPTLinux
+      - number: 3
+        label: "varlib"
+        size: 0 # to end of partition
+        type: GPTLinux

A sample lvm layout which puts /var/lib as stripe on the nvme device

---
+id: lvm
+description: "lvm layout"
+constraints:
+  size:
+    - s2-xlarge-x86
+  images:
+    debian: ">=10"
+    ubuntu: ">=20.04"
+    centos: ">=7"
+filesystems:
+  - path: "/boot/efi"
+    device: "/dev/sda1"
+    format: "vfat"
+    createoptions: 
+      - "-F 32"
+    label: "efi"
+  - path: "/"
+    device: "/dev/sda2"
+    format: "ext4"
+    label: "root"
+  - path: "/var/lib"
+    device: "/dev/vg00/varlib"
+    format: "ext4"
+    label: "varlib"
+  - path: "/tmp"
+    device: "tmpfs"
+    format: "tmpfs"
+    mountoptions: ["defaults","noatime","nosuid","nodev","noexec","mode=1777","size=512M"]
+volumegroups:
+  - name: "vg00"
+    devices:
+      - "/dev/nvmne0n1"
+      - "/dev/nvmne0n2"
+logicalvolumes:
+  - name: "varlib"
+    volumegroup: "vg00"
+    size: 200
+    lvmtype: "striped"
+disks:
+  - device: "/dev/sda"
+    wipeonreinstall: true
+    partitions:
+      - number: 1
+        label: "efi"
+        size: 500
+        gpttype: "ef00"
+      - number: 2
+        label: "root"
+        size: 5000
+        gpttype: "8300"
+  - device: "/dev/nvmne0n1"
+    wipeonreinstall: false
+  - device: "/dev/nvmne0n2"
+    wipeonreinstall: false

Components which requires modifications

  • metal-hammer:
    • change implementation from build in hard coded logic
    • move logic to create fstab from install.sh to metal-hammer
  • metal-api:
    • new endpoint filesystemlayouts
    • add optional spec of filesystemlayout during allocation with validation if given filesystemlayout is possible on given size.
    • add allocation.filesystemlayout in the response, based on either the specified filesystemlayout or the calculated one.
    • implement filesystemlayouts validation for:
      • matching to disks in the size
      • no overlapping with the sizes/imagefilter specified in filesystemlayouts
      • all devices specified exists from top to bottom (fs -> disks -> device || fs -> raid -> devices)
  • metalctl:
    • implement filesystemlayouts
  • metal-go:
    • adopt api changes
  • metal-images:
    • install mdadm for raid support
diff --git a/v0.18.15/development/proposals/MEP8/filesystems.drawio b/v0.18.15/development/proposals/MEP8/filesystems.drawio new file mode 100644 index 0000000000..0f0c6ab556 --- /dev/null +++ b/v0.18.15/development/proposals/MEP8/filesystems.drawio @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/v0.18.15/development/proposals/MEP8/filesystems.png b/v0.18.15/development/proposals/MEP8/filesystems.png new file mode 100644 index 0000000000000000000000000000000000000000..6d903b7ec9c8c069383846912f136127e54a371a GIT binary patch literal 24073 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 literal 0 HcmV?d00001 diff --git a/v0.18.15/development/proposals/MEP9/README/index.html b/v0.18.15/development/proposals/MEP9/README/index.html new file mode 100644 index 0000000000..a3d403024d --- /dev/null +++ b/v0.18.15/development/proposals/MEP9/README/index.html @@ -0,0 +1,13 @@ + +No Open Ports To the Data Center · metal-stack

No Open Ports To the Data Center

Our metal-stack partitions typically have open ports for metal-stack native services, these are:

  • SSH port on the firewalls
  • bmc-reverse-proxy for serial console access through the metal-console

These open ports are potential security risks. For example, while SSH access is possible only with private key it's still vulnerable to DoS attack.

Therefore, we want to get rid off these open ports to reduce the attack surface to the data center.

Requirements

  • Access to firewall SSH only via VPN
  • Easy to update VPN components

As a next step, we can also consider joining the management servers to the VPN mesh, which would replace typical WireGuard setups for operators to enter resources inside the partition.

High Level Design

Simplified drawing showing old vs. new architecture.

Concerns

There's few concerns when using WireGuard for implementing VPN:

  1. WireGuard doesn't implement dynamic cipher substitution. Which is important in case one of the crypto methods, used by WireGuard will be broken. The only possible solution for that will be to update WireGuard to a fixed version.
  2. Coordination server(Headscale) is a single point of failure. In case it fails, it potentially can disconnect existing members of the network, as WireGuard can't manage dynamic IPs by itself.
  3. Headscale is already falls behind Tailscale coordination server implementation. Which can complicate the upgrade to newer version of Tailscale client in case of emergency.

Solutions to concerns

  1. Tailscale node software is using userspace implementation of WireGuard – wireguard-go. One of the options is to inject Tailscale client into metalctl. And make it available as metalctl vpn or similar command. It should be possible to do as tailscale node is already available as open sourced Go pkg. That would allow us to control, what version of Tailscale users are using and in case of any critical changes to enforce them to update metalctl to use VPN functionality.
  2. Would it be a considerable risk? We could look into wg-dynamic project to cover this problem.
  3. At the moment, repository looks well maintained and the metal-stack team already contributes to it.

Implementation Details

metal-roles

metal-roles will be responsible for deployment of headscale server(via new headscale role). It also should provide sufficient config to metal-api so it establishes connection with headscale gRPC server.

New metalctl commands

metalctl will be responsible for client-side implementation of this MEP. Specifically, it's by using metalctl user expected to connect to firewalls.

  • metalctl vpn – section for VPN related commands:
    • metalctl vpn get key [vpn name] --namespace [namespace name] – returns auth key to be used with tailscale client for establishing connection.

Extend metalctl firewall:

  • metalctl firewall ssh [ID] – connect to firewall via SSH.

Extend metalctl machine:

  • metalctl machine ssh [ID] – connect to machine via SSH.

metalctl will be able to connect to firewall and machines by running tailscale in container.

metal-api

Updates to metal-api should be made, so that it's able to add firewalls to VPNs. There should be one Tailscale namespace per project. So if multiple firewalls are created in single project, they will join the same namespace.

Two new flags should be introduced to connect metal-api to headscale gRPC server:

  • headscale-addr – specifies address of Headscale grpc API.
  • headscale-api-key – specifies temporary API key to connect to Headscale. It should be replaced and then rotated by metal-api.

If metal-api initialized with headscale connection it should automatically join all created firewalls to VPN.

Add new endpoint, that will be used by metalctl to connect to VPN:

  • /v1/vpn GET – requests auth key from headscale server.

metal-hammer

metal-hammer acts as an intermediary for machine configuration between metal-api and machine's image. Specifically it writes to /etc/metal/install.yaml file, data from which later will be used by image's install.sh file.

To implement VPN support we have to add authentication key and VPN server address to install.yaml file. This key will be used to join machine to a VPN.

metal-images

Images install.sh script have to be updated to work with authentication key and VPN server address, provided in install.yaml file. If this key is present, machine should connect to VPN.

metal-networker

metal-networker also have to know if VPN was configured. In that case we need to disable public access to SSH and allow all(?) traffic from WireGuard interface.

firewall-controller

firewall-controller have to monitor changes in Firewall resource and keep tailscaled version up-to-date.

Resources

Update Firewall resource to include desired/actual tailscale version:

Firewall:
+  Spec:
+    tailscale:
+      Version:   Minimal version
+    ...
+  Status:
+    ...
+    VPN:
+      Status:    Boolean field
+    tailscale:
+      Version:   Actual version
+    ...

bmc-reverse-proxy

TODO

References

  1. WireGuard: Next Generation Secure Network Tunnel
  2. How Tailscale works
  3. Tailscale is officially SOC 2 compliant
  4. Why not Wireguard
  5. Wireguard: Known Limitations
  6. Wireguard: Things That Might Be Accomplished
  7. Headscale: Tailscale control protocol v2
diff --git a/v0.18.15/development/proposals/MEP9/architecture.drawio.svg b/v0.18.15/development/proposals/MEP9/architecture.drawio.svg new file mode 100644 index 0000000000..adb092145b --- /dev/null +++ b/v0.18.15/development/proposals/MEP9/architecture.drawio.svg @@ -0,0 +1,324 @@ + + + + + + + +
+
+
+ Metal Control Plane +
+
+
+
+ + Metal Control Plane + +
+
+ + + + +
+
+
+ metal-stack +
+ Partition +
+
+
+
+ + metal-stack... + +
+
+ + + + +
+
+
+ firewall +
+
+
+
+ + firewall + +
+
+ + + + + +
+
+
+ machine +
+
+
+
+ + machine + +
+
+ + + + +
+
+
+ ssh +
+
+
+
+ + ssh + +
+
+ + + + +
+
+
+ bmc-proxy +
+
+
+
+ + bmc-proxy + +
+
+ + + + + + + + + + +
+
+
+ Metal Control Plane +
+
+
+
+ + Metal Control Plane + +
+
+ + + + +
+
+
+ metal-stack +
+ Partition +
+
+
+
+ + metal-stack... + +
+
+ + + + +
+
+
+ firewall +
+
+
+
+ + firewall + +
+
+ + + + + +
+
+
+ machine +
+
+
+
+ + machine + +
+
+ + + + +
+
+
+ ssh +
+
+
+
+ + ssh + +
+
+ + + + + + +
+
+
+ bmc-proxy +
+
+
+
+ + bmc-proxy + +
+
+ + + + +
+
+
+ headscale +
+
+
+
+ + headscale + +
+
+ + + + + + + + + + +
+
+
+ tailscaled +
+
+
+
+ + tailscaled + +
+
+ + + + + + +
+
+
+ tailscaled +
+
+
+
+ + tailscaled + +
+
+ + + + +
+
+
+ Internet +
+
+
+
+ + Internet + +
+
+ + + + +
+
+
+ Internet +
+
+
+
+ + Internet + +
+
+
+ + + + + Viewer does not support full SVG 1.1 + + + +
diff --git a/v0.18.15/development/proposals/index.html b/v0.18.15/development/proposals/index.html new file mode 100644 index 0000000000..73210408b3 --- /dev/null +++ b/v0.18.15/development/proposals/index.html @@ -0,0 +1,2 @@ + +Enhancement Proposals · metal-stack

Metal Stack Enhancement Proposals (MEPs)

This section contains proposals which address substantial modifications to metal-stack.

Every proposal has a short name which starts with MEP followed by an incremental, unique number. Proposals should be raised as pull requests in the docs repository and can be discussed in Github issues.

The list of proposal and their current state is listed in the table below.

Possible states are:

  • In Discussion
  • Accepted
  • Declined
  • In Progress
  • Completed
  • Aborted

Once a proposal was accepted, an issue should be raised and the implementation should be done in a separate PR.

NameDescriptionState
MEP-1Distributed Control Plane DeploymentIn Discussion
MEP-2Two Factor AuthenticationAborted
MEP-3Machine Re-Installation to preserve local dataCompleted
MEP-4Multi-tenancy for the metal-apiIn Discussion
MEP-5Shared NetworksCompleted
MEP-6DMZ NetworksCompleted
MEP-8Configurable FilesystemlayoutCompleted
MEP-9No Open Ports To the Data CenterCompleted
MEP-10SONiC SupportCompleted
MEP-11Auditing of metal-stack resourcesCompleted
MEP-12Rack SpreadingCompleted
MEP-14Independence from external sourcesIn Discussion
diff --git a/v0.18.15/development/roadmap/index.html b/v0.18.15/development/roadmap/index.html new file mode 100644 index 0000000000..034871a0ee --- /dev/null +++ b/v0.18.15/development/roadmap/index.html @@ -0,0 +1,2 @@ + +Roadmap · metal-stack

Roadmap

A roadmap with short-, mid- and long-term planning will be available soon. For now, there is only a backlog.

Short-term

Available soon.

Mid-term

Available soon.

Long-term

Available soon.

Backlog

The backlog contains ideas of what could become part of the roadmap in the future. The list is ordered alphabetically. Therefore, the order does not express the importance or weight of a backlog item.

We incorporate community feedback into the roadmap. If you think that important points are missing in the backlog, please share your ideas with us. We have a Slack channel. Please check out metal-stack.io for contact information.

Danger

By no means this list is a promise of what is being worked on in the near future. It is just a summary of ideas that was agreed on to be "nice to have". It is up to the investors, maintainers and the community to choose topics from this list and to implement them or to remove them from the list.

  • Add metal-stack to Gardener conformance test grid
  • Autoscaler for metal control plane components
  • CI dashboard and public integration testing
  • Cilium as the default CNI for metal-stack on Gardener K8s clusters
  • Improved release and deploy processes (GitOps, Spinnaker, Flux)
  • Machine internet without firewalls
  • metal-stack dashboard (UI)
  • Offer our metal-stack extensions as enterprise products (accounting, cluster-api, S3) (neither of them will ever be required for running metal-stack, they just add extra value for certain enterprises)
  • Partition managed by Kubernetes (with Kubelets joining the control plane cluster)
  • Public offering / demo playground
  • Resource scoping in the metal-api (MEP-4)
  • Service / API tokens (for scoped technical user access)
diff --git a/v0.18.15/external/csi-driver-lvm/CONTRIBUTING/index.html b/v0.18.15/external/csi-driver-lvm/CONTRIBUTING/index.html new file mode 100644 index 0000000000..47cbb99d4a --- /dev/null +++ b/v0.18.15/external/csi-driver-lvm/CONTRIBUTING/index.html @@ -0,0 +1,2 @@ + +Contributing · metal-stack diff --git a/v0.18.15/external/csi-driver-lvm/README/index.html b/v0.18.15/external/csi-driver-lvm/README/index.html new file mode 100644 index 0000000000..dbe7b7a198 --- /dev/null +++ b/v0.18.15/external/csi-driver-lvm/README/index.html @@ -0,0 +1,16 @@ + +csi-driver-lvm · metal-stack

csi-driver-lvm

CSI DRIVER LVM utilizes local storage of Kubernetes nodes to provide persistent storage for pods.

It automatically creates hostPath based persistent volumes on the nodes.

Underneath it creates a LVM logical volume on the local disks. A comma-separated list of grok pattern, which disks to use must be specified.

This CSI driver is derived from csi-driver-host-path and csi-lvm

Currently it can create, delete, mount, unmount and resize block and filesystem volumes via lvm

For the special case of block volumes, the filesystem-expansion has to be performed by the app using the block device

Installation

Helm charts for installation are located in a separate repository called helm-charts. If you would like to contribute to the helm chart, please raise an issue or pull request there.

You have to set the devicePattern for your hardware to specify which disks should be used to create the volume group.

helm install --repo https://helm.metal-stack.io mytest csi-driver-lvm --set lvm.devicePattern='/dev/nvme[0-9]n[0-9]'

Now you can use one of following storageClasses:

  • csi-driver-lvm-linear
  • csi-driver-lvm-mirror
  • csi-driver-lvm-striped

To get the previous old and now deprecated csi-lvm-sc-linear, ... storageclasses, set helm-chart value compat03x=true.

Migration

If you want to migrate your existing PVC to / from csi-driver-lvm, you can use korb.

Todo

  • implement CreateSnapshot(), ListSnapshots(), DeleteSnapshot()

Test

kubectl apply -f examples/csi-pvc-raw.yaml
+kubectl apply -f examples/csi-pod-raw.yaml
+
+
+kubectl apply -f examples/csi-pvc.yaml
+kubectl apply -f examples/csi-app.yaml
+
+kubectl delete -f examples/csi-pod-raw.yaml
+kubectl delete -f examples/csi-pvc-raw.yaml
+
+kubectl delete -f  examples/csi-app.yaml
+kubectl delete -f examples/csi-pvc.yaml

Development

In order to run the integration tests locally, you need to create to loop devices on your host machine. Make sure the loop device mount paths are not used on your system (default path is /dev/loop10{0,1}).

You can create these loop devices like this:

for i in 100 101; do fallocate -l 1G loop${i}.img ; sudo losetup /dev/loop${i} loop${i}.img; done
+sudo losetup -a
+# use this for recreation or cleanup
+# for i in 100 101; do sudo losetup -d /dev/loop${i}; rm -f loop${i}.img; done

You can then run the tests against a kind cluster, running:

make test

To recreate or cleanup the kind cluster:

make test-cleanup

Page Tree

diff --git a/v0.18.15/external/firewall-controller/CONTRIBUTING/index.html b/v0.18.15/external/firewall-controller/CONTRIBUTING/index.html new file mode 100644 index 0000000000..b410ca34a7 --- /dev/null +++ b/v0.18.15/external/firewall-controller/CONTRIBUTING/index.html @@ -0,0 +1,2 @@ + +Contributing · metal-stack diff --git a/v0.18.15/external/firewall-controller/DEVELOP/index.html b/v0.18.15/external/firewall-controller/DEVELOP/index.html new file mode 100644 index 0000000000..2e4e90e797 --- /dev/null +++ b/v0.18.15/external/firewall-controller/DEVELOP/index.html @@ -0,0 +1,21 @@ + +Develop Setup · metal-stack

Develop Setup

  1. download kubebuilder
  2. download kustomize from kustomize
  3. init project and run kubebuilder
    kubebuilder init --domain metal-stack.io
    +kubebuilder create api --group firewall --version v1 --kind Network
  4. run test
    export KUBEBUILDER_ASSETS=/usr/local/kubebuilder/bin # path-to-kubebuilder/bin
    +make test

Testing locally

# make binary
+make
+
+# start the controller
+bin/firewall-controller --hosts-file ./hosts --enable-signature-check=false --enable-IDS=false
+
+# install kind (k8s in docker)
+
+# create a local kind cluster
+kind create cluster
+
+# deploy manifests
+k apply -f deploy
+
+# watch results
+k describe -n firewall firewall
+cat nftables.v4
+cat hosts
diff --git a/v0.18.15/external/firewall-controller/README/index.html b/v0.18.15/external/firewall-controller/README/index.html new file mode 100644 index 0000000000..39fcc87232 --- /dev/null +++ b/v0.18.15/external/firewall-controller/README/index.html @@ -0,0 +1,125 @@ + +firewall-controller · metal-stack

Firewall Controller

This controller is installed on a bare-metal firewall in front of several kubernetes worker nodes and responsible to reconcile a ClusterwideNetworkPolicy to nftables rules to control access to and from the kubernetes cluster. It allows also to control the traffic rate going through, to limit network resources for restricted usage scenarios. Nftable and node metrics are exposed with the nftables-exporter and node-exporter, the ips are visible as service and endpoint from the kubernetes cluster.

Additional an IDS is managed on the firewall to detect known network anomalies. suricata is used for this purpose. Right now, only basic statistics about the amount of scanned packets is reported. In a future release, access to all alarms will be provided.

Architecture

Architecture

Automatically generated ingress rules

For every Service of type LoadBalancer in the cluster, the corresponding ingress rules will be automatically generated.

If loadBalancerSourceRanges is not specified, incomig traffic to this service will be allowed for any source ip addresses.

Configuration

Firewall Controller is configured with 2 CRDs: firewalls.metal-stack.io and clusterwidenetworkpolicies.metal-stack.io. Both are namespaced and must reside in the firewall namespace. The firewalls CRD is typically written from the gardener-extension-provider-metal, the clusterwidenetworkpolicy should be provided by the deployment of your application.

Example Firewall CRD:

apiVersion: metal-stack.io/v1
+kind: Firewall
+metadata:
+  namespace: firewall
+  name: firewall
+spec:
+  # Interval of reconciliation if nftables rules and network traffic accounting
+  interval: 10s
+  # Ratelimits specify on which physical interface, which maximum rate of traffic is allowed
+  ratelimits:
+  # The name of the interface visible with ip link show
+  - interface: vrf104009
+    # The maximum rate in MBits/s
+    rate: 10
+  # Internalprefixes defines a list of prefixes where the traffic going to, or coming from is considered internal, e.g. not leaving into external networks
+  # given the architecture picture above this would be:
+  internalprefixes:
+  - "1.2.3.0/24
+  - "172.17.0.0/16"
+  - "10.0.0.0/8"

Example ClusterwideNetworkPolicy:

apiVersion: metal-stack.io/v1
+kind: ClusterwideNetworkPolicy
+metadata:
+  namespace: firewall
+  name: clusterwidenetworkpolicy-sample
+spec:
+  egress:
+  - to:
+    - cidr: 1.1.0.0/24
+      except:
+      - 1.1.1.0/16
+    - cidr: 8.8.8.8/32
+    ports:
+    - protocol: UDP
+      port: 53
+    - protocol: TCP
+      port: 53

Status

Once the firewall-controller is running, it will report several statistics to the Firewall CRD Status: This can be inspected by running:

kubectl describe -n firewall firewall

The output would look like:

Status:
+  Last Run:  2020-06-17T13:18:58Z
+  Stats:
+    # Network traffic in bytes separated into external and internal in/out/total
+    Devices:
+      External:
+        In:     91696
+        Out:    34600
+        Total:  0
+      Internal:
+        In:     0
+        Out:    0
+        Total:  2678671
+    # IDS Statistics by interface
+    Idsstats:
+      vrf104009:
+        Drop:              1992
+        Invalidchecksums:  0
+        Packets:           4997276
+    # nftable rule statistics by rule name
+    Rules:
+      Accept:
+        BGP unnumbered:
+          Counter:
+            Bytes:    0
+            Packets:  0
+        SSH incoming connections:
+          Counter:
+            Bytes:    936
+            Packets:  16
+        accept established connections:
+          Counter:
+            Bytes:    21211168
+            Packets:  39785
+        accept icmp:
+          Counter:
+            Bytes:    0
+            Packets:  0
+        accept traffic for k8s service kube-system/vpn-shoot:
+          Counter:
+            Bytes:    360
+            Packets:  6
+      Drop:
+        drop invalid packets:
+          Counter:
+            Bytes:    52
+            Packets:  1
+        drop invalid packets from forwarding to prevent malicious activity:
+          Counter:
+            Bytes:    0
+            Packets:  0
+        drop invalid packets to prevent malicious activity:
+          Counter:
+            Bytes:    0
+            Packets:  0
+        drop packets with invalid ct state:
+          Counter:
+            Bytes:    0
+            Packets:  0
+        drop ping floods:
+          Counter:
+            Bytes:    0
+            Packets:  0
+      Other:
+        block bgp forward to machines:
+          Counter:
+            Bytes:    0
+            Packets:  0
+        count and log dropped packets:
+          Counter:
+            Bytes:    2528
+            Packets:  51
+        snat (networkid: internet):
+          Counter:
+            Bytes:    36960
+            Packets:  486

Prometheus integration

There are two exporters running on the firewall to report essential metrics from this machine:

  • node-exporter for machine specific metrics like cpu, ram and disk usage, see node-exporter for details.
  • nftables-exporter for nftables metrics, see nftables-exporter

Both exporters are exposed as services:

kubectl get svc -n firewall
+NAME                TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)    AGE
+nftables-exporter   ClusterIP   None         <none>        9630/TCP   13h
+node-exporter       ClusterIP   None         <none>        9100/TCP   13h

These services are in front of virtual endpoints:

kubectl get ep -n firewall
+NAME                ENDPOINTS         AGE
+nftables-exporter   10.3.164.1:9630   13h
+node-exporter       10.3.164.1:9100   13h

You can scrape these services in you prometheus installation to get the metrics.

To check you can run:

curl nftables-exporter.firewall.svc.cluster.local:9630/metrics
+curl node-exporter.firewall.svc.cluster.local:9100/metrics

Firewall Logs

It is also possible to tail for the dropped packets with the following command (install stern from stern ):

stern -n firewall drop

The output will look like:


+droptailer-6d556bd988-4g8gp droptailer 2020-06-17 13:23:27 +0000 UTC {"DPT":"4000","DST":"1.2.3.4","ID":"54321","IN":"vrf104009","LEN":"40","MAC":"ca:41:f9:80:fa:89:aa:bb:0e:62:8c:a6:08:00","OUT":"vlan179","PREC":"0x00","PROTO":"TCP","RES":"0x00","SPT":"38464","SRC":"2.3.4.5","SYN":"","TOS":"0x00","TTL":"236","URGP":"0","WINDOW":"65535","timestamp":"2020-06-17 13:23:27 +0000 UTC"}
+droptailer-6d556bd988-4g8gp droptailer 2020-06-17 13:23:34 +0000 UTC {"DPT":"2362","DST":"1.2.3.4","ID":"44545","IN":"vrf104009","LEN":"40","MAC":"ca:41:f9:80:fa:89:aa:bb:0e:62:8c:a6:08:00","OUT":"","PREC":"0x00","PROTO":"TCP","RES":"0x00","SPT":"40194","SRC":"2.3.4.5","SYN":"","TOS":"0x00","TTL":"242","URGP":"0","WINDOW":"1024","timestamp":"2020-06-17 13:23:34 +0000 UTC"}
+droptailer-6d556bd988-4g8gp droptailer 2020-06-17 13:23:30 +0000 UTC {"DPT":"650","DST":"1.2.3.4","ID":"12399","IN":"vrf104009","LEN":"40","MAC":"ca:41:f9:80:fa:89:aa:bb:0e:62:8c:a6:08:00","OUT":"vlan179","PREC":"0x00","PROTO":"TCP","RES":"0x00","SPT":"40194","SRC":"2.3.4.5","SYN":"","TOS":"0x00","TTL":"241","URGP":"0","WINDOW":"1024","timestamp":"2020-06-17 13:23:30 +0000 UTC"}
+droptailer-6d556bd988-4g8gp droptailer 2020-06-17 13:23:34 +0000 UTC {"DPT":"2362","DST":"1.2.3.4","ID":"44545","IN":"vrf104009","LEN":"40","MAC":"ca:41:f9:80:fa:89:aa:bb:0e:62:8c:a6:08:00","OUT":"","PREC":"0x00","PROTO":"TCP","RES":"0x00","SPT":"40194","SRC":"2.3.4.5","SYN":"","TOS":"0x00","TTL":"242","URGP":"0","WINDOW":"1024","timestamp":"2020-06-17 13:23:34 +0000 UTC"}
+droptailer-6d556bd988-4g8gp droptailer 2020-06-17 13:23:10 +0000 UTC {"DPT":"63351","DST":"1.2.3.4","ID":"11855","IN":"vrf104009","LEN":"40","MAC":"ca:41:f9:80:fa:89:aa:bb:0e:62:8c:a6:08:00","OUT":"vlan179","PREC":"0x00","PROTO":"TCP","RES":"0x00","SPT":"54589","SRC":"2.3.4.5","SYN":"","TOS":"0x00","TTL":"245","URGP":"0","WINDOW":"1024","timestamp":"2020-06-17 13:23:10 +0000 UTC"}
+droptailer-6d556bd988-4g8gp droptailer 2020-06-17 13:23:51 +0000 UTC {"DPT":"8002","DST":"1.2.3.4","ID":"17539","IN":"vrf104009","LEN":"40","MAC":"ca:41:f9:80:fa:89:aa:bb:0e:62:8c:a6:08:00","OUT":"","PREC":"0x00","PROTO":"TCP","RES":"0x00","SPT":"47615","SRC":"2.3.4.5","SYN":"","TOS":"0x08","TTL":"239","URGP":"0","WINDOW":"1024","timestamp":"2020-06-17 13:23:51 +0000 UTC"}

You can forward the droptailer logs to any log aggregation infrastructure you have in place.

Page Tree

diff --git a/v0.18.15/external/firewall-controller/architecture.svg b/v0.18.15/external/firewall-controller/architecture.svg new file mode 100644 index 0000000000..898a8b9db7 --- /dev/null +++ b/v0.18.15/external/firewall-controller/architecture.svg @@ -0,0 +1 @@ +
Worker Node
Worker Node
Firewall
Firewall
Worker VRF
Worker VRF
Firewall-Controller
Firewall-Controller
Internet VRF
Internet VRF
Legacy VRF
Legacy VRF
1.2.3.0/24
1.2.3.0/24
172.17.0.0/16
172.17.0.0/16
10.0.0.0/0
10.0.0.0/0
0.0.0.0/0
0.0.0.0/0
<service>
nftables-exporter
<service>...
<service>
node-exporter
<service>...
droptailer
droptailer
Worker Node
Worker Node
Worker Node
Worker Node
droptailer
droptailer
send nftables drops
<grpc>
send nftables drops...
Viewer does not support full SVG 1.1
\ No newline at end of file diff --git a/v0.18.15/external/metalctl/CONTRIBUTING/index.html b/v0.18.15/external/metalctl/CONTRIBUTING/index.html new file mode 100644 index 0000000000..64bc81ef4b --- /dev/null +++ b/v0.18.15/external/metalctl/CONTRIBUTING/index.html @@ -0,0 +1,2 @@ + +Contributing · metal-stack diff --git a/v0.18.15/external/metalctl/README/index.html b/v0.18.15/external/metalctl/README/index.html new file mode 100644 index 0000000000..0688032e20 --- /dev/null +++ b/v0.18.15/external/metalctl/README/index.html @@ -0,0 +1,38 @@ + +metalctl · metal-stack

metalctl

metalctl is the command line client to access the metal-api.

Installation

Download locations:

Installation on Linux

curl -LO https://github.com/metal-stack/metalctl/releases/latest/download/metalctl-linux-amd64
+chmod +x metalctl-linux-amd64
+sudo mv metalctl-linux-amd64 /usr/local/bin/metalctl

Installation on MacOS

For x86 based Macs:

curl -LO https://github.com/metal-stack/metalctl/releases/latest/download/metalctl-darwin-amd64
+chmod +x metalctl-darwin-amd64
+sudo mv metalctl-darwin-amd64 /usr/local/bin/metalctl

For Apple Silicon (M1) based Macs:

curl -LO https://github.com/metal-stack/metalctl/releases/latest/download/metalctl-darwin-arm64
+chmod +x metalctl-darwin-arm64
+sudo mv metalctl-darwin-arm64 /usr/local/bin/metalctl

Installation on Windows

curl -LO https://github.com/metal-stack/metalctl/releases/latest/download/metalctl-windows-amd64
+copy metalctl-windows-amd64 metalctl.exe

metalctl update

In order to keep your local metalctl installation up to date, you can update the binary like this:

metalctl update check
+latest version:v0.8.3 from:2020-08-13T11:55:14Z
+local  version:v0.8.2 from:2020-08-12T09:27:39Z
+metalctl is not up to date
+
+metalctl update do
+# a download with progress bar starts and replaces the binary. If the binary has root permissions please execute
+sudo metalctl update do
+# instead

Built from project

make
+sudo ln -sf $(pwd)/bin/metalctl /usr/local/bin/metalctl

Configuration

Set up auto-completion for metalctl, e.g. add to your ~/.bashrc:

source <(metalctl completion bash)

Set up metalctl config, by first creating the config folder (mkdir -p ~/.metalctl), then set the values according to your installation in ~/.metalctl/config.yaml:

---
+current: prod
+contexts:
+  prod:
+    url: https://api.metal-stack.io/metal
+    issuer_url: https://dex.metal-stack.io/dex
+    client_id: metal_client
+    client_secret: 456
+    hmac: YOUR_HMAC

Optional you can specify issuer_type: generic if you use other issuers as Dex, e.g. Keycloak (this will request scopes openid,profile,email):

contexts:
+  prod:
+    url: https://api.metal-stack.io/metal
+    issuer_url: https://keycloak.somedomain.io
+    issuer_type: generic
+    client_id: my-client-id
+    client_secret: my-secret

If you must specify special scopes for your issuer, you can use custom_scopes:

contexts:
+  prod:
+    url: https://api.metal-stack.io/metal
+    issuer_url: https://keycloak.somedomain.io
+    custom_scopes: roles,openid,profile,email
+    client_id: my-client-id
+    client_secret: my-secret

Available commands

Full documentation is generated out of the cobra command implementation with:

metalctl markdown

generated markdown is here and here

Development

For MacOS users, running the tests might throw an error because tests are utilizing go-mpatch in order to manipulate the time.Now function. The patch allows testing with fixed timestamps.

Instead, MacOS users can utilize the make test-in-docker target to execute the tests.

Page Tree

diff --git a/v0.18.15/external/metalctl/docs/metalctl/index.html b/v0.18.15/external/metalctl/docs/metalctl/index.html new file mode 100644 index 0000000000..b6383c2965 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl/index.html @@ -0,0 +1,25 @@ + +metalctl · metal-stack

metalctl

a cli to manage entities in the metal-stack api

Options

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+  -h, --help                   help for metalctl
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_audit/index.html b/v0.18.15/external/metalctl/docs/metalctl_audit/index.html new file mode 100644 index 0000000000..865545e4ff --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_audit/index.html @@ -0,0 +1,24 @@ + +metalctl audit · metal-stack

metalctl audit

manage audit trace entities

Synopsis

show audit traces of the api. feature must be enabled on server-side.

Options

  -h, --help   help for audit

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_audit_describe/index.html b/v0.18.15/external/metalctl/docs/metalctl_audit_describe/index.html new file mode 100644 index 0000000000..95936b335a --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_audit_describe/index.html @@ -0,0 +1,26 @@ + +metalctl audit describe · metal-stack

metalctl audit describe

describes the audit trace

metalctl audit describe <id> [flags]

Options

  -h, --help            help for describe
+      --phase string    phase of the audit trace. One of [request, response, single, error, opened, closed] (default "response")
+      --prettify-body   attempts to interpret the body as json and prettifies it

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_audit_list/index.html b/v0.18.15/external/metalctl/docs/metalctl_audit_list/index.html new file mode 100644 index 0000000000..cc70be0581 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_audit_list/index.html @@ -0,0 +1,41 @@ + +metalctl audit list · metal-stack

metalctl audit list

list all audit traces

metalctl audit list [flags]

Options

      --component string       component of the audit trace.
+      --detail string          detail of the audit trace. An HTTP method, unary or stream
+      --error string           error of the audit trace.
+      --forwarded-for string   forwarded for of the audit trace.
+      --from string            start of range of the audit traces. e.g. 1h, 10m, 2006-01-02 15:04:05 (default "1h")
+  -h, --help                   help for list
+      --limit int              limit the number of audit traces. (default 100)
+      --path string            api path of the audit trace.
+      --phase string           phase of the audit trace. One of [request, response, single, error, opened, closed]
+  -q, --query string           filters audit trace body payloads for the given text.
+      --remote-addr string     remote address of the audit trace.
+      --request-id string      request id of the audit trace.
+      --sort-by strings        sort by (comma separated) column(s), sort direction can be changed by appending :asc or :desc behind the column identifier. possible values: path|tenant|timestamp|user
+      --status-code int32      HTTP status code of the audit trace.
+      --tenant string          tenant of the audit trace.
+      --to string              end of range of the audit traces. e.g. 1h, 10m, 2006-01-02 15:04:05
+      --type string            type of the audit trace. One of [http, grpc, event].
+      --user string            user of the audit trace.

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_completion/index.html b/v0.18.15/external/metalctl/docs/metalctl_completion/index.html new file mode 100644 index 0000000000..28afef3bfe --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_completion/index.html @@ -0,0 +1,24 @@ + +metalctl completion · metal-stack

metalctl completion

Generate the autocompletion script for the specified shell

Synopsis

Generate the autocompletion script for metalctl for the specified shell. See each sub-command's help for details on how to use the generated script.

Options

  -h, --help   help for completion

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_completion_bash/index.html b/v0.18.15/external/metalctl/docs/metalctl_completion_bash/index.html new file mode 100644 index 0000000000..404d8c5cb3 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_completion_bash/index.html @@ -0,0 +1,25 @@ + +metalctl completion bash · metal-stack

metalctl completion bash

Generate the autocompletion script for bash

Synopsis

Generate the autocompletion script for the bash shell.

This script depends on the 'bash-completion' package. If it is not installed already, you can install it via your OS's package manager.

To load completions in your current shell session:

source <(metalctl completion bash)

To load completions for every new session, execute once:

Linux:

metalctl completion bash > /etc/bash_completion.d/metalctl

macOS:

metalctl completion bash > $(brew --prefix)/etc/bash_completion.d/metalctl

You will need to start a new shell for this setup to take effect.

metalctl completion bash

Options

  -h, --help              help for bash
+      --no-descriptions   disable completion descriptions

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_completion_fish/index.html b/v0.18.15/external/metalctl/docs/metalctl_completion_fish/index.html new file mode 100644 index 0000000000..6f2f7d5858 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_completion_fish/index.html @@ -0,0 +1,25 @@ + +metalctl completion fish · metal-stack

metalctl completion fish

Generate the autocompletion script for fish

Synopsis

Generate the autocompletion script for the fish shell.

To load completions in your current shell session:

metalctl completion fish | source

To load completions for every new session, execute once:

metalctl completion fish > ~/.config/fish/completions/metalctl.fish

You will need to start a new shell for this setup to take effect.

metalctl completion fish [flags]

Options

  -h, --help              help for fish
+      --no-descriptions   disable completion descriptions

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_completion_powershell/index.html b/v0.18.15/external/metalctl/docs/metalctl_completion_powershell/index.html new file mode 100644 index 0000000000..3c65b546b5 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_completion_powershell/index.html @@ -0,0 +1,25 @@ + +metalctl completion powershell · metal-stack

metalctl completion powershell

Generate the autocompletion script for powershell

Synopsis

Generate the autocompletion script for powershell.

To load completions in your current shell session:

metalctl completion powershell | Out-String | Invoke-Expression

To load completions for every new session, add the output of the above command to your powershell profile.

metalctl completion powershell [flags]

Options

  -h, --help              help for powershell
+      --no-descriptions   disable completion descriptions

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_completion_zsh/index.html b/v0.18.15/external/metalctl/docs/metalctl_completion_zsh/index.html new file mode 100644 index 0000000000..75dd0ba382 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_completion_zsh/index.html @@ -0,0 +1,25 @@ + +metalctl completion zsh · metal-stack

metalctl completion zsh

Generate the autocompletion script for zsh

Synopsis

Generate the autocompletion script for the zsh shell.

If shell completion is not already enabled in your environment you will need to enable it. You can execute the following once:

echo "autoload -U compinit; compinit" >> ~/.zshrc

To load completions in your current shell session:

source <(metalctl completion zsh)

To load completions for every new session, execute once:

Linux:

metalctl completion zsh > "${fpath[1]}/_metalctl"

macOS:

metalctl completion zsh > $(brew --prefix)/share/zsh/site-functions/_metalctl

You will need to start a new shell for this setup to take effect.

metalctl completion zsh [flags]

Options

  -h, --help              help for zsh
+      --no-descriptions   disable completion descriptions

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_context/index.html b/v0.18.15/external/metalctl/docs/metalctl_context/index.html new file mode 100644 index 0000000000..41dd5cc86b --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_context/index.html @@ -0,0 +1,40 @@ + +metalctl context · metal-stack

metalctl context

manage metalctl context

Synopsis

context defines the backend to which metalctl talks to. You can switch back and forth with "-"

metalctl context <name> [flags]

Examples


+~/.metalctl/config.yaml
+---
+current: prod
+contexts:
+  prod:
+    url: https://api.metal-stack.io/metal
+    issuer_url: https://dex.metal-stack.io/dex
+    client_id: metal_client
+    client_secret: 456
+  dev:
+    url: https://api.metal-stack.dev/metal
+    issuer_url: https://dex.metal-stack.dev/dex
+    client_id: metal_client
+    client_secret: 123
+...
+

Options

  -h, --help   help for context

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_context_short/index.html b/v0.18.15/external/metalctl/docs/metalctl_context_short/index.html new file mode 100644 index 0000000000..f2f9777ba1 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_context_short/index.html @@ -0,0 +1,24 @@ + +metalctl context short · metal-stack

metalctl context short

only show the default context name

metalctl context short [flags]

Options

  -h, --help   help for short

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_filesystemlayout/index.html b/v0.18.15/external/metalctl/docs/metalctl_filesystemlayout/index.html new file mode 100644 index 0000000000..87e04d0a8f --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_filesystemlayout/index.html @@ -0,0 +1,24 @@ + +metalctl filesystemlayout · metal-stack

metalctl filesystemlayout

manage filesystemlayout entities

Synopsis

a filesystemlayout is a specification how the disks in a machine are partitioned, formatted and mounted.

Options

  -h, --help   help for filesystemlayout

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_filesystemlayout_apply/index.html b/v0.18.15/external/metalctl/docs/metalctl_filesystemlayout_apply/index.html new file mode 100644 index 0000000000..f0addb2bdb --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_filesystemlayout_apply/index.html @@ -0,0 +1,39 @@ + +metalctl filesystemlayout apply · metal-stack

metalctl filesystemlayout apply

applies one or more filesystemlayouts from a given file

metalctl filesystemlayout apply [flags]

Options

      --bulk-output             when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.
+  -f, --file string             filename of the create or update request in yaml format, or - for stdin.
+                                
+                                Example:
+                                $ metalctl filesystemlayout describe filesystemlayout-1 -o yaml > filesystemlayout.yaml
+                                $ vi filesystemlayout.yaml
+                                $ # either via stdin
+                                $ cat filesystemlayout.yaml | metalctl filesystemlayout apply -f -
+                                $ # or via file
+                                $ metalctl filesystemlayout apply -f filesystemlayout.yaml
+                                
+                                the file can also contain multiple documents and perform a bulk operation.
+                                	
+  -h, --help                    help for apply
+      --skip-security-prompts   skips security prompt for bulk operations
+      --timestamps              when used with --file (bulk operation): prints timestamps in-between the operations

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_filesystemlayout_create/index.html b/v0.18.15/external/metalctl/docs/metalctl_filesystemlayout_create/index.html new file mode 100644 index 0000000000..d0928c37ed --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_filesystemlayout_create/index.html @@ -0,0 +1,39 @@ + +metalctl filesystemlayout create · metal-stack

metalctl filesystemlayout create

creates the filesystemlayout

metalctl filesystemlayout create [flags]

Options

      --bulk-output             when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.
+  -f, --file string             filename of the create or update request in yaml format, or - for stdin.
+                                
+                                Example:
+                                $ metalctl filesystemlayout describe filesystemlayout-1 -o yaml > filesystemlayout.yaml
+                                $ vi filesystemlayout.yaml
+                                $ # either via stdin
+                                $ cat filesystemlayout.yaml | metalctl filesystemlayout create -f -
+                                $ # or via file
+                                $ metalctl filesystemlayout create -f filesystemlayout.yaml
+                                
+                                the file can also contain multiple documents and perform a bulk operation.
+                                	
+  -h, --help                    help for create
+      --skip-security-prompts   skips security prompt for bulk operations
+      --timestamps              when used with --file (bulk operation): prints timestamps in-between the operations

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_filesystemlayout_delete/index.html b/v0.18.15/external/metalctl/docs/metalctl_filesystemlayout_delete/index.html new file mode 100644 index 0000000000..a9dcb07449 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_filesystemlayout_delete/index.html @@ -0,0 +1,39 @@ + +metalctl filesystemlayout delete · metal-stack

metalctl filesystemlayout delete

deletes the filesystemlayout

metalctl filesystemlayout delete <id> [flags]

Options

      --bulk-output             when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.
+  -f, --file string             filename of the create or update request in yaml format, or - for stdin.
+                                
+                                Example:
+                                $ metalctl filesystemlayout describe filesystemlayout-1 -o yaml > filesystemlayout.yaml
+                                $ vi filesystemlayout.yaml
+                                $ # either via stdin
+                                $ cat filesystemlayout.yaml | metalctl filesystemlayout delete <id> -f -
+                                $ # or via file
+                                $ metalctl filesystemlayout delete <id> -f filesystemlayout.yaml
+                                
+                                the file can also contain multiple documents and perform a bulk operation.
+                                	
+  -h, --help                    help for delete
+      --skip-security-prompts   skips security prompt for bulk operations
+      --timestamps              when used with --file (bulk operation): prints timestamps in-between the operations

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_filesystemlayout_describe/index.html b/v0.18.15/external/metalctl/docs/metalctl_filesystemlayout_describe/index.html new file mode 100644 index 0000000000..9e84fc8c1f --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_filesystemlayout_describe/index.html @@ -0,0 +1,24 @@ + +metalctl filesystemlayout describe · metal-stack

metalctl filesystemlayout describe

describes the filesystemlayout

metalctl filesystemlayout describe <id> [flags]

Options

  -h, --help   help for describe

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_filesystemlayout_edit/index.html b/v0.18.15/external/metalctl/docs/metalctl_filesystemlayout_edit/index.html new file mode 100644 index 0000000000..77cf43e3ff --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_filesystemlayout_edit/index.html @@ -0,0 +1,24 @@ + +metalctl filesystemlayout edit · metal-stack

metalctl filesystemlayout edit

edit the filesystemlayout through an editor and update

metalctl filesystemlayout edit <id> [flags]

Options

  -h, --help   help for edit

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_filesystemlayout_list/index.html b/v0.18.15/external/metalctl/docs/metalctl_filesystemlayout_list/index.html new file mode 100644 index 0000000000..e1222faa11 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_filesystemlayout_list/index.html @@ -0,0 +1,25 @@ + +metalctl filesystemlayout list · metal-stack

metalctl filesystemlayout list

list all filesystemlayouts

metalctl filesystemlayout list [flags]

Options

  -h, --help              help for list
+      --sort-by strings   sort by (comma separated) column(s), sort direction can be changed by appending :asc or :desc behind the column identifier. possible values: description|id|name

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_filesystemlayout_match/index.html b/v0.18.15/external/metalctl/docs/metalctl_filesystemlayout_match/index.html new file mode 100644 index 0000000000..c0d5ff392b --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_filesystemlayout_match/index.html @@ -0,0 +1,26 @@ + +metalctl filesystemlayout match · metal-stack

metalctl filesystemlayout match

check if a machine satisfies all disk requirements of a given filesystemlayout

metalctl filesystemlayout match [flags]

Options

      --filesystemlayout string   filesystemlayout id to check against [required]
+  -h, --help                      help for match
+      --machine string            machine id to check for match [required]

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_filesystemlayout_try/index.html b/v0.18.15/external/metalctl/docs/metalctl_filesystemlayout_try/index.html new file mode 100644 index 0000000000..0081d36cde --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_filesystemlayout_try/index.html @@ -0,0 +1,26 @@ + +metalctl filesystemlayout try · metal-stack

metalctl filesystemlayout try

try to detect a filesystem by given size and image

metalctl filesystemlayout try [flags]

Options

  -h, --help           help for try
+      --image string   image to try
+      --size string    size to try

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_filesystemlayout_update/index.html b/v0.18.15/external/metalctl/docs/metalctl_filesystemlayout_update/index.html new file mode 100644 index 0000000000..c15568af18 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_filesystemlayout_update/index.html @@ -0,0 +1,39 @@ + +metalctl filesystemlayout update · metal-stack

metalctl filesystemlayout update

updates the filesystemlayout

metalctl filesystemlayout update [flags]

Options

      --bulk-output             when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.
+  -f, --file string             filename of the create or update request in yaml format, or - for stdin.
+                                
+                                Example:
+                                $ metalctl filesystemlayout describe filesystemlayout-1 -o yaml > filesystemlayout.yaml
+                                $ vi filesystemlayout.yaml
+                                $ # either via stdin
+                                $ cat filesystemlayout.yaml | metalctl filesystemlayout update -f -
+                                $ # or via file
+                                $ metalctl filesystemlayout update -f filesystemlayout.yaml
+                                
+                                the file can also contain multiple documents and perform a bulk operation.
+                                	
+  -h, --help                    help for update
+      --skip-security-prompts   skips security prompt for bulk operations
+      --timestamps              when used with --file (bulk operation): prints timestamps in-between the operations

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_firewall/index.html b/v0.18.15/external/metalctl/docs/metalctl_firewall/index.html new file mode 100644 index 0000000000..45576fdf16 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_firewall/index.html @@ -0,0 +1,24 @@ + +metalctl firewall · metal-stack

metalctl firewall

manage firewall entities

Synopsis

firewalls are used to establish network connectivity between metal-stack networks. firewalls are similar to machines but are managed by the provider. almost every command of the machine command subset works on firewalls, too.

Options

  -h, --help   help for firewall

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_firewall_create/index.html b/v0.18.15/external/metalctl/docs/metalctl_firewall_create/index.html new file mode 100644 index 0000000000..f7f499403f --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_firewall_create/index.html @@ -0,0 +1,110 @@ + +metalctl firewall create · metal-stack

metalctl firewall create

creates the firewall

metalctl firewall create [flags]

Options

      --bulk-output                  when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.
+  -d, --description string           Description of the firewall to create. [optional]
+  -f, --file string                  filename of the create or update request in yaml format, or - for stdin.
+                                     
+                                     Example:
+                                     $ metalctl firewall describe firewall-1 -o yaml > firewall.yaml
+                                     $ vi firewall.yaml
+                                     $ # either via stdin
+                                     $ cat firewall.yaml | metalctl firewall create -f -
+                                     $ # or via file
+                                     $ metalctl firewall create -f firewall.yaml
+                                     
+                                     the file can also contain multiple documents and perform a bulk operation.
+                                     	
+      --filesystemlayout string      Filesystemlayout to use during machine installation. [optional]
+      --firewall-rules-file string   firewall rules specified in a yaml file
+                                     
+                                     Example:
+                                     
+                                     $ metalctl firewall create ..mandatory args.. --firewall-rules-file rules.yaml
+                                     
+                                     rules.yaml
+                                     ---
+                                     egress:
+                                     - comment: allow outgoing https
+                                       ports:
+                                       - 443
+                                       protocol: TCP
+                                       to:
+                                       - 0.0.0.0/0
+                                     - comment: allow outgoing dns via tcp
+                                       ports:
+                                       - 53
+                                       protocol: TCP
+                                       to:
+                                       - 0.0.0.0/0
+                                     - comment: allow outgoing dns and ntp via udp
+                                       ports:
+                                       - 53
+                                       - 123
+                                       protocol: UDP
+                                       to:
+                                       - 0.0.0.0/0
+                                     ingress:
+                                     - comment: allow incoming ssh only to one ip
+                                       ports:
+                                       - 22
+                                       protocol: TCP
+                                       from:
+                                       - 0.0.0.0/0
+                                       - 1.2.3.4/32
+                                       to:
+                                       - 212.34.83.19/32
+                                     - comment: allow incoming https to all targets
+                                       ports:
+                                       - 80
+                                       - 433
+                                       protocol: TCP
+                                       from:
+                                       - 0.0.0.0/0
+                                     
+                                     
+  -h, --help                         help for create
+  -H, --hostname string              Hostname of the firewall. [required]
+  -I, --id string                    ID of a specific firewall to allocate, if given, size and partition are ignored. Need to be set to reserved (--reserve) state before.
+  -i, --image string                 OS Image to install. [required]
+      --ips strings                  Sets the firewall's IP address. Usage: [--ips[=IPV4-ADDRESS[,IPV4-ADDRESS]...]]...
+                                     IPV4-ADDRESS specifies the IPv4 address to add.
+                                     It can only be used in conjunction with --networks.
+  -n, --name string                  Name of the firewall. [optional]
+      --networks strings             Adds network(s). Usage: --networks NETWORK[:MODE][,NETWORK[:MODE]]... [--networks NETWORK[:MODE][,
+                                     NETWORK[:MODE]]...]...
+                                     NETWORK specifies the id of an existing network.
+                                     MODE can be omitted or one of:
+                                     	auto	IP address is automatically acquired from the given network
+                                     	noauto	No automatic IP address acquisition
+  -S, --partition string             partition/datacenter where the firewall is created. [required, except for reserved machines]
+  -P, --project string               Project where the firewall should belong to. [required]
+  -s, --size string                  Size of the firewall. [required, except for reserved machines]
+      --skip-security-prompts        skips security prompt for bulk operations
+  -p, --sshpublickey string          SSH public key for access via ssh and console. [optional]
+                                     Can be either the public key as string, or pointing to the public key file to use e.g.: "@~/.ssh/id_rsa.pub".
+                                     If ~/.ssh/[id_ed25519.pub | id_rsa.pub | id_dsa.pub] is present it will be picked as default, matching the first one in this order.
+      --tags strings                 tags to add to the firewall, use it like: --tags "tag1,tag2" or --tags "tag3".
+      --timestamps                   when used with --file (bulk operation): prints timestamps in-between the operations
+      --userdata string              cloud-init.io compatible userdata. [optional]
+                                     Can be either the userdata as string, or pointing to the userdata file to use e.g.: "@/tmp/userdata.cfg".

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_firewall_describe/index.html b/v0.18.15/external/metalctl/docs/metalctl_firewall_describe/index.html new file mode 100644 index 0000000000..b8cfc389be --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_firewall_describe/index.html @@ -0,0 +1,24 @@ + +metalctl firewall describe · metal-stack

metalctl firewall describe

describes the firewall

metalctl firewall describe <id> [flags]

Options

  -h, --help   help for describe

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_firewall_list/index.html b/v0.18.15/external/metalctl/docs/metalctl_firewall_list/index.html new file mode 100644 index 0000000000..0481a21b54 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_firewall_list/index.html @@ -0,0 +1,34 @@ + +metalctl firewall list · metal-stack

metalctl firewall list

list all firewalls

metalctl firewall list [flags]

Options

  -h, --help               help for list
+      --hostname string    allocation hostname to filter [optional]
+      --id string          ID to filter [optional]
+      --image string       allocation image to filter [optional]
+      --mac string         mac to filter [optional]
+      --name string        allocation name to filter [optional]
+      --partition string   partition to filter [optional]
+      --project string     allocation project to filter [optional]
+      --size string        size to filter [optional]
+      --sort-by strings    sort by (comma separated) column(s), sort direction can be changed by appending :asc or :desc behind the column identifier. possible values: age|event|id|image|liveliness|partition|project|size|when
+      --tags strings       tags to filter, use it like: --tags "tag1,tag2" or --tags "tag3".

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_firewall_ssh/index.html b/v0.18.15/external/metalctl/docs/metalctl_firewall_ssh/index.html new file mode 100644 index 0000000000..cf09e8bae4 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_firewall_ssh/index.html @@ -0,0 +1,25 @@ + +metalctl firewall ssh · metal-stack

metalctl firewall ssh

SSH to a firewall

Synopsis

SSH to a firewall via VPN.

metalctl firewall ssh <firewall ID> [flags]

Options

  -h, --help              help for ssh
+  -i, --identity string   specify identity file to SSH to the firewall like: -i path/to/id_rsa (default "~/.ssh/id_rsa")

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_firmware/index.html b/v0.18.15/external/metalctl/docs/metalctl_firmware/index.html new file mode 100644 index 0000000000..2c280c7a15 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_firmware/index.html @@ -0,0 +1,24 @@ + +metalctl firmware · metal-stack

metalctl firmware

manage firmwares

Synopsis

list, upload and remove firmwares.

Options

  -h, --help   help for firmware

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_firmware_delete/index.html b/v0.18.15/external/metalctl/docs/metalctl_firmware_delete/index.html new file mode 100644 index 0000000000..2aa0af5654 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_firmware_delete/index.html @@ -0,0 +1,28 @@ + +metalctl firmware delete · metal-stack

metalctl firmware delete

delete a firmware

Synopsis

deletes the specified firmware.

metalctl firmware delete [flags]

Options

      --board string      the board type (required)
+  -h, --help              help for delete
+      --kind string       the firmware kind [bmc|bios] (required)
+      --revision string   the firmware revision (required)
+      --vendor string     the vendor (required)

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_firmware_list/index.html b/v0.18.15/external/metalctl/docs/metalctl_firmware_list/index.html new file mode 100644 index 0000000000..e05c7f8b87 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_firmware_list/index.html @@ -0,0 +1,28 @@ + +metalctl firmware list · metal-stack

metalctl firmware list

list firmwares

Synopsis

lists all available firmwares matching the given criteria.

metalctl firmware list [flags]

Options

      --board string       the board type
+  -h, --help               help for list
+      --kind string        the firmware kind [bmc|bios]
+      --machineid string   the machine id (ignores vendor and board flags)
+      --vendor string      the vendor

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_firmware_upload/index.html b/v0.18.15/external/metalctl/docs/metalctl_firmware_upload/index.html new file mode 100644 index 0000000000..c72161c938 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_firmware_upload/index.html @@ -0,0 +1,24 @@ + +metalctl firmware upload · metal-stack

metalctl firmware upload

upload a firmware

Options

  -h, --help   help for upload

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_firmware_upload_bios/index.html b/v0.18.15/external/metalctl/docs/metalctl_firmware_upload_bios/index.html new file mode 100644 index 0000000000..05fcf45dda --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_firmware_upload_bios/index.html @@ -0,0 +1,27 @@ + +metalctl firmware upload bios · metal-stack

metalctl firmware upload bios

upload a BIOS firmware

Synopsis

the given BIOS firmware file will be uploaded and tagged as given revision.

metalctl firmware upload bios <file> [flags]

Options

      --board string      the board type (required)
+  -h, --help              help for bios
+      --revision string   the BIOS firmware revision (required)
+      --vendor string     the vendor (required)

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_firmware_upload_bmc/index.html b/v0.18.15/external/metalctl/docs/metalctl_firmware_upload_bmc/index.html new file mode 100644 index 0000000000..c9e0a8f671 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_firmware_upload_bmc/index.html @@ -0,0 +1,27 @@ + +metalctl firmware upload bmc · metal-stack

metalctl firmware upload bmc

upload a BMC firmware

Synopsis

the given BMC firmware file will be uploaded and tagged as given revision.

metalctl firmware upload bmc <file> [flags]

Options

      --board string      the board type (required)
+  -h, --help              help for bmc
+      --revision string   the BMC firmware revision (required)
+      --vendor string     the vendor (required)

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_health/index.html b/v0.18.15/external/metalctl/docs/metalctl_health/index.html new file mode 100644 index 0000000000..0d8a6d014b --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_health/index.html @@ -0,0 +1,24 @@ + +metalctl health · metal-stack

metalctl health

shows the server health

metalctl health [flags]

Options

  -h, --help   help for health

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

  • metalctl - a cli to manage entities in the metal-stack api
diff --git a/v0.18.15/external/metalctl/docs/metalctl_image/index.html b/v0.18.15/external/metalctl/docs/metalctl_image/index.html new file mode 100644 index 0000000000..23a7b0977b --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_image/index.html @@ -0,0 +1,24 @@ + +metalctl image · metal-stack

metalctl image

manage image entities

Synopsis

os images available to be installed on machines.

Options

  -h, --help   help for image

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_image_apply/index.html b/v0.18.15/external/metalctl/docs/metalctl_image_apply/index.html new file mode 100644 index 0000000000..125363ce9c --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_image_apply/index.html @@ -0,0 +1,39 @@ + +metalctl image apply · metal-stack

metalctl image apply

applies one or more images from a given file

metalctl image apply [flags]

Options

      --bulk-output             when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.
+  -f, --file string             filename of the create or update request in yaml format, or - for stdin.
+                                
+                                Example:
+                                $ metalctl image describe image-1 -o yaml > image.yaml
+                                $ vi image.yaml
+                                $ # either via stdin
+                                $ cat image.yaml | metalctl image apply -f -
+                                $ # or via file
+                                $ metalctl image apply -f image.yaml
+                                
+                                the file can also contain multiple documents and perform a bulk operation.
+                                	
+  -h, --help                    help for apply
+      --skip-security-prompts   skips security prompt for bulk operations
+      --timestamps              when used with --file (bulk operation): prints timestamps in-between the operations

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_image_create/index.html b/v0.18.15/external/metalctl/docs/metalctl_image_create/index.html new file mode 100644 index 0000000000..53ad12704d --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_image_create/index.html @@ -0,0 +1,44 @@ + +metalctl image create · metal-stack

metalctl image create

creates the image

metalctl image create [flags]

Options

      --bulk-output             when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.
+  -d, --description string      Description of the image.
+      --features strings        features of the image, can be one of machine|firewall
+  -f, --file string             filename of the create or update request in yaml format, or - for stdin.
+                                
+                                Example:
+                                $ metalctl image describe image-1 -o yaml > image.yaml
+                                $ vi image.yaml
+                                $ # either via stdin
+                                $ cat image.yaml | metalctl image create -f -
+                                $ # or via file
+                                $ metalctl image create -f image.yaml
+                                
+                                the file can also contain multiple documents and perform a bulk operation.
+                                	
+  -h, --help                    help for create
+      --id string               ID of the image.
+  -n, --name string             Name of the image.
+      --skip-security-prompts   skips security prompt for bulk operations
+      --timestamps              when used with --file (bulk operation): prints timestamps in-between the operations
+      --url string              url of the image.

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_image_delete/index.html b/v0.18.15/external/metalctl/docs/metalctl_image_delete/index.html new file mode 100644 index 0000000000..820c3f0d2e --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_image_delete/index.html @@ -0,0 +1,39 @@ + +metalctl image delete · metal-stack

metalctl image delete

deletes the image

metalctl image delete <id> [flags]

Options

      --bulk-output             when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.
+  -f, --file string             filename of the create or update request in yaml format, or - for stdin.
+                                
+                                Example:
+                                $ metalctl image describe image-1 -o yaml > image.yaml
+                                $ vi image.yaml
+                                $ # either via stdin
+                                $ cat image.yaml | metalctl image delete <id> -f -
+                                $ # or via file
+                                $ metalctl image delete <id> -f image.yaml
+                                
+                                the file can also contain multiple documents and perform a bulk operation.
+                                	
+  -h, --help                    help for delete
+      --skip-security-prompts   skips security prompt for bulk operations
+      --timestamps              when used with --file (bulk operation): prints timestamps in-between the operations

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_image_describe/index.html b/v0.18.15/external/metalctl/docs/metalctl_image_describe/index.html new file mode 100644 index 0000000000..5a8b84a0f6 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_image_describe/index.html @@ -0,0 +1,24 @@ + +metalctl image describe · metal-stack

metalctl image describe

describes the image

metalctl image describe <id> [flags]

Options

  -h, --help   help for describe

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_image_edit/index.html b/v0.18.15/external/metalctl/docs/metalctl_image_edit/index.html new file mode 100644 index 0000000000..097247e4fc --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_image_edit/index.html @@ -0,0 +1,24 @@ + +metalctl image edit · metal-stack

metalctl image edit

edit the image through an editor and update

metalctl image edit <id> [flags]

Options

  -h, --help   help for edit

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_image_list/index.html b/v0.18.15/external/metalctl/docs/metalctl_image_list/index.html new file mode 100644 index 0000000000..fd42e2a472 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_image_list/index.html @@ -0,0 +1,32 @@ + +metalctl image list · metal-stack

metalctl image list

list all images

metalctl image list [flags]

Options

      --classification string   Classification of this image.
+      --features string         Features of this image.
+  -h, --help                    help for list
+      --id string               ID of the image.
+      --name string             Name of the image.
+      --os string               OS derivate of this image.
+      --show-usage              show from how many allocated machines every image is used
+      --sort-by strings         sort by (comma separated) column(s), sort direction can be changed by appending :asc or :desc behind the column identifier. possible values: classification|description|expiration|id|name
+      --version string          Version of this image.

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_image_update/index.html b/v0.18.15/external/metalctl/docs/metalctl_image_update/index.html new file mode 100644 index 0000000000..1f26277c81 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_image_update/index.html @@ -0,0 +1,39 @@ + +metalctl image update · metal-stack

metalctl image update

updates the image

metalctl image update [flags]

Options

      --bulk-output             when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.
+  -f, --file string             filename of the create or update request in yaml format, or - for stdin.
+                                
+                                Example:
+                                $ metalctl image describe image-1 -o yaml > image.yaml
+                                $ vi image.yaml
+                                $ # either via stdin
+                                $ cat image.yaml | metalctl image update -f -
+                                $ # or via file
+                                $ metalctl image update -f image.yaml
+                                
+                                the file can also contain multiple documents and perform a bulk operation.
+                                	
+  -h, --help                    help for update
+      --skip-security-prompts   skips security prompt for bulk operations
+      --timestamps              when used with --file (bulk operation): prints timestamps in-between the operations

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_login/index.html b/v0.18.15/external/metalctl/docs/metalctl_login/index.html new file mode 100644 index 0000000000..06fd197284 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_login/index.html @@ -0,0 +1,25 @@ + +metalctl login · metal-stack

metalctl login

login user and receive token

Synopsis

login and receive token that will be used to authenticate commands.

metalctl login [flags]

Options

  -h, --help         help for login
+      --print-only   If true, the token is printed to stdout

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

  • metalctl - a cli to manage entities in the metal-stack api
diff --git a/v0.18.15/external/metalctl/docs/metalctl_logout/index.html b/v0.18.15/external/metalctl/docs/metalctl_logout/index.html new file mode 100644 index 0000000000..dc7d74f871 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_logout/index.html @@ -0,0 +1,24 @@ + +metalctl logout · metal-stack

metalctl logout

logout user from OIDC SSO session

metalctl logout [flags]

Options

  -h, --help   help for logout

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

  • metalctl - a cli to manage entities in the metal-stack api
diff --git a/v0.18.15/external/metalctl/docs/metalctl_machine/index.html b/v0.18.15/external/metalctl/docs/metalctl_machine/index.html new file mode 100644 index 0000000000..eebb411df2 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_machine/index.html @@ -0,0 +1,24 @@ + +metalctl machine · metal-stack

metalctl machine

manage machine entities

Synopsis

a machine is a bare metal server provisioned through metal-stack that is intended to run user workload.

Options

  -h, --help   help for machine

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_machine_apply/index.html b/v0.18.15/external/metalctl/docs/metalctl_machine_apply/index.html new file mode 100644 index 0000000000..af128102a7 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_machine_apply/index.html @@ -0,0 +1,39 @@ + +metalctl machine apply · metal-stack

metalctl machine apply

applies one or more machines from a given file

metalctl machine apply [flags]

Options

      --bulk-output             when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.
+  -f, --file string             filename of the create or update request in yaml format, or - for stdin.
+                                
+                                Example:
+                                $ metalctl machine describe machine-1 -o yaml > machine.yaml
+                                $ vi machine.yaml
+                                $ # either via stdin
+                                $ cat machine.yaml | metalctl machine apply -f -
+                                $ # or via file
+                                $ metalctl machine apply -f machine.yaml
+                                
+                                the file can also contain multiple documents and perform a bulk operation.
+                                	
+  -h, --help                    help for apply
+      --skip-security-prompts   skips security prompt for bulk operations
+      --timestamps              when used with --file (bulk operation): prints timestamps in-between the operations

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_machine_console/index.html b/v0.18.15/external/metalctl/docs/metalctl_machine_console/index.html new file mode 100644 index 0000000000..c25141d530 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_machine_console/index.html @@ -0,0 +1,29 @@ + +metalctl machine console · metal-stack

metalctl machine console

console access to a machine

Synopsis

console access to a machine, machine must be created with a ssh public key, authentication is done with your private key. In case the machine did not register properly a direct ipmi console access is available via the –ipmi flag. This is only for administrative access.

metalctl machine console <machine ID> [flags]

Options

      --admin                 authenticate as admin (admin only).
+  -h, --help                  help for console
+      --ipmi                  use ipmitool with direct network access (admin only).
+      --ipmipassword string   overwrite ipmi password (admin only).
+      --ipmiuser string       overwrite ipmi user (admin only).
+  -i, --sshidentity string    SSH key file, if not given the default ssh key will be used if present [optional].

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_machine_consolepassword/index.html b/v0.18.15/external/metalctl/docs/metalctl_machine_consolepassword/index.html new file mode 100644 index 0000000000..61d2013b90 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_machine_consolepassword/index.html @@ -0,0 +1,25 @@ + +metalctl machine consolepassword · metal-stack

metalctl machine consolepassword

fetch the consolepassword for a machine

metalctl machine consolepassword <machine ID> [flags]

Options

  -h, --help            help for consolepassword
+      --reason string   a short description why access to the consolepassword is required

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_machine_create/index.html b/v0.18.15/external/metalctl/docs/metalctl_machine_create/index.html new file mode 100644 index 0000000000..ff46672da0 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_machine_create/index.html @@ -0,0 +1,96 @@ + +metalctl machine create · metal-stack

metalctl machine create

creates the machine

metalctl machine create [flags]

Examples

machine create can be done in two different ways:
+
+- default with automatic allocation:
+
+	metalctl machine create \
+		--hostname worker01 \
+		--name worker \
+		--image ubuntu-18.04 \ # query available with: metalctl image list
+		--size t1-small-x86 \  # query available with: metalctl size list
+		--partition test \     # query available with: metalctl partition list
+		--project cluster01 \
+		--sshpublickey "@~/.ssh/id_rsa.pub"
+
+- for metal administration with reserved machines:
+
+	reserve a machine you want to allocate:
+
+	metalctl machine reserve 00000000-0000-0000-0000-0cc47ae54694 --description "blocked for maintenance"
+
+	allocate this machine:
+
+	metalctl machine create \
+		--hostname worker01 \
+		--name worker \
+		--image ubuntu-18.04 \ # query available with: metalctl image list
+		--project cluster01 \
+		--sshpublickey "@~/.ssh/id_rsa.pub" \
+		--id 00000000-0000-0000-0000-0cc47ae54694
+
+after you do not want to use this machine exclusive, remove the reservation:
+
+metalctl machine reserve 00000000-0000-0000-0000-0cc47ae54694 --remove
+
+Once created the machine installation can not be modified anymore.
+

Options

      --bulk-output               when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.
+  -d, --description string        Description of the machine to create. [optional]
+  -f, --file string               filename of the create or update request in yaml format, or - for stdin.
+                                  
+                                  Example:
+                                  $ metalctl machine describe machine-1 -o yaml > machine.yaml
+                                  $ vi machine.yaml
+                                  $ # either via stdin
+                                  $ cat machine.yaml | metalctl machine create -f -
+                                  $ # or via file
+                                  $ metalctl machine create -f machine.yaml
+                                  
+                                  the file can also contain multiple documents and perform a bulk operation.
+                                  	
+      --filesystemlayout string   Filesystemlayout to use during machine installation. [optional]
+  -h, --help                      help for create
+  -H, --hostname string           Hostname of the machine. [required]
+  -I, --id string                 ID of a specific machine to allocate, if given, size and partition are ignored. Need to be set to reserved (--reserve) state before.
+  -i, --image string              OS Image to install. [required]
+      --ips strings               Sets the machine's IP address. Usage: [--ips[=IPV4-ADDRESS[,IPV4-ADDRESS]...]]...
+                                  IPV4-ADDRESS specifies the IPv4 address to add.
+                                  It can only be used in conjunction with --networks.
+  -n, --name string               Name of the machine. [optional]
+      --networks strings          Adds a network. Usage: [--networks NETWORK[:MODE][,NETWORK[:MODE]]...]...
+                                  NETWORK specifies the name or id of an existing network.
+                                  MODE cane be omitted or one of:
+                                  	auto	IP address is automatically acquired from the given network
+                                  	noauto	IP address for the given network must be provided via --ips
+  -S, --partition string          partition/datacenter where the machine is created. [required, except for reserved machines]
+  -P, --project string            Project where the machine should belong to. [required]
+  -s, --size string               Size of the machine. [required, except for reserved machines]
+      --skip-security-prompts     skips security prompt for bulk operations
+  -p, --sshpublickey string       SSH public key for access via ssh and console. [optional]
+                                  Can be either the public key as string, or pointing to the public key file to use e.g.: "@~/.ssh/id_rsa.pub".
+                                  If ~/.ssh/[id_ed25519.pub | id_rsa.pub | id_dsa.pub] is present it will be picked as default, matching the first one in this order.
+      --tags strings              tags to add to the machine, use it like: --tags "tag1,tag2" or --tags "tag3".
+      --timestamps                when used with --file (bulk operation): prints timestamps in-between the operations
+      --userdata string           cloud-init.io compatible userdata. [optional]
+                                  Can be either the userdata as string, or pointing to the userdata file to use e.g.: "@/tmp/userdata.cfg".

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_machine_delete/index.html b/v0.18.15/external/metalctl/docs/metalctl_machine_delete/index.html new file mode 100644 index 0000000000..487bc5a136 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_machine_delete/index.html @@ -0,0 +1,40 @@ + +metalctl machine delete · metal-stack

metalctl machine delete

deletes the machine

Synopsis

delete a machine and destroy all data stored on the local disks. Once destroyed it is back for usage by other projects. A destroyed machine can not restored anymore

metalctl machine delete <id> [flags]

Options

      --bulk-output             when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.
+  -f, --file string             filename of the create or update request in yaml format, or - for stdin.
+                                
+                                Example:
+                                $ metalctl machine describe machine-1 -o yaml > machine.yaml
+                                $ vi machine.yaml
+                                $ # either via stdin
+                                $ cat machine.yaml | metalctl machine delete <id> -f -
+                                $ # or via file
+                                $ metalctl machine delete <id> -f machine.yaml
+                                
+                                the file can also contain multiple documents and perform a bulk operation.
+                                	
+  -h, --help                    help for delete
+      --remove-from-database    remove given machine from the database, is only required for maintenance reasons [optional] (admin only).
+      --skip-security-prompts   skips security prompt for bulk operations
+      --timestamps              when used with --file (bulk operation): prints timestamps in-between the operations

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_machine_describe/index.html b/v0.18.15/external/metalctl/docs/metalctl_machine_describe/index.html new file mode 100644 index 0000000000..f2724c9d57 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_machine_describe/index.html @@ -0,0 +1,24 @@ + +metalctl machine describe · metal-stack

metalctl machine describe

describes the machine

metalctl machine describe <id> [flags]

Options

  -h, --help   help for describe

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_machine_edit/index.html b/v0.18.15/external/metalctl/docs/metalctl_machine_edit/index.html new file mode 100644 index 0000000000..95199027dc --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_machine_edit/index.html @@ -0,0 +1,24 @@ + +metalctl machine edit · metal-stack

metalctl machine edit

edit the machine through an editor and update

metalctl machine edit <id> [flags]

Options

  -h, --help   help for edit

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_machine_identify/index.html b/v0.18.15/external/metalctl/docs/metalctl_machine_identify/index.html new file mode 100644 index 0000000000..f82022ab88 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_machine_identify/index.html @@ -0,0 +1,24 @@ + +metalctl machine identify · metal-stack

metalctl machine identify

manage machine chassis identify LED power

Options

  -h, --help   help for identify

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_machine_identify_off/index.html b/v0.18.15/external/metalctl/docs/metalctl_machine_identify_off/index.html new file mode 100644 index 0000000000..f10cafa3bb --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_machine_identify_off/index.html @@ -0,0 +1,25 @@ + +metalctl machine identify off · metal-stack

metalctl machine identify off

power off the machine chassis identify LED

Synopsis

set the machine chassis identify LED to off state

metalctl machine identify off <machine ID> [flags]

Options

  -d, --description string   description of the reason for chassis identify LED turn-off. (default "Triggered by metalctl")
+  -h, --help                 help for off

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_machine_identify_on/index.html b/v0.18.15/external/metalctl/docs/metalctl_machine_identify_on/index.html new file mode 100644 index 0000000000..02f8d1622a --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_machine_identify_on/index.html @@ -0,0 +1,25 @@ + +metalctl machine identify on · metal-stack

metalctl machine identify on

power on the machine chassis identify LED

Synopsis

set the machine chassis identify LED to on state

metalctl machine identify on <machine ID> [flags]

Options

  -d, --description string   description of the reason for chassis identify LED turn-on.
+  -h, --help                 help for on

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_machine_ipmi/index.html b/v0.18.15/external/metalctl/docs/metalctl_machine_ipmi/index.html new file mode 100644 index 0000000000..68a52e1165 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_machine_ipmi/index.html @@ -0,0 +1,47 @@ + +metalctl machine ipmi · metal-stack

metalctl machine ipmi

display ipmi details of the machine, if no machine ID is given all ipmi addresses are returned.

Synopsis

display ipmi details of the machine, if no machine ID is given all ipmi addresses are returned.

Meaning of the emojis:

🚧 Machine is reserved. Reserved machines are not considered for random allocation until the reservation flag is removed. 🔒 Machine is locked. Locked machines can not be deleted until the lock is removed. 💀 Machine is dead. The metal-api does not receive any events from this machine. ❗ Machine has a last event error. The machine has recently encountered an error during the provisioning lifecycle. ❓ Machine is in unknown condition. The metal-api does not receive phoned home events anymore or has never booted successfully. ⭕ Machine is in a provisioning crash loop. Flag can be reset through an API-triggered reboot or when the machine reaches the phoned home state. 🚑 Machine reclaim has failed. The machine was deleted but it is not going back into the available machine pool. 🛡 Machine is connected to our VPN, ssh access only possible via this VPN.

metalctl machine ipmi [<machine ID>] [flags]

Options

      --bmc-address string                    bmc ipmi address (needs to include port) to filter [optional]
+      --bmc-mac string                        bmc mac address to filter [optional]
+      --board-part-number string              fru board part number to filter [optional]
+  -h, --help                                  help for ipmi
+      --hostname string                       allocation hostname to filter [optional]
+      --id string                             ID to filter [optional]
+      --image string                          allocation image to filter [optional]
+      --last-event-error-threshold duration   the duration up to how long in the past a machine last event error will be counted as an issue [optional] (default 1h0m0s)
+      --mac string                            mac to filter [optional]
+      --manufacturer string                   fru manufacturer to filter [optional]
+      --name string                           allocation name to filter [optional]
+      --network-destination-prefixes string   network destination prefixes to filter [optional]
+      --network-ids string                    network ids to filter [optional]
+      --network-ips string                    network ips to filter [optional]
+      --partition string                      partition to filter [optional]
+      --product-part-number string            fru product part number to filter [optional]
+      --product-serial string                 fru product serial to filter [optional]
+      --project string                        allocation project to filter [optional]
+      --rack string                           rack to filter [optional]
+      --role string                           allocation role to filter [optional]
+      --size string                           size to filter [optional]
+      --sort-by strings                       sort by (comma separated) column(s), sort direction can be changed by appending :asc or :desc behind the column identifier. possible values: age|bios|bmc|event|id|liveliness|partition|project|rack|size|when
+      --state string                          state to filter [optional]
+      --tags strings                          tags to filter, use it like: --tags "tag1,tag2" or --tags "tag3".

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_machine_ipmi_events/index.html b/v0.18.15/external/metalctl/docs/metalctl_machine_ipmi_events/index.html new file mode 100644 index 0000000000..3de4226e7b --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_machine_ipmi_events/index.html @@ -0,0 +1,27 @@ + +metalctl machine ipmi events · metal-stack

metalctl machine ipmi events

display machine hardware events

metalctl machine ipmi events <machine ID> [flags]

Options

  -h, --help                  help for events
+      --ipmipassword string   overwrite ipmi password (admin only).
+      --ipmiuser string       overwrite ipmi user (admin only).
+  -n, --last string           show last <n> log entries. (default "10")

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

  • metalctl machine ipmi - display ipmi details of the machine, if no machine ID is given all ipmi addresses are returned.
diff --git a/v0.18.15/external/metalctl/docs/metalctl_machine_issues/index.html b/v0.18.15/external/metalctl/docs/metalctl_machine_issues/index.html new file mode 100644 index 0000000000..3767cf435a --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_machine_issues/index.html @@ -0,0 +1,50 @@ + +metalctl machine issues · metal-stack

metalctl machine issues

display machines which are in a potential bad state

Synopsis

display machines which are in a potential bad state

Meaning of the emojis:

🚧 Machine is reserved. Reserved machines are not considered for random allocation until the reservation flag is removed. 🔒 Machine is locked. Locked machines can not be deleted until the lock is removed. 💀 Machine is dead. The metal-api does not receive any events from this machine. ❗ Machine has a last event error. The machine has recently encountered an error during the provisioning lifecycle. ❓ Machine is in unknown condition. The metal-api does not receive phoned home events anymore or has never booted successfully. ⭕ Machine is in a provisioning crash loop. Flag can be reset through an API-triggered reboot or when the machine reaches the phoned home state. 🚑 Machine reclaim has failed. The machine was deleted but it is not going back into the available machine pool. 🛡 Machine is connected to our VPN, ssh access only possible via this VPN.

metalctl machine issues [<machine ID>] [flags]

Options

      --bmc-address string                    bmc ipmi address (needs to include port) to filter [optional]
+      --bmc-mac string                        bmc mac address to filter [optional]
+      --board-part-number string              fru board part number to filter [optional]
+  -h, --help                                  help for issues
+      --hostname string                       allocation hostname to filter [optional]
+      --id string                             ID to filter [optional]
+      --image string                          allocation image to filter [optional]
+      --last-event-error-threshold duration   the duration up to how long in the past a machine last event error will be counted as an issue [optional]
+      --mac string                            mac to filter [optional]
+      --manufacturer string                   fru manufacturer to filter [optional]
+      --name string                           allocation name to filter [optional]
+      --network-destination-prefixes string   network destination prefixes to filter [optional]
+      --network-ids string                    network ids to filter [optional]
+      --network-ips string                    network ips to filter [optional]
+      --omit strings                          issue types to omit [optional]
+      --only strings                          issue types to include [optional]
+      --partition string                      partition to filter [optional]
+      --product-part-number string            fru product part number to filter [optional]
+      --product-serial string                 fru product serial to filter [optional]
+      --project string                        allocation project to filter [optional]
+      --rack string                           rack to filter [optional]
+      --role string                           allocation role to filter [optional]
+      --severity string                       issue severity to include [optional]
+      --size string                           size to filter [optional]
+      --sort-by strings                       sort by (comma separated) column(s), sort direction can be changed by appending :asc or :desc behind the column identifier. possible values: age|bios|bmc|event|id|liveliness|partition|project|rack|size|when
+      --state string                          state to filter [optional]
+      --tags strings                          tags to filter, use it like: --tags "tag1,tag2" or --tags "tag3".

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_machine_issues_list/index.html b/v0.18.15/external/metalctl/docs/metalctl_machine_issues_list/index.html new file mode 100644 index 0000000000..65c617bce3 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_machine_issues_list/index.html @@ -0,0 +1,25 @@ + +metalctl machine issues list · metal-stack

metalctl machine issues list

list all machine issues that the metal-api can evaluate

metalctl machine issues list [flags]

Options

  -h, --help              help for list
+      --sort-by strings   sort by (comma separated) column(s), sort direction can be changed by appending :asc or :desc behind the column identifier. possible values: id|severity

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_machine_list/index.html b/v0.18.15/external/metalctl/docs/metalctl_machine_list/index.html new file mode 100644 index 0000000000..c0744e14bb --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_machine_list/index.html @@ -0,0 +1,47 @@ + +metalctl machine list · metal-stack

metalctl machine list

list all machines

Synopsis

list all machines

Meaning of the emojis:

🚧 Machine is reserved. Reserved machines are not considered for random allocation until the reservation flag is removed. 🔒 Machine is locked. Locked machines can not be deleted until the lock is removed. 💀 Machine is dead. The metal-api does not receive any events from this machine. ❗ Machine has a last event error. The machine has recently encountered an error during the provisioning lifecycle. ❓ Machine is in unknown condition. The metal-api does not receive phoned home events anymore or has never booted successfully. ⭕ Machine is in a provisioning crash loop. Flag can be reset through an API-triggered reboot or when the machine reaches the phoned home state. 🚑 Machine reclaim has failed. The machine was deleted but it is not going back into the available machine pool. 🛡 Machine is connected to our VPN, ssh access only possible via this VPN.

metalctl machine list [flags]

Options

      --bmc-address string                    bmc ipmi address (needs to include port) to filter [optional]
+      --bmc-mac string                        bmc mac address to filter [optional]
+      --board-part-number string              fru board part number to filter [optional]
+  -h, --help                                  help for list
+      --hostname string                       allocation hostname to filter [optional]
+      --id string                             ID to filter [optional]
+      --image string                          allocation image to filter [optional]
+      --last-event-error-threshold duration   the duration up to how long in the past a machine last event error will be counted as an issue [optional] (default 1h0m0s)
+      --mac string                            mac to filter [optional]
+      --manufacturer string                   fru manufacturer to filter [optional]
+      --name string                           allocation name to filter [optional]
+      --network-destination-prefixes string   network destination prefixes to filter [optional]
+      --network-ids string                    network ids to filter [optional]
+      --network-ips string                    network ips to filter [optional]
+      --partition string                      partition to filter [optional]
+      --product-part-number string            fru product part number to filter [optional]
+      --product-serial string                 fru product serial to filter [optional]
+      --project string                        allocation project to filter [optional]
+      --rack string                           rack to filter [optional]
+      --role string                           allocation role to filter [optional]
+      --size string                           size to filter [optional]
+      --sort-by strings                       sort by (comma separated) column(s), sort direction can be changed by appending :asc or :desc behind the column identifier. possible values: age|event|id|image|liveliness|partition|project|rack|size|when
+      --state string                          state to filter [optional]
+      --tags strings                          tags to filter, use it like: --tags "tag1,tag2" or --tags "tag3".

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_machine_lock/index.html b/v0.18.15/external/metalctl/docs/metalctl_machine_lock/index.html new file mode 100644 index 0000000000..57569113e4 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_machine_lock/index.html @@ -0,0 +1,26 @@ + +metalctl machine lock · metal-stack

metalctl machine lock

lock a machine

Synopsis

when a machine is locked, it can not be destroyed, to destroy a machine you must first remove the lock from that machine with –remove

metalctl machine lock <machine ID> [flags]

Options

  -d, --description string   description of the reason for the lock.
+  -h, --help                 help for lock
+  -r, --remove               remove the lock.

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_machine_logs/index.html b/v0.18.15/external/metalctl/docs/metalctl_machine_logs/index.html new file mode 100644 index 0000000000..92f2ced8f0 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_machine_logs/index.html @@ -0,0 +1,25 @@ + +metalctl machine logs · metal-stack

metalctl machine logs

display machine provisioning logs

metalctl machine logs <machine ID> [flags]

Options

  -h, --help                                  help for logs
+      --last-event-error-threshold duration   the duration up to how long in the past a machine last event error will be counted as an issue [optional] (default 168h0m0s)

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_machine_power/index.html b/v0.18.15/external/metalctl/docs/metalctl_machine_power/index.html new file mode 100644 index 0000000000..4655a06597 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_machine_power/index.html @@ -0,0 +1,24 @@ + +metalctl machine power · metal-stack

metalctl machine power

manage machine power

Options

  -h, --help   help for power

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_machine_power_bios/index.html b/v0.18.15/external/metalctl/docs/metalctl_machine_power_bios/index.html new file mode 100644 index 0000000000..2f09cf79c6 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_machine_power_bios/index.html @@ -0,0 +1,24 @@ + +metalctl machine power bios · metal-stack

metalctl machine power bios

boot a machine into BIOS

Synopsis

the machine will boot into bios. (machine does not reboot automatically)

metalctl machine power bios <machine ID> [flags]

Options

  -h, --help   help for bios

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_machine_power_cycle/index.html b/v0.18.15/external/metalctl/docs/metalctl_machine_power_cycle/index.html new file mode 100644 index 0000000000..4ea7198080 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_machine_power_cycle/index.html @@ -0,0 +1,24 @@ + +metalctl machine power cycle · metal-stack

metalctl machine power cycle

power cycle a machine (graceful shutdown)

Synopsis

(soft) cycle the machine power.

metalctl machine power cycle <machine ID> [flags]

Options

  -h, --help   help for cycle

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_machine_power_disk/index.html b/v0.18.15/external/metalctl/docs/metalctl_machine_power_disk/index.html new file mode 100644 index 0000000000..3f653d6bdb --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_machine_power_disk/index.html @@ -0,0 +1,24 @@ + +metalctl machine power disk · metal-stack

metalctl machine power disk

boot a machine from disk

Synopsis

the machine will boot from disk. (machine does not reboot automatically)

metalctl machine power disk <machine ID> [flags]

Options

  -h, --help   help for disk

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_machine_power_off/index.html b/v0.18.15/external/metalctl/docs/metalctl_machine_power_off/index.html new file mode 100644 index 0000000000..70419bccbc --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_machine_power_off/index.html @@ -0,0 +1,24 @@ + +metalctl machine power off · metal-stack

metalctl machine power off

power off a machine

Synopsis

set the machine to power off state, if the machine already was off nothing happens. It will usually take some time to power off the machine, depending on the machine type. Power on will therefore not work if the machine is in the powering off phase.

metalctl machine power off <machine ID> [flags]

Options

  -h, --help   help for off

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_machine_power_on/index.html b/v0.18.15/external/metalctl/docs/metalctl_machine_power_on/index.html new file mode 100644 index 0000000000..f9b5733436 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_machine_power_on/index.html @@ -0,0 +1,24 @@ + +metalctl machine power on · metal-stack

metalctl machine power on

power on a machine

Synopsis

set the machine to power on state, if the machine already was on nothing happens.

metalctl machine power on <machine ID> [flags]

Options

  -h, --help   help for on

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_machine_power_pxe/index.html b/v0.18.15/external/metalctl/docs/metalctl_machine_power_pxe/index.html new file mode 100644 index 0000000000..7cf4081f6c --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_machine_power_pxe/index.html @@ -0,0 +1,24 @@ + +metalctl machine power pxe · metal-stack

metalctl machine power pxe

boot a machine from PXE

Synopsis

the machine will boot from PXE. (machine does not reboot automatically)

metalctl machine power pxe <machine ID> [flags]

Options

  -h, --help   help for pxe

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_machine_power_reset/index.html b/v0.18.15/external/metalctl/docs/metalctl_machine_power_reset/index.html new file mode 100644 index 0000000000..1b53e3b528 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_machine_power_reset/index.html @@ -0,0 +1,24 @@ + +metalctl machine power reset · metal-stack

metalctl machine power reset

power reset a machine

Synopsis

(hard) reset the machine power.

metalctl machine power reset <machine ID> [flags]

Options

  -h, --help   help for reset

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_machine_reinstall/index.html b/v0.18.15/external/metalctl/docs/metalctl_machine_reinstall/index.html new file mode 100644 index 0000000000..8c6b60fb97 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_machine_reinstall/index.html @@ -0,0 +1,26 @@ + +metalctl machine reinstall · metal-stack

metalctl machine reinstall

reinstalls an already allocated machine

Synopsis

reinstalls an already allocated machine. If it is not yet allocated, nothing happens, otherwise only the machine's primary disk is wiped and the new image will subsequently be installed on that device

metalctl machine reinstall <machine ID> [flags]

Options

  -d, --description string   description of the reinstallation. [optional]
+  -h, --help                 help for reinstall
+      --image string         id of the image to get installed. [required]

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_machine_reserve/index.html b/v0.18.15/external/metalctl/docs/metalctl_machine_reserve/index.html new file mode 100644 index 0000000000..4344ba09d5 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_machine_reserve/index.html @@ -0,0 +1,26 @@ + +metalctl machine reserve · metal-stack

metalctl machine reserve

reserve a machine

Synopsis

reserve a machine for exclusive usage, this machine will no longer be picked by other allocations. This is useful for maintenance of the machine or testing. After the reservation is not needed anymore, the reservation should be removed with –remove.

metalctl machine reserve <machine ID> [flags]

Options

  -d, --description string   description of the reason for the reservation.
+  -h, --help                 help for reserve
+  -r, --remove               remove the reservation.

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_machine_update-firmware/index.html b/v0.18.15/external/metalctl/docs/metalctl_machine_update-firmware/index.html new file mode 100644 index 0000000000..10741381a6 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_machine_update-firmware/index.html @@ -0,0 +1,24 @@ + +metalctl machine update-firmware · metal-stack

metalctl machine update-firmware

update a machine firmware

Options

  -h, --help   help for update-firmware

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_machine_update-firmware_bios/index.html b/v0.18.15/external/metalctl/docs/metalctl_machine_update-firmware_bios/index.html new file mode 100644 index 0000000000..cf993b30c9 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_machine_update-firmware_bios/index.html @@ -0,0 +1,26 @@ + +metalctl machine update-firmware bios · metal-stack

metalctl machine update-firmware bios

update a machine BIOS

Synopsis

the machine BIOS will be updated to given revision. If revision flag is not specified an update plan will be printed instead.

metalctl machine update-firmware bios <machine ID> [flags]

Options

      --description string   the reason why the BIOS should be updated
+  -h, --help                 help for bios
+      --revision string      the BIOS revision

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_machine_update-firmware_bmc/index.html b/v0.18.15/external/metalctl/docs/metalctl_machine_update-firmware_bmc/index.html new file mode 100644 index 0000000000..f5db9d6cb7 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_machine_update-firmware_bmc/index.html @@ -0,0 +1,26 @@ + +metalctl machine update-firmware bmc · metal-stack

metalctl machine update-firmware bmc

update a machine BMC

Synopsis

the machine BMC will be updated to given revision. If revision flag is not specified an update plan will be printed instead.

metalctl machine update-firmware bmc <machine ID> [flags]

Options

      --description string   the reason why the BMC should be updated
+  -h, --help                 help for bmc
+      --revision string      the BMC revision

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_machine_update/index.html b/v0.18.15/external/metalctl/docs/metalctl_machine_update/index.html new file mode 100644 index 0000000000..00b39d964f --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_machine_update/index.html @@ -0,0 +1,42 @@ + +metalctl machine update · metal-stack

metalctl machine update

updates the machine

metalctl machine update <id> [flags]

Options

      --add-tags strings        tags to be added to the machine [optional]
+      --bulk-output             when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.
+      --description string      the description of the machine [optional]
+  -f, --file string             filename of the create or update request in yaml format, or - for stdin.
+                                
+                                Example:
+                                $ metalctl machine describe machine-1 -o yaml > machine.yaml
+                                $ vi machine.yaml
+                                $ # either via stdin
+                                $ cat machine.yaml | metalctl machine update <id> -f -
+                                $ # or via file
+                                $ metalctl machine update <id> -f machine.yaml
+                                
+                                the file can also contain multiple documents and perform a bulk operation.
+                                	
+  -h, --help                    help for update
+      --remove-tags strings     tags to be removed from the machine [optional]
+      --skip-security-prompts   skips security prompt for bulk operations
+      --timestamps              when used with --file (bulk operation): prints timestamps in-between the operations

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_markdown/index.html b/v0.18.15/external/metalctl/docs/metalctl_markdown/index.html new file mode 100644 index 0000000000..d32a890c5e --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_markdown/index.html @@ -0,0 +1,24 @@ + +metalctl markdown · metal-stack

metalctl markdown

create markdown documentation

metalctl markdown [flags]

Options

  -h, --help   help for markdown

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

  • metalctl - a cli to manage entities in the metal-stack api
diff --git a/v0.18.15/external/metalctl/docs/metalctl_network/index.html b/v0.18.15/external/metalctl/docs/metalctl_network/index.html new file mode 100644 index 0000000000..a632f0ca57 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_network/index.html @@ -0,0 +1,24 @@ + +metalctl network · metal-stack

metalctl network

manage network entities

Synopsis

networks can be attached to a machine or firewall such that they can communicate with each other.

Options

  -h, --help   help for network

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_network_allocate/index.html b/v0.18.15/external/metalctl/docs/metalctl_network_allocate/index.html new file mode 100644 index 0000000000..a3a71dfc0d --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_network_allocate/index.html @@ -0,0 +1,31 @@ + +metalctl network allocate · metal-stack

metalctl network allocate

allocate a network

metalctl network allocate [flags]

Options

  -d, --description string   description of the network to create. [optional]
+      --dmz                  use this private network as dmz. [optional]
+  -h, --help                 help for allocate
+      --labels strings       labels for this network. [optional]
+  -n, --name string          name of the network to create. [required]
+      --partition string     partition where this network should exist. [required]
+      --project string       partition where this network should exist. [required]
+      --shared               shared allows usage of this private network from other networks

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_network_apply/index.html b/v0.18.15/external/metalctl/docs/metalctl_network_apply/index.html new file mode 100644 index 0000000000..7b3856bdbe --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_network_apply/index.html @@ -0,0 +1,39 @@ + +metalctl network apply · metal-stack

metalctl network apply

applies one or more networks from a given file

metalctl network apply [flags]

Options

      --bulk-output             when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.
+  -f, --file string             filename of the create or update request in yaml format, or - for stdin.
+                                
+                                Example:
+                                $ metalctl network describe network-1 -o yaml > network.yaml
+                                $ vi network.yaml
+                                $ # either via stdin
+                                $ cat network.yaml | metalctl network apply -f -
+                                $ # or via file
+                                $ metalctl network apply -f network.yaml
+                                
+                                the file can also contain multiple documents and perform a bulk operation.
+                                	
+  -h, --help                    help for apply
+      --skip-security-prompts   skips security prompt for bulk operations
+      --timestamps              when used with --file (bulk operation): prints timestamps in-between the operations

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_network_create/index.html b/v0.18.15/external/metalctl/docs/metalctl_network_create/index.html new file mode 100644 index 0000000000..e5f8eee5bf --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_network_create/index.html @@ -0,0 +1,53 @@ + +metalctl network create · metal-stack

metalctl network create

creates the network

metalctl network create [flags]

Options

      --additional-announcable-cidrs strings   list of cidrs which are added to the route maps per tenant private network, these are typically pod- and service cidrs, can only be set in a supernetwork
+      --bulk-output                            when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.
+  -d, --description string                     description of the network to create. [optional]
+      --destination-prefixes strings           destination prefixes in this network.
+  -f, --file string                            filename of the create or update request in yaml format, or - for stdin.
+                                               
+                                               Example:
+                                               $ metalctl network describe network-1 -o yaml > network.yaml
+                                               $ vi network.yaml
+                                               $ # either via stdin
+                                               $ cat network.yaml | metalctl network create -f -
+                                               $ # or via file
+                                               $ metalctl network create -f network.yaml
+                                               
+                                               the file can also contain multiple documents and perform a bulk operation.
+                                               	
+  -h, --help                                   help for create
+      --id string                              id of the network to create. [optional]
+      --labels strings                         add initial labels, must be in the form of key=value, use it like: --labels "key1=value1,key2=value2".
+  -n, --name string                            name of the network to create. [optional]
+      --nat                                    set nat flag of network, if set to true, traffic from this network will be natted.
+  -p, --partition string                       partition where this network should exist.
+      --prefixes strings                       prefixes in this network.
+      --privatesuper                           set private super flag of network, if set to true, this network is used to start machines there.
+      --project string                         project of the network to create. [optional]
+      --skip-security-prompts                  skips security prompt for bulk operations
+      --timestamps                             when used with --file (bulk operation): prints timestamps in-between the operations
+      --underlay                               set underlay flag of network, if set to true, this is used to transport underlay network traffic
+      --vrf int                                vrf of this network
+      --vrfshared                              vrf shared allows multiple networks to share a vrf

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_network_delete/index.html b/v0.18.15/external/metalctl/docs/metalctl_network_delete/index.html new file mode 100644 index 0000000000..9b43871d5a --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_network_delete/index.html @@ -0,0 +1,39 @@ + +metalctl network delete · metal-stack

metalctl network delete

deletes the network

metalctl network delete <id> [flags]

Options

      --bulk-output             when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.
+  -f, --file string             filename of the create or update request in yaml format, or - for stdin.
+                                
+                                Example:
+                                $ metalctl network describe network-1 -o yaml > network.yaml
+                                $ vi network.yaml
+                                $ # either via stdin
+                                $ cat network.yaml | metalctl network delete <id> -f -
+                                $ # or via file
+                                $ metalctl network delete <id> -f network.yaml
+                                
+                                the file can also contain multiple documents and perform a bulk operation.
+                                	
+  -h, --help                    help for delete
+      --skip-security-prompts   skips security prompt for bulk operations
+      --timestamps              when used with --file (bulk operation): prints timestamps in-between the operations

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_network_describe/index.html b/v0.18.15/external/metalctl/docs/metalctl_network_describe/index.html new file mode 100644 index 0000000000..e9c30fd88f --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_network_describe/index.html @@ -0,0 +1,24 @@ + +metalctl network describe · metal-stack

metalctl network describe

describes the network

metalctl network describe <id> [flags]

Options

  -h, --help   help for describe

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_network_edit/index.html b/v0.18.15/external/metalctl/docs/metalctl_network_edit/index.html new file mode 100644 index 0000000000..77a94773db --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_network_edit/index.html @@ -0,0 +1,24 @@ + +metalctl network edit · metal-stack

metalctl network edit

edit the network through an editor and update

metalctl network edit <id> [flags]

Options

  -h, --help   help for edit

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_network_free/index.html b/v0.18.15/external/metalctl/docs/metalctl_network_free/index.html new file mode 100644 index 0000000000..72582b612c --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_network_free/index.html @@ -0,0 +1,24 @@ + +metalctl network free · metal-stack

metalctl network free

free a network

metalctl network free <networkid> [flags]

Options

  -h, --help   help for free

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_network_ip/index.html b/v0.18.15/external/metalctl/docs/metalctl_network_ip/index.html new file mode 100644 index 0000000000..c2ee81a02c --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_network_ip/index.html @@ -0,0 +1,24 @@ + +metalctl network ip · metal-stack

metalctl network ip

manage ip entities

Synopsis

an ip address can be attached to a machine or firewall such that network traffic can be routed to these servers.

Options

  -h, --help   help for ip

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_network_ip_apply/index.html b/v0.18.15/external/metalctl/docs/metalctl_network_ip_apply/index.html new file mode 100644 index 0000000000..088578334b --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_network_ip_apply/index.html @@ -0,0 +1,39 @@ + +metalctl network ip apply · metal-stack

metalctl network ip apply

applies one or more ips from a given file

metalctl network ip apply [flags]

Options

      --bulk-output             when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.
+  -f, --file string             filename of the create or update request in yaml format, or - for stdin.
+                                
+                                Example:
+                                $ metalctl ip describe ip-1 -o yaml > ip.yaml
+                                $ vi ip.yaml
+                                $ # either via stdin
+                                $ cat ip.yaml | metalctl ip apply -f -
+                                $ # or via file
+                                $ metalctl ip apply -f ip.yaml
+                                
+                                the file can also contain multiple documents and perform a bulk operation.
+                                	
+  -h, --help                    help for apply
+      --skip-security-prompts   skips security prompt for bulk operations
+      --timestamps              when used with --file (bulk operation): prints timestamps in-between the operations

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_network_ip_create/index.html b/v0.18.15/external/metalctl/docs/metalctl_network_ip_create/index.html new file mode 100644 index 0000000000..c28eca4c75 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_network_ip_create/index.html @@ -0,0 +1,46 @@ + +metalctl network ip create · metal-stack

metalctl network ip create

creates the ip

metalctl network ip create [flags]

Options

      --bulk-output             when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.
+  -d, --description string      description of the IP to allocate. [optional]
+  -f, --file string             filename of the create or update request in yaml format, or - for stdin.
+                                
+                                Example:
+                                $ metalctl ip describe ip-1 -o yaml > ip.yaml
+                                $ vi ip.yaml
+                                $ # either via stdin
+                                $ cat ip.yaml | metalctl ip create -f -
+                                $ # or via file
+                                $ metalctl ip create -f ip.yaml
+                                
+                                the file can also contain multiple documents and perform a bulk operation.
+                                	
+  -h, --help                    help for create
+      --ipaddress string        a specific ip address to allocate. [optional]
+  -n, --name string             name of the IP to allocate. [optional]
+      --network string          network from where the IP should be allocated.
+      --project string          project for which the IP should be allocated.
+      --skip-security-prompts   skips security prompt for bulk operations
+      --tags strings            tags to attach to the IP.
+      --timestamps              when used with --file (bulk operation): prints timestamps in-between the operations
+      --type string             type of the IP to allocate: ephemeral|static [optional] (default "ephemeral")

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_network_ip_delete/index.html b/v0.18.15/external/metalctl/docs/metalctl_network_ip_delete/index.html new file mode 100644 index 0000000000..b74f419ae1 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_network_ip_delete/index.html @@ -0,0 +1,39 @@ + +metalctl network ip delete · metal-stack

metalctl network ip delete

deletes the ip

metalctl network ip delete <id> [flags]

Options

      --bulk-output             when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.
+  -f, --file string             filename of the create or update request in yaml format, or - for stdin.
+                                
+                                Example:
+                                $ metalctl ip describe ip-1 -o yaml > ip.yaml
+                                $ vi ip.yaml
+                                $ # either via stdin
+                                $ cat ip.yaml | metalctl ip delete <id> -f -
+                                $ # or via file
+                                $ metalctl ip delete <id> -f ip.yaml
+                                
+                                the file can also contain multiple documents and perform a bulk operation.
+                                	
+  -h, --help                    help for delete
+      --skip-security-prompts   skips security prompt for bulk operations
+      --timestamps              when used with --file (bulk operation): prints timestamps in-between the operations

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_network_ip_describe/index.html b/v0.18.15/external/metalctl/docs/metalctl_network_ip_describe/index.html new file mode 100644 index 0000000000..92fadb5328 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_network_ip_describe/index.html @@ -0,0 +1,24 @@ + +metalctl network ip describe · metal-stack

metalctl network ip describe

describes the ip

metalctl network ip describe <id> [flags]

Options

  -h, --help   help for describe

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_network_ip_edit/index.html b/v0.18.15/external/metalctl/docs/metalctl_network_ip_edit/index.html new file mode 100644 index 0000000000..267321c599 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_network_ip_edit/index.html @@ -0,0 +1,24 @@ + +metalctl network ip edit · metal-stack

metalctl network ip edit

edit the ip through an editor and update

metalctl network ip edit <id> [flags]

Options

  -h, --help   help for edit

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_network_ip_issues/index.html b/v0.18.15/external/metalctl/docs/metalctl_network_ip_issues/index.html new file mode 100644 index 0000000000..c56837197c --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_network_ip_issues/index.html @@ -0,0 +1,24 @@ + +metalctl network ip issues · metal-stack

metalctl network ip issues

display ips which are in a potential bad state

metalctl network ip issues [flags]

Options

  -h, --help   help for issues

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_network_ip_list/index.html b/v0.18.15/external/metalctl/docs/metalctl_network_ip_list/index.html new file mode 100644 index 0000000000..50b4810a6e --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_network_ip_list/index.html @@ -0,0 +1,33 @@ + +metalctl network ip list · metal-stack

metalctl network ip list

list all ips

metalctl network ip list [flags]

Options

  -h, --help               help for list
+      --ipaddress string   ipaddress to filter [optional]
+      --machineid string   machineid to filter [optional]
+      --name string        name to filter [optional]
+      --network string     network to filter [optional]
+      --prefix string      prefix to filter [optional]
+      --project string     project to filter [optional]
+      --sort-by strings    sort by (comma separated) column(s), sort direction can be changed by appending :asc or :desc behind the column identifier. possible values: age|description|id|ipaddress|name|network|type
+      --tags strings       tags to filter [optional]
+      --type string        type to filter [optional]

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_network_ip_update/index.html b/v0.18.15/external/metalctl/docs/metalctl_network_ip_update/index.html new file mode 100644 index 0000000000..1d5fdfcd72 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_network_ip_update/index.html @@ -0,0 +1,39 @@ + +metalctl network ip update · metal-stack

metalctl network ip update

updates the ip

metalctl network ip update [flags]

Options

      --bulk-output             when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.
+  -f, --file string             filename of the create or update request in yaml format, or - for stdin.
+                                
+                                Example:
+                                $ metalctl ip describe ip-1 -o yaml > ip.yaml
+                                $ vi ip.yaml
+                                $ # either via stdin
+                                $ cat ip.yaml | metalctl ip update -f -
+                                $ # or via file
+                                $ metalctl ip update -f ip.yaml
+                                
+                                the file can also contain multiple documents and perform a bulk operation.
+                                	
+  -h, --help                    help for update
+      --skip-security-prompts   skips security prompt for bulk operations
+      --timestamps              when used with --file (bulk operation): prints timestamps in-between the operations

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_network_list/index.html b/v0.18.15/external/metalctl/docs/metalctl_network_list/index.html new file mode 100644 index 0000000000..4fbc831773 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_network_list/index.html @@ -0,0 +1,36 @@ + +metalctl network list · metal-stack

metalctl network list

list all networks

metalctl network list [flags]

Options

      --destination-prefixes strings   destination prefixes to filter, use it like: --destination-prefixes prefix1,prefix2.
+  -h, --help                           help for list
+      --id string                      ID to filter [optional]
+      --name string                    name to filter [optional]
+      --nat                            nat to filter [optional]
+      --parent string                  parent network to filter [optional]
+      --partition string               partition to filter [optional]
+      --prefixes strings               prefixes to filter, use it like: --prefixes prefix1,prefix2.
+      --privatesuper                   privatesuper to filter [optional]
+      --project string                 project to filter [optional]
+      --sort-by strings                sort by (comma separated) column(s), sort direction can be changed by appending :asc or :desc behind the column identifier. possible values: description|id|name|partition|project
+      --underlay                       underlay to filter [optional]
+      --vrf int                        vrf to filter [optional]

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_network_update/index.html b/v0.18.15/external/metalctl/docs/metalctl_network_update/index.html new file mode 100644 index 0000000000..e787c05597 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_network_update/index.html @@ -0,0 +1,48 @@ + +metalctl network update · metal-stack

metalctl network update

updates the network

metalctl network update <id> [flags]

Options

      --add-destinationprefixes strings        destination prefixes to be added to the network [optional]
+      --add-prefixes strings                   prefixes to be added to the network [optional]
+      --additional-announcable-cidrs strings   list of cidrs which are added to the route maps per tenant private network, these are typically pod- and service cidrs, can only be set in a supernetwork
+      --bulk-output                            when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.
+      --description string                     the description of the network [optional]
+  -f, --file string                            filename of the create or update request in yaml format, or - for stdin.
+                                               
+                                               Example:
+                                               $ metalctl network describe network-1 -o yaml > network.yaml
+                                               $ vi network.yaml
+                                               $ # either via stdin
+                                               $ cat network.yaml | metalctl network update <id> -f -
+                                               $ # or via file
+                                               $ metalctl network update <id> -f network.yaml
+                                               
+                                               the file can also contain multiple documents and perform a bulk operation.
+                                               	
+  -h, --help                                   help for update
+      --labels strings                         the labels of the network, must be in the form of key=value, use it like: --labels "key1=value1,key2=value2". [optional]
+      --name string                            the name of the network [optional]
+      --remove-destinationprefixes strings     destination prefixes to be removed from the network [optional]
+      --remove-prefixes strings                prefixes to be removed from the network [optional]
+      --shared                                 marks a network as shared or not [optional]
+      --skip-security-prompts                  skips security prompt for bulk operations
+      --timestamps                             when used with --file (bulk operation): prints timestamps in-between the operations

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_partition/index.html b/v0.18.15/external/metalctl/docs/metalctl_partition/index.html new file mode 100644 index 0000000000..8033cc61bb --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_partition/index.html @@ -0,0 +1,24 @@ + +metalctl partition · metal-stack

metalctl partition

manage partition entities

Synopsis

a partition is a failure domain in the data center.

Options

  -h, --help   help for partition

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_partition_apply/index.html b/v0.18.15/external/metalctl/docs/metalctl_partition_apply/index.html new file mode 100644 index 0000000000..124c2e8485 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_partition_apply/index.html @@ -0,0 +1,39 @@ + +metalctl partition apply · metal-stack

metalctl partition apply

applies one or more partitions from a given file

metalctl partition apply [flags]

Options

      --bulk-output             when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.
+  -f, --file string             filename of the create or update request in yaml format, or - for stdin.
+                                
+                                Example:
+                                $ metalctl partition describe partition-1 -o yaml > partition.yaml
+                                $ vi partition.yaml
+                                $ # either via stdin
+                                $ cat partition.yaml | metalctl partition apply -f -
+                                $ # or via file
+                                $ metalctl partition apply -f partition.yaml
+                                
+                                the file can also contain multiple documents and perform a bulk operation.
+                                	
+  -h, --help                    help for apply
+      --skip-security-prompts   skips security prompt for bulk operations
+      --timestamps              when used with --file (bulk operation): prints timestamps in-between the operations

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_partition_capacity/index.html b/v0.18.15/external/metalctl/docs/metalctl_partition_capacity/index.html new file mode 100644 index 0000000000..407fd29f96 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_partition_capacity/index.html @@ -0,0 +1,27 @@ + +metalctl partition capacity · metal-stack

metalctl partition capacity

show partition capacity

metalctl partition capacity [flags]

Options

  -h, --help              help for capacity
+      --id string         filter on partition id. [optional]
+      --size string       filter on size id. [optional]
+      --sort-by strings   order by (comma separated) column(s), sort direction can be changed by appending :asc or :desc behind the column identifier. possible values: description|id|name

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_partition_create/index.html b/v0.18.15/external/metalctl/docs/metalctl_partition_create/index.html new file mode 100644 index 0000000000..8ac0b1d482 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_partition_create/index.html @@ -0,0 +1,46 @@ + +metalctl partition create · metal-stack

metalctl partition create

creates the partition

metalctl partition create [flags]

Options

      --bulk-output             when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.
+      --cmdline string          kernel commandline for the metal-hammer in the partition. [required]
+  -d, --description string      Description of the partition. [required]
+  -f, --file string             filename of the create or update request in yaml format, or - for stdin.
+                                
+                                Example:
+                                $ metalctl partition describe partition-1 -o yaml > partition.yaml
+                                $ vi partition.yaml
+                                $ # either via stdin
+                                $ cat partition.yaml | metalctl partition create -f -
+                                $ # or via file
+                                $ metalctl partition create -f partition.yaml
+                                
+                                the file can also contain multiple documents and perform a bulk operation.
+                                	
+  -h, --help                    help for create
+      --id string               ID of the partition. [required]
+      --imageurl string         initrd for the metal-hammer in the partition. [required]
+      --kernelurl string        kernel url for the metal-hammer in the partition. [required]
+      --mgmtserver string       management server address in the partition. [required]
+  -n, --name string             Name of the partition. [optional]
+      --skip-security-prompts   skips security prompt for bulk operations
+      --timestamps              when used with --file (bulk operation): prints timestamps in-between the operations

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_partition_delete/index.html b/v0.18.15/external/metalctl/docs/metalctl_partition_delete/index.html new file mode 100644 index 0000000000..e671a9eb1d --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_partition_delete/index.html @@ -0,0 +1,39 @@ + +metalctl partition delete · metal-stack

metalctl partition delete

deletes the partition

metalctl partition delete <id> [flags]

Options

      --bulk-output             when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.
+  -f, --file string             filename of the create or update request in yaml format, or - for stdin.
+                                
+                                Example:
+                                $ metalctl partition describe partition-1 -o yaml > partition.yaml
+                                $ vi partition.yaml
+                                $ # either via stdin
+                                $ cat partition.yaml | metalctl partition delete <id> -f -
+                                $ # or via file
+                                $ metalctl partition delete <id> -f partition.yaml
+                                
+                                the file can also contain multiple documents and perform a bulk operation.
+                                	
+  -h, --help                    help for delete
+      --skip-security-prompts   skips security prompt for bulk operations
+      --timestamps              when used with --file (bulk operation): prints timestamps in-between the operations

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_partition_describe/index.html b/v0.18.15/external/metalctl/docs/metalctl_partition_describe/index.html new file mode 100644 index 0000000000..63decef4a7 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_partition_describe/index.html @@ -0,0 +1,24 @@ + +metalctl partition describe · metal-stack

metalctl partition describe

describes the partition

metalctl partition describe <id> [flags]

Options

  -h, --help   help for describe

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_partition_edit/index.html b/v0.18.15/external/metalctl/docs/metalctl_partition_edit/index.html new file mode 100644 index 0000000000..b60ae89f6f --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_partition_edit/index.html @@ -0,0 +1,24 @@ + +metalctl partition edit · metal-stack

metalctl partition edit

edit the partition through an editor and update

metalctl partition edit <id> [flags]

Options

  -h, --help   help for edit

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_partition_list/index.html b/v0.18.15/external/metalctl/docs/metalctl_partition_list/index.html new file mode 100644 index 0000000000..b5c0c81e54 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_partition_list/index.html @@ -0,0 +1,25 @@ + +metalctl partition list · metal-stack

metalctl partition list

list all partitions

metalctl partition list [flags]

Options

  -h, --help              help for list
+      --sort-by strings   sort by (comma separated) column(s), sort direction can be changed by appending :asc or :desc behind the column identifier. possible values: description|id|name

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_partition_update/index.html b/v0.18.15/external/metalctl/docs/metalctl_partition_update/index.html new file mode 100644 index 0000000000..2adc563f79 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_partition_update/index.html @@ -0,0 +1,39 @@ + +metalctl partition update · metal-stack

metalctl partition update

updates the partition

metalctl partition update [flags]

Options

      --bulk-output             when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.
+  -f, --file string             filename of the create or update request in yaml format, or - for stdin.
+                                
+                                Example:
+                                $ metalctl partition describe partition-1 -o yaml > partition.yaml
+                                $ vi partition.yaml
+                                $ # either via stdin
+                                $ cat partition.yaml | metalctl partition update -f -
+                                $ # or via file
+                                $ metalctl partition update -f partition.yaml
+                                
+                                the file can also contain multiple documents and perform a bulk operation.
+                                	
+  -h, --help                    help for update
+      --skip-security-prompts   skips security prompt for bulk operations
+      --timestamps              when used with --file (bulk operation): prints timestamps in-between the operations

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_project/index.html b/v0.18.15/external/metalctl/docs/metalctl_project/index.html new file mode 100644 index 0000000000..0efa8cc976 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_project/index.html @@ -0,0 +1,24 @@ + +metalctl project · metal-stack

metalctl project

manage project entities

Synopsis

a project belongs to a tenant and groups together entities in metal-stack.

Options

  -h, --help   help for project

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_project_apply/index.html b/v0.18.15/external/metalctl/docs/metalctl_project_apply/index.html new file mode 100644 index 0000000000..02d7234035 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_project_apply/index.html @@ -0,0 +1,39 @@ + +metalctl project apply · metal-stack

metalctl project apply

applies one or more projects from a given file

metalctl project apply [flags]

Options

      --bulk-output             when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.
+  -f, --file string             filename of the create or update request in yaml format, or - for stdin.
+                                
+                                Example:
+                                $ metalctl project describe project-1 -o yaml > project.yaml
+                                $ vi project.yaml
+                                $ # either via stdin
+                                $ cat project.yaml | metalctl project apply -f -
+                                $ # or via file
+                                $ metalctl project apply -f project.yaml
+                                
+                                the file can also contain multiple documents and perform a bulk operation.
+                                	
+  -h, --help                    help for apply
+      --skip-security-prompts   skips security prompt for bulk operations
+      --timestamps              when used with --file (bulk operation): prints timestamps in-between the operations

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_project_create/index.html b/v0.18.15/external/metalctl/docs/metalctl_project_create/index.html new file mode 100644 index 0000000000..66a0f5dfd5 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_project_create/index.html @@ -0,0 +1,47 @@ + +metalctl project create · metal-stack

metalctl project create

creates the project

metalctl project create [flags]

Options

      --annotation strings      add initial annotation, must be in the form of key=value, can be given multiple times to add multiple annotations, e.g. --annotation key=value --annotation foo=bar
+      --bulk-output             when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.
+      --cluster-quota int32     cluster quota
+      --description string      description of the project.
+  -f, --file string             filename of the create or update request in yaml format, or - for stdin.
+                                
+                                Example:
+                                $ metalctl project describe project-1 -o yaml > project.yaml
+                                $ vi project.yaml
+                                $ # either via stdin
+                                $ cat project.yaml | metalctl project create -f -
+                                $ # or via file
+                                $ metalctl project create -f project.yaml
+                                
+                                the file can also contain multiple documents and perform a bulk operation.
+                                	
+  -h, --help                    help for create
+      --ip-quota int32          ip quota
+      --label strings           add initial label, can be given multiple times to add multiple labels, e.g. --label=foo --label=bar
+      --machine-quota int32     machine quota
+      --name string             name of the project, max 10 characters.
+      --skip-security-prompts   skips security prompt for bulk operations
+      --tenant string           create project for given tenant
+      --timestamps              when used with --file (bulk operation): prints timestamps in-between the operations

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_project_delete/index.html b/v0.18.15/external/metalctl/docs/metalctl_project_delete/index.html new file mode 100644 index 0000000000..dedca5d87e --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_project_delete/index.html @@ -0,0 +1,39 @@ + +metalctl project delete · metal-stack

metalctl project delete

deletes the project

metalctl project delete <id> [flags]

Options

      --bulk-output             when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.
+  -f, --file string             filename of the create or update request in yaml format, or - for stdin.
+                                
+                                Example:
+                                $ metalctl project describe project-1 -o yaml > project.yaml
+                                $ vi project.yaml
+                                $ # either via stdin
+                                $ cat project.yaml | metalctl project delete <id> -f -
+                                $ # or via file
+                                $ metalctl project delete <id> -f project.yaml
+                                
+                                the file can also contain multiple documents and perform a bulk operation.
+                                	
+  -h, --help                    help for delete
+      --skip-security-prompts   skips security prompt for bulk operations
+      --timestamps              when used with --file (bulk operation): prints timestamps in-between the operations

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_project_describe/index.html b/v0.18.15/external/metalctl/docs/metalctl_project_describe/index.html new file mode 100644 index 0000000000..1161b661d8 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_project_describe/index.html @@ -0,0 +1,24 @@ + +metalctl project describe · metal-stack

metalctl project describe

describes the project

metalctl project describe <id> [flags]

Options

  -h, --help   help for describe

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_project_edit/index.html b/v0.18.15/external/metalctl/docs/metalctl_project_edit/index.html new file mode 100644 index 0000000000..e18d4eb9c5 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_project_edit/index.html @@ -0,0 +1,24 @@ + +metalctl project edit · metal-stack

metalctl project edit

edit the project through an editor and update

metalctl project edit <id> [flags]

Options

  -h, --help   help for edit

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_project_list/index.html b/v0.18.15/external/metalctl/docs/metalctl_project_list/index.html new file mode 100644 index 0000000000..f351abc994 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_project_list/index.html @@ -0,0 +1,28 @@ + +metalctl project list · metal-stack

metalctl project list

list all projects

metalctl project list [flags]

Options

  -h, --help              help for list
+      --id string         ID of the project.
+      --name string       Name of the project.
+      --sort-by strings   sort by (comma separated) column(s), sort direction can be changed by appending :asc or :desc behind the column identifier. possible values: description|id|name|tenant
+      --tenant string     tenant of this project.

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_project_update/index.html b/v0.18.15/external/metalctl/docs/metalctl_project_update/index.html new file mode 100644 index 0000000000..b9b55a61ad --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_project_update/index.html @@ -0,0 +1,39 @@ + +metalctl project update · metal-stack

metalctl project update

updates the project

metalctl project update [flags]

Options

      --bulk-output             when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.
+  -f, --file string             filename of the create or update request in yaml format, or - for stdin.
+                                
+                                Example:
+                                $ metalctl project describe project-1 -o yaml > project.yaml
+                                $ vi project.yaml
+                                $ # either via stdin
+                                $ cat project.yaml | metalctl project update -f -
+                                $ # or via file
+                                $ metalctl project update -f project.yaml
+                                
+                                the file can also contain multiple documents and perform a bulk operation.
+                                	
+  -h, --help                    help for update
+      --skip-security-prompts   skips security prompt for bulk operations
+      --timestamps              when used with --file (bulk operation): prints timestamps in-between the operations

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_size/index.html b/v0.18.15/external/metalctl/docs/metalctl_size/index.html new file mode 100644 index 0000000000..7b7f20f6be --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_size/index.html @@ -0,0 +1,24 @@ + +metalctl size · metal-stack

metalctl size

manage size entities

Synopsis

a size matches a machine in terms of cpu cores, ram and storage.

Options

  -h, --help   help for size

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_size_apply/index.html b/v0.18.15/external/metalctl/docs/metalctl_size_apply/index.html new file mode 100644 index 0000000000..dcca9569e1 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_size_apply/index.html @@ -0,0 +1,39 @@ + +metalctl size apply · metal-stack

metalctl size apply

applies one or more sizes from a given file

metalctl size apply [flags]

Options

      --bulk-output             when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.
+  -f, --file string             filename of the create or update request in yaml format, or - for stdin.
+                                
+                                Example:
+                                $ metalctl size describe size-1 -o yaml > size.yaml
+                                $ vi size.yaml
+                                $ # either via stdin
+                                $ cat size.yaml | metalctl size apply -f -
+                                $ # or via file
+                                $ metalctl size apply -f size.yaml
+                                
+                                the file can also contain multiple documents and perform a bulk operation.
+                                	
+  -h, --help                    help for apply
+      --skip-security-prompts   skips security prompt for bulk operations
+      --timestamps              when used with --file (bulk operation): prints timestamps in-between the operations

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_size_create/index.html b/v0.18.15/external/metalctl/docs/metalctl_size_create/index.html new file mode 100644 index 0000000000..f58262da9a --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_size_create/index.html @@ -0,0 +1,45 @@ + +metalctl size create · metal-stack

metalctl size create

creates the size

metalctl size create [flags]

Options

      --bulk-output             when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.
+  -d, --description string      Description of the size. [required]
+  -f, --file string             filename of the create or update request in yaml format, or - for stdin.
+                                
+                                Example:
+                                $ metalctl size describe size-1 -o yaml > size.yaml
+                                $ vi size.yaml
+                                $ # either via stdin
+                                $ cat size.yaml | metalctl size create -f -
+                                $ # or via file
+                                $ metalctl size create -f size.yaml
+                                
+                                the file can also contain multiple documents and perform a bulk operation.
+                                	
+  -h, --help                    help for create
+      --id string               ID of the size. [required]
+      --max int                 min value of given size constraint type. [required]
+      --min int                 min value of given size constraint type. [required]
+  -n, --name string             Name of the size. [optional]
+      --skip-security-prompts   skips security prompt for bulk operations
+      --timestamps              when used with --file (bulk operation): prints timestamps in-between the operations
+      --type string             type of constraints. [required]

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_size_delete/index.html b/v0.18.15/external/metalctl/docs/metalctl_size_delete/index.html new file mode 100644 index 0000000000..7564d98537 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_size_delete/index.html @@ -0,0 +1,39 @@ + +metalctl size delete · metal-stack

metalctl size delete

deletes the size

metalctl size delete <id> [flags]

Options

      --bulk-output             when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.
+  -f, --file string             filename of the create or update request in yaml format, or - for stdin.
+                                
+                                Example:
+                                $ metalctl size describe size-1 -o yaml > size.yaml
+                                $ vi size.yaml
+                                $ # either via stdin
+                                $ cat size.yaml | metalctl size delete <id> -f -
+                                $ # or via file
+                                $ metalctl size delete <id> -f size.yaml
+                                
+                                the file can also contain multiple documents and perform a bulk operation.
+                                	
+  -h, --help                    help for delete
+      --skip-security-prompts   skips security prompt for bulk operations
+      --timestamps              when used with --file (bulk operation): prints timestamps in-between the operations

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_size_describe/index.html b/v0.18.15/external/metalctl/docs/metalctl_size_describe/index.html new file mode 100644 index 0000000000..54f52ad116 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_size_describe/index.html @@ -0,0 +1,24 @@ + +metalctl size describe · metal-stack

metalctl size describe

describes the size

metalctl size describe <id> [flags]

Options

  -h, --help   help for describe

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_size_edit/index.html b/v0.18.15/external/metalctl/docs/metalctl_size_edit/index.html new file mode 100644 index 0000000000..1e9a8ee816 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_size_edit/index.html @@ -0,0 +1,24 @@ + +metalctl size edit · metal-stack

metalctl size edit

edit the size through an editor and update

metalctl size edit <id> [flags]

Options

  -h, --help   help for edit

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_size_imageconstraint/index.html b/v0.18.15/external/metalctl/docs/metalctl_size_imageconstraint/index.html new file mode 100644 index 0000000000..8dab228ade --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_size_imageconstraint/index.html @@ -0,0 +1,24 @@ + +metalctl size imageconstraint · metal-stack

metalctl size imageconstraint

manage imageconstraint entities

Synopsis

if a size has specific requirements regarding the images which must fulfill certain constraints, this can be configured here.

Options

  -h, --help   help for imageconstraint

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_size_imageconstraint_apply/index.html b/v0.18.15/external/metalctl/docs/metalctl_size_imageconstraint_apply/index.html new file mode 100644 index 0000000000..eada326aa0 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_size_imageconstraint_apply/index.html @@ -0,0 +1,39 @@ + +metalctl size imageconstraint apply · metal-stack

metalctl size imageconstraint apply

applies one or more imageconstraints from a given file

metalctl size imageconstraint apply [flags]

Options

      --bulk-output             when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.
+  -f, --file string             filename of the create or update request in yaml format, or - for stdin.
+                                
+                                Example:
+                                $ metalctl imageconstraint describe imageconstraint-1 -o yaml > imageconstraint.yaml
+                                $ vi imageconstraint.yaml
+                                $ # either via stdin
+                                $ cat imageconstraint.yaml | metalctl imageconstraint apply -f -
+                                $ # or via file
+                                $ metalctl imageconstraint apply -f imageconstraint.yaml
+                                
+                                the file can also contain multiple documents and perform a bulk operation.
+                                	
+  -h, --help                    help for apply
+      --skip-security-prompts   skips security prompt for bulk operations
+      --timestamps              when used with --file (bulk operation): prints timestamps in-between the operations

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_size_imageconstraint_create/index.html b/v0.18.15/external/metalctl/docs/metalctl_size_imageconstraint_create/index.html new file mode 100644 index 0000000000..ef2a4c4c83 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_size_imageconstraint_create/index.html @@ -0,0 +1,39 @@ + +metalctl size imageconstraint create · metal-stack

metalctl size imageconstraint create

creates the imageconstraint

metalctl size imageconstraint create [flags]

Options

      --bulk-output             when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.
+  -f, --file string             filename of the create or update request in yaml format, or - for stdin.
+                                
+                                Example:
+                                $ metalctl imageconstraint describe imageconstraint-1 -o yaml > imageconstraint.yaml
+                                $ vi imageconstraint.yaml
+                                $ # either via stdin
+                                $ cat imageconstraint.yaml | metalctl imageconstraint create -f -
+                                $ # or via file
+                                $ metalctl imageconstraint create -f imageconstraint.yaml
+                                
+                                the file can also contain multiple documents and perform a bulk operation.
+                                	
+  -h, --help                    help for create
+      --skip-security-prompts   skips security prompt for bulk operations
+      --timestamps              when used with --file (bulk operation): prints timestamps in-between the operations

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_size_imageconstraint_delete/index.html b/v0.18.15/external/metalctl/docs/metalctl_size_imageconstraint_delete/index.html new file mode 100644 index 0000000000..2438a13d73 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_size_imageconstraint_delete/index.html @@ -0,0 +1,39 @@ + +metalctl size imageconstraint delete · metal-stack

metalctl size imageconstraint delete

deletes the imageconstraint

metalctl size imageconstraint delete <id> [flags]

Options

      --bulk-output             when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.
+  -f, --file string             filename of the create or update request in yaml format, or - for stdin.
+                                
+                                Example:
+                                $ metalctl imageconstraint describe imageconstraint-1 -o yaml > imageconstraint.yaml
+                                $ vi imageconstraint.yaml
+                                $ # either via stdin
+                                $ cat imageconstraint.yaml | metalctl imageconstraint delete <id> -f -
+                                $ # or via file
+                                $ metalctl imageconstraint delete <id> -f imageconstraint.yaml
+                                
+                                the file can also contain multiple documents and perform a bulk operation.
+                                	
+  -h, --help                    help for delete
+      --skip-security-prompts   skips security prompt for bulk operations
+      --timestamps              when used with --file (bulk operation): prints timestamps in-between the operations

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_size_imageconstraint_describe/index.html b/v0.18.15/external/metalctl/docs/metalctl_size_imageconstraint_describe/index.html new file mode 100644 index 0000000000..0739ea2509 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_size_imageconstraint_describe/index.html @@ -0,0 +1,24 @@ + +metalctl size imageconstraint describe · metal-stack

metalctl size imageconstraint describe

describes the imageconstraint

metalctl size imageconstraint describe <id> [flags]

Options

  -h, --help   help for describe

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_size_imageconstraint_edit/index.html b/v0.18.15/external/metalctl/docs/metalctl_size_imageconstraint_edit/index.html new file mode 100644 index 0000000000..9d7f4de8fa --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_size_imageconstraint_edit/index.html @@ -0,0 +1,24 @@ + +metalctl size imageconstraint edit · metal-stack

metalctl size imageconstraint edit

edit the imageconstraint through an editor and update

metalctl size imageconstraint edit <id> [flags]

Options

  -h, --help   help for edit

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_size_imageconstraint_list/index.html b/v0.18.15/external/metalctl/docs/metalctl_size_imageconstraint_list/index.html new file mode 100644 index 0000000000..4295189008 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_size_imageconstraint_list/index.html @@ -0,0 +1,25 @@ + +metalctl size imageconstraint list · metal-stack

metalctl size imageconstraint list

list all imageconstraints

metalctl size imageconstraint list [flags]

Options

  -h, --help              help for list
+      --sort-by strings   sort by (comma separated) column(s), sort direction can be changed by appending :asc or :desc behind the column identifier. possible values: description|id|name

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_size_imageconstraint_try/index.html b/v0.18.15/external/metalctl/docs/metalctl_size_imageconstraint_try/index.html new file mode 100644 index 0000000000..07f5365b08 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_size_imageconstraint_try/index.html @@ -0,0 +1,26 @@ + +metalctl size imageconstraint try · metal-stack

metalctl size imageconstraint try

try if size and image can be allocated

metalctl size imageconstraint try [flags]

Options

  -h, --help           help for try
+      --image string   image to check if allocaltion is possible
+      --size string    size to check if allocaltion is possible

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_size_imageconstraint_update/index.html b/v0.18.15/external/metalctl/docs/metalctl_size_imageconstraint_update/index.html new file mode 100644 index 0000000000..243bbdae30 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_size_imageconstraint_update/index.html @@ -0,0 +1,39 @@ + +metalctl size imageconstraint update · metal-stack

metalctl size imageconstraint update

updates the imageconstraint

metalctl size imageconstraint update [flags]

Options

      --bulk-output             when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.
+  -f, --file string             filename of the create or update request in yaml format, or - for stdin.
+                                
+                                Example:
+                                $ metalctl imageconstraint describe imageconstraint-1 -o yaml > imageconstraint.yaml
+                                $ vi imageconstraint.yaml
+                                $ # either via stdin
+                                $ cat imageconstraint.yaml | metalctl imageconstraint update -f -
+                                $ # or via file
+                                $ metalctl imageconstraint update -f imageconstraint.yaml
+                                
+                                the file can also contain multiple documents and perform a bulk operation.
+                                	
+  -h, --help                    help for update
+      --skip-security-prompts   skips security prompt for bulk operations
+      --timestamps              when used with --file (bulk operation): prints timestamps in-between the operations

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_size_list/index.html b/v0.18.15/external/metalctl/docs/metalctl_size_list/index.html new file mode 100644 index 0000000000..a5cfedf2ce --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_size_list/index.html @@ -0,0 +1,25 @@ + +metalctl size list · metal-stack

metalctl size list

list all sizes

metalctl size list [flags]

Options

  -h, --help              help for list
+      --sort-by strings   sort by (comma separated) column(s), sort direction can be changed by appending :asc or :desc behind the column identifier. possible values: description|id|name

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_size_reservation/index.html b/v0.18.15/external/metalctl/docs/metalctl_size_reservation/index.html new file mode 100644 index 0000000000..993ae73b77 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_size_reservation/index.html @@ -0,0 +1,24 @@ + +metalctl size reservation · metal-stack

metalctl size reservation

manage reservation entities

Synopsis

manage size reservations

Options

  -h, --help   help for reservation

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_size_reservation_apply/index.html b/v0.18.15/external/metalctl/docs/metalctl_size_reservation_apply/index.html new file mode 100644 index 0000000000..c7e5afb1d8 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_size_reservation_apply/index.html @@ -0,0 +1,39 @@ + +metalctl size reservation apply · metal-stack

metalctl size reservation apply

applies one or more reservations from a given file

metalctl size reservation apply [flags]

Options

      --bulk-output             when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.
+  -f, --file string             filename of the create or update request in yaml format, or - for stdin.
+                                
+                                Example:
+                                $ metalctl reservation describe reservation-1 -o yaml > reservation.yaml
+                                $ vi reservation.yaml
+                                $ # either via stdin
+                                $ cat reservation.yaml | metalctl reservation apply -f -
+                                $ # or via file
+                                $ metalctl reservation apply -f reservation.yaml
+                                
+                                the file can also contain multiple documents and perform a bulk operation.
+                                	
+  -h, --help                    help for apply
+      --skip-security-prompts   skips security prompt for bulk operations
+      --timestamps              when used with --file (bulk operation): prints timestamps in-between the operations

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_size_reservation_create/index.html b/v0.18.15/external/metalctl/docs/metalctl_size_reservation_create/index.html new file mode 100644 index 0000000000..bd58d49e75 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_size_reservation_create/index.html @@ -0,0 +1,46 @@ + +metalctl size reservation create · metal-stack

metalctl size reservation create

creates the reservation

metalctl size reservation create [flags]

Options

      --amount int32            the amount to associate with this reservation
+      --bulk-output             when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.
+      --description string      the description to associate with this reservation
+  -f, --file string             filename of the create or update request in yaml format, or - for stdin.
+                                
+                                Example:
+                                $ metalctl reservation describe reservation-1 -o yaml > reservation.yaml
+                                $ vi reservation.yaml
+                                $ # either via stdin
+                                $ cat reservation.yaml | metalctl reservation create -f -
+                                $ # or via file
+                                $ metalctl reservation create -f reservation.yaml
+                                
+                                the file can also contain multiple documents and perform a bulk operation.
+                                	
+  -h, --help                    help for create
+      --id string               the id to associate with this reservation
+      --labels strings          the labels to associate with this reservation
+      --partitions strings      the partition ids to associate with this reservation
+      --project string          the project id to associate with this reservation
+      --size string             the size id to associate with this reservation
+      --skip-security-prompts   skips security prompt for bulk operations
+      --timestamps              when used with --file (bulk operation): prints timestamps in-between the operations

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_size_reservation_delete/index.html b/v0.18.15/external/metalctl/docs/metalctl_size_reservation_delete/index.html new file mode 100644 index 0000000000..18ec97d39d --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_size_reservation_delete/index.html @@ -0,0 +1,39 @@ + +metalctl size reservation delete · metal-stack

metalctl size reservation delete

deletes the reservation

metalctl size reservation delete <id> [flags]

Options

      --bulk-output             when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.
+  -f, --file string             filename of the create or update request in yaml format, or - for stdin.
+                                
+                                Example:
+                                $ metalctl reservation describe reservation-1 -o yaml > reservation.yaml
+                                $ vi reservation.yaml
+                                $ # either via stdin
+                                $ cat reservation.yaml | metalctl reservation delete <id> -f -
+                                $ # or via file
+                                $ metalctl reservation delete <id> -f reservation.yaml
+                                
+                                the file can also contain multiple documents and perform a bulk operation.
+                                	
+  -h, --help                    help for delete
+      --skip-security-prompts   skips security prompt for bulk operations
+      --timestamps              when used with --file (bulk operation): prints timestamps in-between the operations

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_size_reservation_describe/index.html b/v0.18.15/external/metalctl/docs/metalctl_size_reservation_describe/index.html new file mode 100644 index 0000000000..fcbfa555d6 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_size_reservation_describe/index.html @@ -0,0 +1,24 @@ + +metalctl size reservation describe · metal-stack

metalctl size reservation describe

describes the reservation

metalctl size reservation describe <id> [flags]

Options

  -h, --help   help for describe

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_size_reservation_edit/index.html b/v0.18.15/external/metalctl/docs/metalctl_size_reservation_edit/index.html new file mode 100644 index 0000000000..94e85bcf60 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_size_reservation_edit/index.html @@ -0,0 +1,24 @@ + +metalctl size reservation edit · metal-stack

metalctl size reservation edit

edit the reservation through an editor and update

metalctl size reservation edit <id> [flags]

Options

  -h, --help   help for edit

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_size_reservation_list/index.html b/v0.18.15/external/metalctl/docs/metalctl_size_reservation_list/index.html new file mode 100644 index 0000000000..0112312552 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_size_reservation_list/index.html @@ -0,0 +1,29 @@ + +metalctl size reservation list · metal-stack

metalctl size reservation list

list all reservations

metalctl size reservation list [flags]

Options

  -h, --help               help for list
+      --id string          the id to filter
+      --partition string   the partition id to filter
+      --project string     the project id to filter
+      --size string        the size id to filter
+      --sort-by strings    sort by (comma separated) column(s), sort direction can be changed by appending :asc or :desc behind the column identifier. possible values: amount|id|partition|project|size

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_size_reservation_update/index.html b/v0.18.15/external/metalctl/docs/metalctl_size_reservation_update/index.html new file mode 100644 index 0000000000..85cb691c70 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_size_reservation_update/index.html @@ -0,0 +1,43 @@ + +metalctl size reservation update · metal-stack

metalctl size reservation update

updates the reservation

metalctl size reservation update <id> [flags]

Options

      --amount int32            the amount to associate with this reservation
+      --bulk-output             when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.
+      --description string      the description to associate with this reservation
+  -f, --file string             filename of the create or update request in yaml format, or - for stdin.
+                                
+                                Example:
+                                $ metalctl reservation describe reservation-1 -o yaml > reservation.yaml
+                                $ vi reservation.yaml
+                                $ # either via stdin
+                                $ cat reservation.yaml | metalctl reservation update <id> -f -
+                                $ # or via file
+                                $ metalctl reservation update <id> -f reservation.yaml
+                                
+                                the file can also contain multiple documents and perform a bulk operation.
+                                	
+  -h, --help                    help for update
+      --labels strings          the labels to associate with this reservation
+      --partitions strings      the partition ids to associate with this reservation
+      --skip-security-prompts   skips security prompt for bulk operations
+      --timestamps              when used with --file (bulk operation): prints timestamps in-between the operations

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_size_reservation_usage/index.html b/v0.18.15/external/metalctl/docs/metalctl_size_reservation_usage/index.html new file mode 100644 index 0000000000..508366f4f4 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_size_reservation_usage/index.html @@ -0,0 +1,28 @@ + +metalctl size reservation usage · metal-stack

metalctl size reservation usage

see current usage of size reservations

metalctl size reservation usage [flags]

Options

  -h, --help               help for usage
+      --partition string   the partition to filter
+      --project string     the project to filter
+      --size-id string     the size-id to filter
+      --sort-by strings    sort by (comma separated) column(s), sort direction can be changed by appending :asc or :desc behind the column identifier. possible values: amount|id|partition|project|size|used-amount

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_size_suggest/index.html b/v0.18.15/external/metalctl/docs/metalctl_size_suggest/index.html new file mode 100644 index 0000000000..4233a7a74b --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_size_suggest/index.html @@ -0,0 +1,28 @@ + +metalctl size suggest · metal-stack

metalctl size suggest

suggest size from a given machine id

metalctl size suggest <id> [flags]

Options

      --description string   The description of the suggested size (default "a suggested size")
+  -h, --help                 help for suggest
+      --labels strings       labels to add to the size
+      --machine-id string    Machine id used to create the size suggestion. [required]
+      --name string          The name of the suggested size (default "suggested-size")

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_size_update/index.html b/v0.18.15/external/metalctl/docs/metalctl_size_update/index.html new file mode 100644 index 0000000000..acc03866f1 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_size_update/index.html @@ -0,0 +1,39 @@ + +metalctl size update · metal-stack

metalctl size update

updates the size

metalctl size update [flags]

Options

      --bulk-output             when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.
+  -f, --file string             filename of the create or update request in yaml format, or - for stdin.
+                                
+                                Example:
+                                $ metalctl size describe size-1 -o yaml > size.yaml
+                                $ vi size.yaml
+                                $ # either via stdin
+                                $ cat size.yaml | metalctl size update -f -
+                                $ # or via file
+                                $ metalctl size update -f size.yaml
+                                
+                                the file can also contain multiple documents and perform a bulk operation.
+                                	
+  -h, --help                    help for update
+      --skip-security-prompts   skips security prompt for bulk operations
+      --timestamps              when used with --file (bulk operation): prints timestamps in-between the operations

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_switch/index.html b/v0.18.15/external/metalctl/docs/metalctl_switch/index.html new file mode 100644 index 0000000000..02af846c26 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_switch/index.html @@ -0,0 +1,24 @@ + +metalctl switch · metal-stack

metalctl switch

manage switch entities

Synopsis

switch are the leaf switches in the data center that are controlled by metal-stack.

Options

  -h, --help   help for switch

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_switch_connected-machines/index.html b/v0.18.15/external/metalctl/docs/metalctl_switch_connected-machines/index.html new file mode 100644 index 0000000000..ee89bf2b64 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_switch_connected-machines/index.html @@ -0,0 +1,40 @@ + +metalctl switch connected-machines · metal-stack

metalctl switch connected-machines

shows switches with their connected machines

metalctl switch connected-machines [flags]

Examples

The command will show the machines connected to the switch ports.
+
+Can also be used with -o template in order to generate CSV-style output:
+
+$ metalctl switch connected-machines -o template --template '{{ $machines := .machines }}{{ range .switches }}{{ $switch := . }}{{ range .connections }}{{ $switch.id }},{{ $switch.rack_id }},{{ .nic.name }},{{ .machine_id }},{{ (index $machines .machine_id).ipmi.fru.product_serial }}{{ printf "\n" }}{{ end }}{{ end }}'
+r01leaf01,swp1,f78cc340-e5e8-48ed-8fe7-2336c1e2ded2,<a-serial>
+r01leaf01,swp2,44e3a522-5f48-4f3c-9188-41025f9e401e,<b-serial>
+...
+

Options

  -h, --help                help for connected-machines
+      --id string           ID of the switch.
+      --machine-id string   The id of the connected machine, ignores size flag if set.
+      --name string         Name of the switch.
+      --os-vendor string    OS vendor of this switch.
+      --os-version string   OS version of this switch.
+      --partition string    Partition of this switch.
+      --rack string         Rack of this switch.
+      --size string         Size of the connected machines.

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_switch_console/index.html b/v0.18.15/external/metalctl/docs/metalctl_switch_console/index.html new file mode 100644 index 0000000000..767f1a1f13 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_switch_console/index.html @@ -0,0 +1,24 @@ + +metalctl switch console · metal-stack

metalctl switch console

connect to the switch console

Synopsis

this requires a network connectivity to the ip address of the console server this switch is connected to.

metalctl switch console <switchID> [flags]

Options

  -h, --help   help for console

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_switch_delete/index.html b/v0.18.15/external/metalctl/docs/metalctl_switch_delete/index.html new file mode 100644 index 0000000000..ee9d5812d7 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_switch_delete/index.html @@ -0,0 +1,40 @@ + +metalctl switch delete · metal-stack

metalctl switch delete

deletes the switch

metalctl switch delete <id> [flags]

Options

      --bulk-output             when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.
+  -f, --file string             filename of the create or update request in yaml format, or - for stdin.
+                                
+                                Example:
+                                $ metalctl switch describe switch-1 -o yaml > switch.yaml
+                                $ vi switch.yaml
+                                $ # either via stdin
+                                $ cat switch.yaml | metalctl switch delete <id> -f -
+                                $ # or via file
+                                $ metalctl switch delete <id> -f switch.yaml
+                                
+                                the file can also contain multiple documents and perform a bulk operation.
+                                	
+      --force                   forcefully delete the switch accepting the risk that it still has machines connected to it
+  -h, --help                    help for delete
+      --skip-security-prompts   skips security prompt for bulk operations
+      --timestamps              when used with --file (bulk operation): prints timestamps in-between the operations

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_switch_describe/index.html b/v0.18.15/external/metalctl/docs/metalctl_switch_describe/index.html new file mode 100644 index 0000000000..23202e9af1 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_switch_describe/index.html @@ -0,0 +1,24 @@ + +metalctl switch describe · metal-stack

metalctl switch describe

describes the switch

metalctl switch describe <id> [flags]

Options

  -h, --help   help for describe

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_switch_detail/index.html b/v0.18.15/external/metalctl/docs/metalctl_switch_detail/index.html new file mode 100644 index 0000000000..c24b507c1a --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_switch_detail/index.html @@ -0,0 +1,30 @@ + +metalctl switch detail · metal-stack

metalctl switch detail

switch details

metalctl switch detail [flags]

Options

  -h, --help                help for detail
+      --id string           ID of the switch.
+      --name string         Name of the switch.
+      --os-vendor string    OS vendor of this switch.
+      --os-version string   OS version of this switch.
+      --partition string    Partition of this switch.
+      --rack string         Rack of this switch.

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_switch_edit/index.html b/v0.18.15/external/metalctl/docs/metalctl_switch_edit/index.html new file mode 100644 index 0000000000..9f8895254e --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_switch_edit/index.html @@ -0,0 +1,24 @@ + +metalctl switch edit · metal-stack

metalctl switch edit

edit the switch through an editor and update

metalctl switch edit <id> [flags]

Options

  -h, --help   help for edit

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_switch_list/index.html b/v0.18.15/external/metalctl/docs/metalctl_switch_list/index.html new file mode 100644 index 0000000000..75865917e0 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_switch_list/index.html @@ -0,0 +1,31 @@ + +metalctl switch list · metal-stack

metalctl switch list

list all switches

metalctl switch list [flags]

Options

  -h, --help                help for list
+      --id string           ID of the switch.
+      --name string         Name of the switch.
+      --os-vendor string    OS vendor of this switch.
+      --os-version string   OS version of this switch.
+      --partition string    Partition of this switch.
+      --rack string         Rack of this switch.
+      --sort-by strings     sort by (comma separated) column(s), sort direction can be changed by appending :asc or :desc behind the column identifier. possible values: description|id|name

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_switch_port/index.html b/v0.18.15/external/metalctl/docs/metalctl_switch_port/index.html new file mode 100644 index 0000000000..60e5e1a268 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_switch_port/index.html @@ -0,0 +1,25 @@ + +metalctl switch port · metal-stack

metalctl switch port

sets the given switch port state up or down

Options

  -h, --help          help for port
+      --port string   the port to be changed.

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_switch_port_describe/index.html b/v0.18.15/external/metalctl/docs/metalctl_switch_port_describe/index.html new file mode 100644 index 0000000000..1fe0e49031 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_switch_port_describe/index.html @@ -0,0 +1,25 @@ + +metalctl switch port describe · metal-stack

metalctl switch port describe

gets the given switch port state

Synopsis

shows the current actual and desired state of the port of the given switch.

metalctl switch port describe <switch ID> [flags]

Options

  -h, --help   help for describe

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --port string            the port to be changed.
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_switch_port_down/index.html b/v0.18.15/external/metalctl/docs/metalctl_switch_port_down/index.html new file mode 100644 index 0000000000..aae7897f72 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_switch_port_down/index.html @@ -0,0 +1,25 @@ + +metalctl switch port down · metal-stack

metalctl switch port down

sets the given switch port state down

Synopsis

sets the port status to DOWN so the connected machine will not be able to connect to the switch.

metalctl switch port down <switch ID> [flags]

Options

  -h, --help   help for down

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --port string            the port to be changed.
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_switch_port_up/index.html b/v0.18.15/external/metalctl/docs/metalctl_switch_port_up/index.html new file mode 100644 index 0000000000..ffe67f1cac --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_switch_port_up/index.html @@ -0,0 +1,25 @@ + +metalctl switch port up · metal-stack

metalctl switch port up

sets the given switch port state up

Synopsis

sets the port status to UP so the connected machine will be able to connect to the switch.

metalctl switch port up <switch ID> [flags]

Options

  -h, --help   help for up

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --port string            the port to be changed.
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_switch_replace/index.html b/v0.18.15/external/metalctl/docs/metalctl_switch_replace/index.html new file mode 100644 index 0000000000..033276c72b --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_switch_replace/index.html @@ -0,0 +1,24 @@ + +metalctl switch replace · metal-stack

metalctl switch replace

put a leaf switch into replace mode in preparation for physical replacement. For a description of the steps involved see the long help.

Synopsis

Put a leaf switch into replace mode in preparation for physical replacement

Operational steps to replace a switch:

  • Put the switch that needs to be replaced in replace mode with this command
  • Replace the switch MAC address in the metal-stack deployment configuration
  • Make sure that interfaces on the new switch do not get connected to the PXE-bridge immediately by setting the interfaces list of the respective leaf switch to [] in the metal-stack deployment configuration
  • Deploy the management servers so that the dhcp servers will serve the right address and DHCP options to the new switch
  • Replace the switch physically. Be careful to ensure that the cabling mirrors the remaining leaf exactly because the new switch information will be cloned from the remaining switch! Also make sure to have console access to the switch so you can start and monitor the install process
  • If the switch is not in onie install mode but already has an operating system installed, put it into install mode with "sudo onie-select -i -f -v" and reboot it. Now the switch should be provisioned with a management IP from a management server, install itself with the right software image and receive license and ssh keys through ZTP. You can check whether that process has completed successfully with the command "sudo ztp -s". The ZTP state should be disabled and the result should be success.
  • Deploy the switch plane and metal-core through metal-stack deployment CI job
  • The switch will now register with its metal-api, and the metal-core service will receive the cloned interface and routing information. You can verify successful switch replacement by checking the interface and BGP configuration, and checking the switch status with "metalctl switch ls -o wide"; it should now be operational again
metalctl switch replace <switchID> [flags]

Options

  -h, --help   help for replace

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_switch_ssh/index.html b/v0.18.15/external/metalctl/docs/metalctl_switch_ssh/index.html new file mode 100644 index 0000000000..bc5f32a832 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_switch_ssh/index.html @@ -0,0 +1,24 @@ + +metalctl switch ssh · metal-stack

metalctl switch ssh

connect to the switch via ssh

Synopsis

this requires a network connectivity to the management ip address of the switch.

metalctl switch ssh <switchID> [flags]

Options

  -h, --help   help for ssh

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_switch_update/index.html b/v0.18.15/external/metalctl/docs/metalctl_switch_update/index.html new file mode 100644 index 0000000000..929f637182 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_switch_update/index.html @@ -0,0 +1,39 @@ + +metalctl switch update · metal-stack

metalctl switch update

updates the switch

metalctl switch update [flags]

Options

      --bulk-output             when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.
+  -f, --file string             filename of the create or update request in yaml format, or - for stdin.
+                                
+                                Example:
+                                $ metalctl switch describe switch-1 -o yaml > switch.yaml
+                                $ vi switch.yaml
+                                $ # either via stdin
+                                $ cat switch.yaml | metalctl switch update -f -
+                                $ # or via file
+                                $ metalctl switch update -f switch.yaml
+                                
+                                the file can also contain multiple documents and perform a bulk operation.
+                                	
+  -h, --help                    help for update
+      --skip-security-prompts   skips security prompt for bulk operations
+      --timestamps              when used with --file (bulk operation): prints timestamps in-between the operations

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_tenant/index.html b/v0.18.15/external/metalctl/docs/metalctl_tenant/index.html new file mode 100644 index 0000000000..b6f2e9b937 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_tenant/index.html @@ -0,0 +1,24 @@ + +metalctl tenant · metal-stack

metalctl tenant

manage tenant entities

Synopsis

a tenant belongs to a tenant and groups together entities in metal-stack.

Options

  -h, --help   help for tenant

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_tenant_apply/index.html b/v0.18.15/external/metalctl/docs/metalctl_tenant_apply/index.html new file mode 100644 index 0000000000..42243e7406 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_tenant_apply/index.html @@ -0,0 +1,39 @@ + +metalctl tenant apply · metal-stack

metalctl tenant apply

applies one or more tenants from a given file

metalctl tenant apply [flags]

Options

      --bulk-output             when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.
+  -f, --file string             filename of the create or update request in yaml format, or - for stdin.
+                                
+                                Example:
+                                $ metalctl tenant describe tenant-1 -o yaml > tenant.yaml
+                                $ vi tenant.yaml
+                                $ # either via stdin
+                                $ cat tenant.yaml | metalctl tenant apply -f -
+                                $ # or via file
+                                $ metalctl tenant apply -f tenant.yaml
+                                
+                                the file can also contain multiple documents and perform a bulk operation.
+                                	
+  -h, --help                    help for apply
+      --skip-security-prompts   skips security prompt for bulk operations
+      --timestamps              when used with --file (bulk operation): prints timestamps in-between the operations

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_tenant_create/index.html b/v0.18.15/external/metalctl/docs/metalctl_tenant_create/index.html new file mode 100644 index 0000000000..1f793bc931 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_tenant_create/index.html @@ -0,0 +1,47 @@ + +metalctl tenant create · metal-stack

metalctl tenant create

creates the tenant

metalctl tenant create [flags]

Options

      --annotations strings     add initial annotations, must be in the form of key=value, can be given multiple times to add multiple annotations, e.g. --annotation key=value --annotation foo=bar
+      --bulk-output             when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.
+      --cluster-quota int32     cluster quota
+      --description string      description of the tenant.
+  -f, --file string             filename of the create or update request in yaml format, or - for stdin.
+                                
+                                Example:
+                                $ metalctl tenant describe tenant-1 -o yaml > tenant.yaml
+                                $ vi tenant.yaml
+                                $ # either via stdin
+                                $ cat tenant.yaml | metalctl tenant create -f -
+                                $ # or via file
+                                $ metalctl tenant create -f tenant.yaml
+                                
+                                the file can also contain multiple documents and perform a bulk operation.
+                                	
+  -h, --help                    help for create
+      --id string               id of the tenant, max 10 characters.
+      --ip-quota int32          ip quota
+      --labels strings          add initial label, can be given multiple times to add multiple labels, e.g. --label=foo --label=bar
+      --machine-quota int32     machine quota
+      --name string             name of the tenant, max 10 characters.
+      --skip-security-prompts   skips security prompt for bulk operations
+      --timestamps              when used with --file (bulk operation): prints timestamps in-between the operations

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_tenant_delete/index.html b/v0.18.15/external/metalctl/docs/metalctl_tenant_delete/index.html new file mode 100644 index 0000000000..9f624c5f5e --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_tenant_delete/index.html @@ -0,0 +1,39 @@ + +metalctl tenant delete · metal-stack

metalctl tenant delete

deletes the tenant

metalctl tenant delete <id> [flags]

Options

      --bulk-output             when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.
+  -f, --file string             filename of the create or update request in yaml format, or - for stdin.
+                                
+                                Example:
+                                $ metalctl tenant describe tenant-1 -o yaml > tenant.yaml
+                                $ vi tenant.yaml
+                                $ # either via stdin
+                                $ cat tenant.yaml | metalctl tenant delete <id> -f -
+                                $ # or via file
+                                $ metalctl tenant delete <id> -f tenant.yaml
+                                
+                                the file can also contain multiple documents and perform a bulk operation.
+                                	
+  -h, --help                    help for delete
+      --skip-security-prompts   skips security prompt for bulk operations
+      --timestamps              when used with --file (bulk operation): prints timestamps in-between the operations

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_tenant_describe/index.html b/v0.18.15/external/metalctl/docs/metalctl_tenant_describe/index.html new file mode 100644 index 0000000000..7238dab4e4 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_tenant_describe/index.html @@ -0,0 +1,24 @@ + +metalctl tenant describe · metal-stack

metalctl tenant describe

describes the tenant

metalctl tenant describe <id> [flags]

Options

  -h, --help   help for describe

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_tenant_edit/index.html b/v0.18.15/external/metalctl/docs/metalctl_tenant_edit/index.html new file mode 100644 index 0000000000..663e454c33 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_tenant_edit/index.html @@ -0,0 +1,24 @@ + +metalctl tenant edit · metal-stack

metalctl tenant edit

edit the tenant through an editor and update

metalctl tenant edit <id> [flags]

Options

  -h, --help   help for edit

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_tenant_list/index.html b/v0.18.15/external/metalctl/docs/metalctl_tenant_list/index.html new file mode 100644 index 0000000000..fc782dbe45 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_tenant_list/index.html @@ -0,0 +1,28 @@ + +metalctl tenant list · metal-stack

metalctl tenant list

list all tenants

metalctl tenant list [flags]

Options

      --annotations strings   annotations
+  -h, --help                  help for list
+      --id string             ID of the tenant.
+      --name string           Name of the tenant.
+      --sort-by strings       sort by (comma separated) column(s), sort direction can be changed by appending :asc or :desc behind the column identifier. possible values: description|id|name

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_tenant_update/index.html b/v0.18.15/external/metalctl/docs/metalctl_tenant_update/index.html new file mode 100644 index 0000000000..ec356451d4 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_tenant_update/index.html @@ -0,0 +1,39 @@ + +metalctl tenant update · metal-stack

metalctl tenant update

updates the tenant

metalctl tenant update [flags]

Options

      --bulk-output             when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.
+  -f, --file string             filename of the create or update request in yaml format, or - for stdin.
+                                
+                                Example:
+                                $ metalctl tenant describe tenant-1 -o yaml > tenant.yaml
+                                $ vi tenant.yaml
+                                $ # either via stdin
+                                $ cat tenant.yaml | metalctl tenant update -f -
+                                $ # or via file
+                                $ metalctl tenant update -f tenant.yaml
+                                
+                                the file can also contain multiple documents and perform a bulk operation.
+                                	
+  -h, --help                    help for update
+      --skip-security-prompts   skips security prompt for bulk operations
+      --timestamps              when used with --file (bulk operation): prints timestamps in-between the operations

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_update/index.html b/v0.18.15/external/metalctl/docs/metalctl_update/index.html new file mode 100644 index 0000000000..f8d4cabfac --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_update/index.html @@ -0,0 +1,24 @@ + +metalctl update · metal-stack

metalctl update

update the program

Options

  -h, --help   help for update

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_update_check/index.html b/v0.18.15/external/metalctl/docs/metalctl_update_check/index.html new file mode 100644 index 0000000000..4e1370c647 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_update_check/index.html @@ -0,0 +1,24 @@ + +metalctl update check · metal-stack

metalctl update check

check for update of the program

metalctl update check [flags]

Options

  -h, --help   help for check

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_update_do/index.html b/v0.18.15/external/metalctl/docs/metalctl_update_do/index.html new file mode 100644 index 0000000000..6e94dd5854 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_update_do/index.html @@ -0,0 +1,25 @@ + +metalctl update do · metal-stack

metalctl update do

do the update of the program

metalctl update do [flags]

Options

  -h, --help             help for do
+  -v, --version string   the version to update to, by default updates to the supported version, use "latest" to update to latest version

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_version/index.html b/v0.18.15/external/metalctl/docs/metalctl_version/index.html new file mode 100644 index 0000000000..ea87a501cd --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_version/index.html @@ -0,0 +1,24 @@ + +metalctl version · metal-stack

metalctl version

print the client and server version information

metalctl version [flags]

Options

  -h, --help   help for version

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

  • metalctl - a cli to manage entities in the metal-stack api
diff --git a/v0.18.15/external/metalctl/docs/metalctl_vpn/index.html b/v0.18.15/external/metalctl/docs/metalctl_vpn/index.html new file mode 100644 index 0000000000..5e0f530f6a --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_vpn/index.html @@ -0,0 +1,24 @@ + +metalctl vpn · metal-stack

metalctl vpn

access VPN

Synopsis

access VPN

Options

  -h, --help   help for vpn

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_vpn_key/index.html b/v0.18.15/external/metalctl/docs/metalctl_vpn_key/index.html new file mode 100644 index 0000000000..c37d1d04f0 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_vpn_key/index.html @@ -0,0 +1,29 @@ + +metalctl vpn key · metal-stack

metalctl vpn key

create an auth key

Synopsis

create an auth key to connect to VPN

metalctl vpn key [flags]

Examples

auth key for tailscale can be created by this command:
+metalctl vpn key \
+	-- project cluster01
+

Options

      --ephemeral        create an ephemeral key (default true)
+  -h, --help             help for key
+      --project string   project ID for which auth key should be created

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

diff --git a/v0.18.15/external/metalctl/docs/metalctl_whoami/index.html b/v0.18.15/external/metalctl/docs/metalctl_whoami/index.html new file mode 100644 index 0000000000..2a60afbc23 --- /dev/null +++ b/v0.18.15/external/metalctl/docs/metalctl_whoami/index.html @@ -0,0 +1,24 @@ + +metalctl whoami · metal-stack

metalctl whoami

shows current user

Synopsis

shows the current user, that will be used to authenticate commands.

metalctl whoami [flags]

Options

  -h, --help   help for whoami

Options inherited from parent commands

      --api-token string       api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.
+      --api-url string         api server address. Can be specified with METALCTL_API_URL environment variable.
+  -c, --config string          alternative config file path, (default is ~/.metalctl/config.yaml).
+                               Example config.yaml:
+                               
+                               ---
+                               apitoken: "alongtoken"
+                               ...
+                               
+                               
+      --debug                  debug output
+      --force-color            force colored output even without tty
+      --kubeconfig string      Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.
+      --no-headers             do not print headers of table output format (default print headers)
+  -o, --output-format string   output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default "table")
+      --template string        output template for template output-format, go template format.
+                               For property names inspect the output of -o json or -o yaml for reference.
+                               Example for machines:
+                               
+                               metalctl machine list -o template --template "{{ .id }}:{{ .size.id  }}"
+                               
+                               
+      --yes-i-really-mean-it   skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)

SEE ALSO

  • metalctl - a cli to manage entities in the metal-stack api
diff --git a/v0.18.15/external/mini-lab/CONTRIBUTING/index.html b/v0.18.15/external/mini-lab/CONTRIBUTING/index.html new file mode 100644 index 0000000000..25be4e125a --- /dev/null +++ b/v0.18.15/external/mini-lab/CONTRIBUTING/index.html @@ -0,0 +1,2 @@ + +Contributing · metal-stack diff --git a/v0.18.15/external/mini-lab/README/index.html b/v0.18.15/external/mini-lab/README/index.html new file mode 100644 index 0000000000..05ccd72c44 --- /dev/null +++ b/v0.18.15/external/mini-lab/README/index.html @@ -0,0 +1,70 @@ + +mini-lab · metal-stack

mini-lab

The mini-lab is a small, virtual setup to locally run the metal-stack. It deploys the metal control plane and a metal-stack partition with two simulated leaf switches. The lab can be used for trying out metal-stack, demonstration purposes or development.

overview components

ℹ This project can also be used as a template for writing your own metal-stack deployments.

<!– TOC depthfrom:2 depthto:6 withlinks:true updateonsave:false orderedlist:false –>

<!– /TOC –>

Requirements

  • Linux machine with hardware virtualization support
  • kvm as hypervisor for the VMs (you can check through the kvm-ok command)
  • docker >= 24.x.y (for using kind and our deployment base image)
  • kind == v0.23.0 (for hosting the metal control plane)
  • containerlab >= v0.56.0
  • the lab creates a docker network on your host machine with the address block 203.0.113.0/24, designated as TEST-NET-3 for documentation and examples.
  • (recommended) haveged to have enough random entropy (only needed if the PXE process does not work)

Here is some code that should help you to set up most of the requirements:

# If UFW enabled.
+# Disable the firewall or allow traffic through Docker network IP range.
+sudo ufw status
+sudo ufw allow from 172.17.0.0/16
+
+# Install kvm
+sudo apt install -y git curl qemu qemu-kvm haveged
+
+# Install Docker
+curl -fsSL https://get.docker.com | sh
+# if you want to be on the safe side, follow the original installation
+# instructions at https://docs.docker.com/engine/install/ubuntu/
+
+# Ensure that your user is member of the group "docker"
+# you need to login again in order to make this change take effect
+sudo usermod -G docker -a ${USER}
+
+# Install containerlab
+bash -c "$(curl -sL https://get.containerlab.dev)"
+
+# Install kind (kubernetes in docker), for more details see https://kind.sigs.k8s.io/docs/user/quick-start/#installation
+sudo curl -Lo /usr/local/bin/kind "https://kind.sigs.k8s.io/dl/v0.20.0/kind-linux-amd64"
+sudo chmod +x /usr/local/bin/kind

The following ports are used statically on your host machine:

PortBind AddressDescription
64430.0.0.0kube-apiserver of the kind cluster
44430.0.0.0HTTPS ingress
41500.0.0.0nsqd
80800.0.0.0HTTP ingress

Known Limitations

  • to keep the demo small there is no EVPN
  • machine restart and destroy does not work because we cannot change the boot order via IPMI in the lab easily (virtual-bmc could, but it's buggy)
  • login to the machines is possible with virsh console, login to the firewall is possible with SSH from your local machine

Try it out

git clone https://github.com/metal-stack/mini-lab.git
+cd mini-lab

Start the mini-lab with a kind cluster, a metal-api instance as well as two containers wrapping leaf switches and another container that hosts two user-allocatable machines:

make
+# containerlab will ask you for root permissions (https://github.com/srl-labs/containerlab/issues/669)

After the deployment and waiting for a short amount of time, two machines in status PXE booting become visible through metalctl machine ls:

docker compose run --rm metalctl machine ls
+
+ID                                          LAST EVENT   WHEN     AGE  HOSTNAME  PROJECT  SIZE          IMAGE  PARTITION
+e0ab02d2-27cd-5a5e-8efc-080ba80cf258        PXE Booting  3s
+2294c949-88f6-5390-8154-fa53d93a3313        PXE Booting  5s

Wait until the machines reach the waiting state:

docker compose run --rm metalctl machine ls
+
+ID                                          LAST EVENT   WHEN     AGE  HOSTNAME  PROJECT  SIZE          IMAGE  PARTITION
+e0ab02d2-27cd-5a5e-8efc-080ba80cf258        Waiting      8s                               v1-small-x86         mini-lab
+2294c949-88f6-5390-8154-fa53d93a3313        Waiting      8s                               v1-small-x86         mini-lab

Create a firewall and a machine with:

make firewall
+make machine

Alternatively, you may want to issue the metalctl commands on your own:

docker compose run --rm metalctl network allocate \
+        --partition mini-lab \
+        --project 00000000-0000-0000-0000-000000000000 \
+        --name user-private-network
+
+# lookup the network ID and create a machine
+docker compose run --rm metalctl machine create \
+        --description test \
+        --name machine \
+        --hostname machine \
+        --project 00000000-0000-0000-0000-000000000000 \
+        --partition mini-lab \
+        --image ubuntu-20.04 \
+        --size v1-small-x86 \
+        --networks <network-ID>
+
+# create a firewall that is also connected to the virtual internet-mini-lab network
+docker compose run --rm metalctl machine create \
+        --description fw \
+        --name fw \
+        --hostname fw \
+        --project 00000000-0000-0000-0000-000000000000 \
+        --partition mini-lab \
+        --image firewall-ubuntu-2.0 \
+        --size v1-small-x86 \
+        --networks internet-mini-lab,$(privatenet)

See the installation process in action

make console-machine01/02
+...
+Ubuntu 20.04 machine ttyS0
+
+machine login:

Two machines are now installed and have status "Phoned Home"

docker compose run --rm metalctl machine ls
+ID                                          LAST EVENT   WHEN   AGE     HOSTNAME  PROJECT                               SIZE          IMAGE                             PARTITION
+e0ab02d2-27cd-5a5e-8efc-080ba80cf258        Phoned Home  2s     21s     machine   00000000-0000-0000-0000-000000000000  v1-small-x86  Ubuntu 20.04 20200331             mini-lab
+2294c949-88f6-5390-8154-fa53d93a3313        Phoned Home  8s     18s     fw        00000000-0000-0000-0000-000000000000  v1-small-x86  Firewall 2 Ubuntu 20200730        mini-lab

Login with user name metal and the console password from

docker compose run --rm metalctl machine consolepassword e0ab02d2-27cd-5a5e-8efc-080ba80cf258

To remove the kind cluster, the switches and machines, run:

make cleanup

Reinstall machine

Reinstall a machine with

docker compose run --rm metalctl machine reinstall \
+        --image ubuntu-20.04 \
+        e0ab02d2-27cd-5a5e-8efc-080ba80cf258

Free machine

Free a machine with make free-machine01 or

docker compose run --rm metalctl machine rm e0ab02d2-27cd-5a5e-8efc-080ba80cf258

Flavors

There's few versions of mini-lab environment that you can run. We call them flavors. There's 2 flavors at the moment:

  • default – runs 2 machines.
  • cluster-api – runs 3 machines. Useful for testing Control plane and worker node deployment with Cluster API provider.
  • sonic – use SONiC as network operating system for the leaves

In order to start specific flavor, you can define the flavor as follows:

export MINI_LAB_FLAVOR=cluster-api
+make

Page Tree

diff --git a/v0.18.15/external/mini-lab/docs/overview.png b/v0.18.15/external/mini-lab/docs/overview.png new file mode 100644 index 0000000000000000000000000000000000000000..43b42fae5ad791ca1b6760941e617af0cc0c58ce GIT binary patch literal 314999 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%0AX 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Μjek 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 +Introduction · metal-stack diff --git a/v0.18.15/installation/deployment/index.html b/v0.18.15/installation/deployment/index.html new file mode 100644 index 0000000000..e3fd984f03 --- /dev/null +++ b/v0.18.15/installation/deployment/index.html @@ -0,0 +1,317 @@ + +Installation · metal-stack

Deploying metal-stack

We are bootstrapping the metal control plane as well as our partitions with Ansible through CI.

In order to build up your deployment, we recommend to make use of the same Ansible roles that we are using by ourselves in order to deploy the metal-stack. You can find them in the repository called metal-roles.

In order to wrap up deployment dependencies there is a special deployment base image hosted on GitHub that you can use for running the deployment. Using this Docker image eliminates a lot of moving parts in the deployment and should keep the footprints on your system fairly small and maintainable.

This document will from now on assume that you want to use our Ansible deployment roles for setting up metal-stack. We will also use the deployment base image, so you should also have Docker installed. It is in the nature of software deployments to differ from site to site, company to company, user to user. Therefore, we can only describe you the way of how the deployment works for us. It is up to you to tweak the deployment described in this document to your requirements.

Warning

Probably you need to learn writing Ansible playbooks if you want to be able to deploy the metal-stack as presented in this documentation. However, even when starting without any knowledge about Ansible it should be possible to follow these docs. In case you need further explanations regarding Ansible please refer to docs.ansible.com.

Info

If you do not want to use Ansible for deployment, you need to come up with a deployment mechanism by yourself. However, you will probably be able to re-use some of our contents from our metal-roles repository, e.g. the Helm chart for deploying the metal control plane.

Tip

You can use the mini-lab as a template project for your own deployment. It uses the same approach as described in this document.

Metal Control Plane Deployment

The metal control plane is typically deployed in a Kubernetes cluster. Therefore, this document will assume that you have a Kubernetes cluster ready for getting deployed. Even though it is theoretically possible to deploy metal-stack without Kubernetes, we strongly advise you to use the described method because we believe that Kubernetes gives you a lot of benefits regarding the stability and maintainability of the application deployment.

Tip

For metal-stack it does not matter where your control plane Kubernetes cluster is located. You can of course use a cluster managed by a hyperscaler. This has the advantage of not having to setup Kubernetes by yourself and could even become beneficial in terms of fail-safe operation. The only requirement from metal-stack is that your partitions can establish network connections to the metal control plane. If you are interested, you can find a reasoning behind this deployment decision here.

Let's start off with a fresh folder for your deployment:

mkdir -p metal-stack-deployment
+cd metal-stack-deployment

At the end of this section we are gonna end up with the following files and folder structures:

.
+├── ansible.cfg
+├── deploy_metal_control_plane.yaml
+├── files
+│   └── certs
+│       ├── ca-config.json
+│       ├── ca-csr.json
+│       ├── metal-api-grpc
+│       │   ├── client.json
+│       │   ├── server.json
+│       ├── masterdata-api
+│       │   ├── client.json
+│       │   ├── server.json
+│       └── roll_certs.sh
+├── inventories
+│   ├── control-plane.yaml
+│   └── group_vars
+│       ├── all
+│       │   └── images.yaml
+│       └── control-plane
+│           ├── common.yaml
+│           └── metal.yml
+├── generate_role_requirements.yaml
+└── roles
+    └── ingress-controller
+        └── tasks
+            └── main.yaml

You can already define the inventories/group_vars/all/images.yaml file. It contains the metal-stack version you are gonna deploy:

---
+metal_stack_release_version: v0.18.15

Releases and Ansible Role Dependencies

As metal-stack consists of many microservices all having individual versions, we have come up with a releases repository. It contains a YAML file (we often call it release vector) describing the fitting versions of all components for every release of metal-stack.

Ansible role dependencies are also part of a metal-stack release. Therefore, we will now write up a playbook, which dynamically renders a requirements.yaml file from the ansible-roles defined in the release repository. The requirements.yaml can then be used to resolve the actual role dependencies through Ansible Galaxy. Define the following playbook in generate_role_requirements.yaml:

---
+- name: generate requirements.yaml
+  hosts: control-plane
+  connection: local
+  gather_facts: false
+  vars:
+    release_vector_url: "https://raw.githubusercontent.com/metal-stack/releases/{{ metal_stack_release_version }}/release.yaml"
+  tasks:
+    - name: download release vector
+      uri:
+        url: "{{ release_vector_url }}"
+        return_content: yes
+      register: release_vector
+
+    - name: write requirements.yaml from release vector
+      copy:
+        dest: "{{ playbook_dir }}/requirements.yaml"
+        content: |
+          {% for role_name, role_params in (release_vector.content | from_yaml).get('ansible-roles').items() %}
+          - src: {{ role_params.get('repository') }}
+            name: {{ role_name }}
+            version: {{ hostvars[inventory_hostname][role_name | lower | replace('-', '_') + '_version'] | default(role_params.get('version'), true) }}
+          {% endfor %}

This playbook will always be run before the actual metal-stack deployment and provide you with the proper versions of the Ansible role dependencies.

Inventory

Then, there will be an inventory for the control plane deployment in inventories/control-plane.yaml that adds the localhost to the control-plane host group:

---
+control-plane:
+  hosts:
+    localhost:
+      ansible_python_interpreter: "{{ ansible_playbook_python }}"

We do this since we are deploying to Kubernetes and do not need to SSH-connect to any hosts for the deployment (which is what Ansible typically does). This inventory is also necessary to pick up the variables inside inventories/group_vars/control-plane during the deployment.

We recommend using the following ansible.cfg:

[defaults]
+retry_files_enabled = false
+force_color = true
+host_key_checking = false
+stdout_callback = yaml
+jinja2_native = true
+transport = ssh
+timeout = 30
+force_valid_group_names = ignore
+
+[ssh_connection]
+retries=3
+ssh_executable = /usr/bin/ssh

Most of the properties in there are up to taste, but make sure you enable the Jinja2 native environment as this is needed for some of our roles in certain cases.

Control Plane Playbook

Next, we will define the actual deployment playbook in a file called deploy_metal_control_plane.yaml. You can start with the following lines:

---
+- name: Deploy Control Plane
+  hosts: control-plane
+  connection: local
+  gather_facts: no
+  vars:
+    setup_yaml:
+      - url: https://raw.githubusercontent.com/metal-stack/releases/{{ metal_stack_release_version }}/release.yaml
+        meta_var: metal_stack_release
+  roles:
+    - name: ansible-common
+      tags: always
+    - name: ingress-controller
+      tags: ingress-controller
+    - name: metal-roles/control-plane/roles/prepare
+      tags: prepare
+    - name: metal-roles/control-plane/roles/nsq
+      tags: nsq
+    - name: metal-roles/control-plane/roles/metal-db
+      tags: metal-db
+    - name: metal-roles/control-plane/roles/ipam-db
+      tags: ipam-db
+    - name: metal-roles/control-plane/roles/masterdata-db
+      tags: masterdata-db
+    - name: metal-roles/control-plane/roles/metal
+      tags: metal

Basically, this playbook does the following:

  • Include all the modules, filter plugins, etc. of ansible-common into the play
  • Deploys an ingress-controller into your cluster
  • Deploys the metal-stack by
    • Running preparation tasks
    • Deploying NSQ
    • Deploying the rethinkdb database for the metal-api (wrapped in a backup-restore-sidecar),
    • Deploying the postgres database for go-ipam (wrapped in a backup-restore-sidecar)
    • Deploying the postgres database for the masterdata-api (wrapped in a backup-restore-sidecar)
    • Applying the metal control plane helm chart

Setup an ingress-controller

As a next step you have to add a task for deploying an ingress-controller into your cluster. nginx-ingress is what we use. If you want to use another ingress-controller, you need to parametrize the metal roles carefully. When you just use ingress-nginx, make sure to also deploy it to the default namespace ingress-nginx.

This is how your roles/ingress-controller/tasks/main.yaml could look like:

- name: Deploy ingress-controller
+  include_role:
+    name: ansible-common/roles/helm-chart
+  vars:
+    helm_repo: "https://helm.nginx.com/stable"
+    helm_chart: nginx-ingress
+    helm_release_name: nginx-ingress
+    helm_target_namespace: ingress-nginx
Tip

The ansible-common repository contains very general roles and modules that you can also use when extending your deployment further.

Deployment Parametrization

Now you can parametrize the referenced roles to fit your environment. The role parametrization can be looked up in the role documentation on metal-roles/control-plane. You should not need to define a lot of variables for the beginning as most values are reasonably defaulted. You can start with the following content for group_vars/control-plane/common.yaml:

---
+metal_control_plane_ingress_dns: <your-dns-domain> # if you do not have a DNS entry, you could also start with <ingress-ip>.nip.io

Providing Certificates

We have several components in our stack that communicate over encrypted gRPC just like Kubernetes components do.

For the very basic setup you will need to create self-signed certificates for the communication between the following components (see architecture document):

Here is a snippet for files/roll_certs.sh that you can use for generating your certificates (requires cfssl):

#!/usr/bin/env bash
+set -eo pipefail
+
+for i in "$@"
+do
+case $i in
+    -t=*|--target=*)
+    TARGET="${i#*=}"
+    shift
+    ;;
+    *)
+    echo "unknown parameter passed: $1"
+    exit 1
+    ;;
+esac
+done
+
+if [ -z "$TARGET" ]; then
+    echo "generating ca cert"
+    cfssl genkey -initca ca-csr.json | cfssljson -bare ca
+    rm *.csr
+fi
+
+if [ -z "$TARGET" ] || [ $TARGET == "grpc" ]; then
+    pushd metal-api-grpc
+    echo "generating grpc certs"
+    cfssl gencert -ca=../ca.pem -ca-key=../ca-key.pem -config=../ca-config.json -profile=server server.json | cfssljson -bare server
+    cfssl gencert -ca=../ca.pem -ca-key=../ca-key.pem -config=../ca-config.json -profile=client client.json | cfssljson -bare client
+    rm *.csr
+    popd
+fi
+
+if [ -z "$TARGET" ] || [ $TARGET == "masterdata-api" ]; then
+    pushd masterdata-api
+    echo "generating masterdata-api certs"
+    rm -f *.pem
+    cfssl gencert -ca=../ca.pem -ca-key=../ca-key.pem -config=../ca-config.json -profile=client-server server.json | cfssljson -bare server
+    cfssl gencert -ca=../ca.pem -ca-key=../ca-key.pem -config=../ca-config.json -profile=client client.json | cfssljson -bare client
+    rm *.csr
+    popd
+fi

Also define the following configurations for cfssl:

  • files/certs/ca-config.json
    {
    +  "signing": {
    +    "default": {
    +      "expiry": "43800h"
    +    },
    +    "profiles": {
    +      "server": {
    +        "expiry": "43800h",
    +        "usages": ["signing", "key encipherment", "server auth"]
    +      },
    +      "client": {
    +        "expiry": "43800h",
    +        "usages": ["signing", "key encipherment", "client auth"]
    +      },
    +      "client-server": {
    +        "expiry": "43800h",
    +        "usages": [
    +          "signing",
    +          "key encipherment",
    +          "client auth",
    +          "server auth"
    +        ]
    +      }
    +    }
    +  }
    +}
  • files/certs/ca-csr.json
    {
    +  "CN": "metal-control-plane",
    +  "hosts": [],
    +  "key": {
    +    "algo": "rsa",
    +    "size": 4096
    +  },
    +  "names": [
    +    {
    +      "C": "DE",
    +      "L": "Munich",
    +      "O": "Metal-Stack",
    +      "OU": "DevOps",
    +      "ST": "Bavaria"
    +    }
    +  ]
    +}
  • files/certs/masterdata-api/client.json
    {
    +  "CN": "masterdata-client",
    +  "hosts": [""],
    +  "key": {
    +    "algo": "ecdsa",
    +    "size": 256
    +  },
    +  "names": [
    +    {
    +      "C": "DE",
    +      "L": "Munich",
    +      "O": "Metal-Stack",
    +      "OU": "DevOps",
    +      "ST": "Bavaria"
    +    }
    +  ]
    +}
  • files/certs/masterdata-api/server.json
    {
    +  "CN": "masterdata-api",
    +  "hosts": [
    +    "localhost",
    +    "masterdata-api",
    +    "masterdata-api.metal-control-plane.svc",
    +    "masterdata-api.metal-control-plane.svc.cluster.local"
    +  ],
    +  "key": {
    +    "algo": "ecdsa",
    +    "size": 256
    +  },
    +  "names": [
    +    {
    +      "C": "DE",
    +      "L": "Munich",
    +      "O": "Metal-Stack",
    +      "OU": "DevOps",
    +      "ST": "Bavaria"
    +    }
    +  ]
    +}
  • files/certs/metal-api-grpc/client.json
    {
    +  "CN": "grpc-client",
    +  "hosts": [""],
    +  "key": {
    +    "algo": "rsa",
    +    "size": 4096
    +  },
    +  "names": [
    +    {
    +      "C": "DE",
    +      "L": "Munich",
    +      "O": "Metal-Stack",
    +      "OU": "DevOps",
    +      "ST": "Bavaria"
    +    }
    +  ]
    +}
  • files/certs/metal-api-grpc/server.json (Fill in your control plane ingress DNS here)
    {
    +  "CN": "metal-api",
    +  "hosts": ["<your-metal-api-dns-ingress-domain>"],
    +  "key": {
    +    "algo": "rsa",
    +    "size": 4096
    +  },
    +  "names": [
    +    {
    +      "C": "DE",
    +      "L": "Munich",
    +      "O": "Metal-Stack",
    +      "OU": "DevOps",
    +      "ST": "Bavaria"
    +    }
    +  ]
    +}

Running the roll_certs.sh bash script without any arguments should generate you the required certificates.

Now Provide the paths to these certificates in group_vars/control-plane/metal.yaml:

---
+metal_masterdata_api_tls_ca: "{{ lookup('file', 'certs/ca.pem') }}"
+metal_masterdata_api_tls_cert: "{{ lookup('file', 'certs/masterdata-api/server.pem') }}"
+metal_masterdata_api_tls_cert_key: "{{ lookup('file', 'certs/masterdata-api/server-key.pem') }}"
+metal_masterdata_api_tls_client_cert: "{{ lookup('file', 'certs/masterdata-api/client.pem') }}"
+metal_masterdata_api_tls_client_key: "{{ lookup('file', 'certs/masterdata-api/client-key.pem') }}"
+
+metal_api_grpc_certs_server_key: "{{ lookup('file', 'certs/metal-api-grpc/server-key.pem') }}"
+metal_api_grpc_certs_server_cert: "{{  lookup('file', 'certs/metal-api-grpc/server.pem') }}"
+metal_api_grpc_certs_client_key: "{{ lookup('file', 'certs/metal-api-grpc/client-key.pem') }}"
+metal_api_grpc_certs_client_cert: "{{  lookup('file', 'certs/metal-api-grpc/client.pem') }}"
+metal_api_grpc_certs_ca_cert: "{{ lookup('file', 'certs/ca.pem') }}"
Tip

For the actual communication between the metal-api and the user clients (REST API, runs over the ingress-controller you deployed before), you can simply deploy a tool like cert-manager into your Kubernetes cluster, which will automatically provide your ingress domains with Let's Encrypt certificates.

Running the Deployment

Finally, it should be possible to run the deployment through a Docker container. Make sure to have the Kubeconfig file of your cluster and set the path in the following command accordingly:

export KUBECONFIG=<path-to-your-cluster-kubeconfig>
+docker run --rm -it \
+  -v $(pwd):/workdir \
+  --workdir /workdir \
+  -e KUBECONFIG="${KUBECONFIG}" \
+  -e K8S_AUTH_KUBECONFIG="${KUBECONFIG}" \
+  -e ANSIBLE_INVENTORY=inventories/control-plane.yaml \
+  metalstack/metal-deployment-base:v0.7.5 \
+  /bin/bash -ce \
+    "ansible-playbook obtain_role_requirements.yaml
+     ansible-galaxy install -r requirements.yaml
+     ansible-playbook deploy_metal_control_plane.yaml"
Tip

If you are having issues regarding the deployment take a look at the troubleshoot document. Please give feedback such that we can make the deployment of the metal-stack easier for you and for others!

Providing Images

After the deployment has finished (hopefully without any issues!), you should consider deploying some masterdata entities into your metal-api. For example, you can add your first machine sizes and operating system images. You can do this by further parametrizing the metal role. We will just add an operating system for demonstration purposes. Add the following variable to your inventories/group_vars/control-plane/common.yaml:

metal_api_images:
+- id: firewall-ubuntu-2.0.20201004
+  name: Firewall 2 Ubuntu 20201004
+  description: Firewall 2 Ubuntu 20201004
+  url: http://images.metal-stack.io/metal-os/master/firewall/2.0-ubuntu/20201004/img.tar.lz4
+  features:
+    - firewall
+- id: ubuntu-20.04.20201004
+  name: Ubuntu 20.04 20201004
+  description: Ubuntu 20.04 20201004
+  url: http://images.metal-stack.io/metal-os/master/ubuntu/20.04/20201004/img.tar.lz4
+  features:
+    - machine

Then, re-run the deployment to apply your changes. Our playbooks are idempotent.

Info

Image versions should be regularly checked for updates.

Setting up metalctl

You can now verify the existence of the operating system images in the metal-api using our CLI client called metalctl. The configuration for metalctl should look like this:

# ~/.metalctl/config.yaml
+---
+current: test
+contexts:
+  test:
+    # the metal-api endpoint depends on your dns name specified before
+    # you can look up the url to the metal-api via the kubernetes ingress
+    # resource with:
+    # $ kubectl get ingress -n metal-control-plane
+    url: <metal-api-endpoint>
+    # in the future you have to change the HMAC to a strong, random string
+    # in order to protect against unauthorized api access
+    # the default hmac is "change-me"
+    hmac: change-me

Issue the following command:

$ metalctl image ls
+ID                              	NAME                          	DESCRIPTION                   	FEATURES	EXPIRATION	STATUS
+ubuntu-19.10.20200331           	Ubuntu 19.10 20200331         	Ubuntu 19.10 20200331         	machine 	89d 23h   	preview

The basic principles of how the metal control plane can be deployed should now be clear. It is now up to you to move the deployment execution into your CI and add things like certificates for the ingress-controller and NSQ.

Setting Up the backup-restore-sidecar

The backup-restore-sidecar can come up very handy when you want to add another layer of security to the metal-stack databases in your Kubernetes cluster. The sidecar takes backups of the metal databases in small time intervals and stores them in a blobstore of a cloud provider. This way your metal-stack setup can even survive the deletion of your Kubernetes control plane cluster (including all volumes getting lost). After re-deploying metal-stack to another Kubernetes clusters, the databases come up with the latest backup data in a matter of seconds.

Checkout the role documentation of the individual databases to find out how to configure the sidecar properly. You can also try out the mechanism from the backup-restore-sidecar repository.

Auth

metal-stack currently supports two authentication methods:

  • dex for providing user authentication through OpenID Connect (OIDC)
  • HMAC auth, typically used for access by technical users (because we do not have service account tokens at the time being)

In the metal-api, we have three different user roles for authorization:

  • Admin
  • Edit
  • View

How the user permissions are used is documented in the technical API docs.

If you decided to set up a dex server, you can parametrize the metal role for using the dex server by defining the variable metal_api_dex_address.

Info

We also have dedicated controllers for using the dex server for Kubernetes clusters when deploying metal-stack along with the Gardener in your environment. The approach is described in further detail in the section Gardener with metal-stack.

Bootstrapping a Partition

Out-Of-Band-Network

To be able to deploy and maintain a metal-stack partition, you need to bootstrap the Out-Of-Band-Network first. Some considerations must be made to fulfill the requirements of our infrastructure, a partition is designed to be:

  • secure
  • fully routable (BGP)
  • scalable
  • resilient
  • deployable via CI/CD jobs
  • accessible from the internet from specific IPs

In order to accomplish this task remotely and in a nearly automatic manner, you have to bootstrap the components in this order:

  1. management firewalls
  2. management servers
  3. management spines
  4. management leaves
  5. leaves, spines and exits

This document assumes that all cabling is done. Here is a quick overview of the architecture:

Out-of-Band-Network

Management Firewalls

As you can see, the management firewalls are the first bastion hosts in a partition to provide access to our infrastructure. There are two of them in each partition to guarantee high availability and load balancing. The very first configuration of these routers has to be done manually to solve the chicken and egg problem that you need the management firewalls in place to deploy the partition. Manually means that we generate a configuration template with ansible that we deploy with copy/paste, and the load, through the machine console. Once the management server has been deployed, we are able to deploy this configuration via CI runner and ansible. For this you need the user and the ssh-key, which is deployed with the configuration file mentioned above. The Edgerouters has to fulfill some requirements including:

  • provide and restrict access to the Out-Of-Band-Network from the internet with a firewall ruleset
  • provide destination NAT to the management server and its IPMI interface
  • provide Onie Boot and ztp via DHCP options for the management spine
  • provide DHCP management addresses for management spine, management server and ipmi interface of the management server
  • Hairpin-NAT for the management server to access itself via its puplic IP, needed by the CI runner to delegate CI Jobs.
  • propagate a default gateway via BGP

Management Servers

The second bastion hosts are the management servers. They are the main bootstrapping components of the Out-Of-Band-Network. They also act as jump hosts for all components in a partition. Once they are installed and deployed, we are able to bootstrap all the other components. To bootstrap the management servers, we generate an ISO image which will automatically install an OS and an ansible user with ssh keys. It is preconfigured with a preseed file to allow an unattended OS installation for our needs. This is why we need remote access to the IPMI interface of the management servers: The generated ISO is attached via the virtual media function of the BMC. After that, all we have to do is boot from that virtual CD-ROM and wait for the installation to finish. Deployment jobs (Gitlab-CI) in a partition are delegated to the appropriate management servers, therefore we need a CI runner active on each management server.

After the CI runner has been installed, you can trigger your Playbooks from the the CI. The Ansible-Playbooks have to make sure that these functionalities are present on the management servers:

  • Prometheus and exporters
  • CI runner
  • metal-bmc
  • image-cache
  • simple webserver to provide images
  • Onie Boot and ZTP
  • DHCP addresses for ipmi interfaces of the workers
  • DHCP addresses for switches

Management Spines

Tip

If you are using SONiC switches, you should make use of Zero Touch Provisioning and Onie Boot

The purpose of these switches is to connect the management interfaces of all switches to the management servers. The management spine's own management interface is connected to the management firewall for the bootstrapping of the management spine itself. The management firewall will provide a DHCP address and DHCP options to start SONiC's Zero Touch Provisioning; the images for all switches are downloaded from the management server (nginx container). Each management leaf is connected to both management spines to provide redundant connectivity to both management servers. BGP is used as a routing protocol such that, when a link goes down, an alternate path is used. In the picture above you can see that there are also switch management interfaces connected to the management spine. This has to be done so that we can bootstrap these switches; the management spine relays the DHCP requests from these switches to the management servers so that they are able to Onie Boot and get their ZTP scripts.

Management Leaves

All workers have to be connected with their IPMI/BMC interface to the management leaves to get DHCP addresses from the management server. The management leaves are relaying those DHCP requests to the management server which will answer the requests and provide IPs from a given range. The management interfaces of the management leaves also have to be reachable from the management server, and need to get their IP address via DHCP for the bootstrapping process.

In the example setup, these interfaces are connected to an end-of-row-switch which aggregates them and connects them to the management spines with a fiber-optics connection. If you can reach the management spines from the management leaves with copper cables, you do not need the end of row switch. After the initial bootstrapping, the management interfaces of the management leaves continue to be used for access to the switches' command line, and for subsequent OS updates. (update=reset+bootrap+deployment)

Partition Deployment

Gardener with metal-stack

If you want to deploy metal-stack as a cloud provider for Gardener, you should follow the regular Gardener installation instructions and setup a Gardener cluster first. It's perfectly fine to setup the Gardener cluster in the same cluster that you use for hosting metal-stack.

You can find installation instructions for Gardener on the Gardener website beneath docs. metal-stack is an out-of-tree provider and therefore you will not find example files for metal-stack resources in the Gardener repositories. The following list describes the resources and components that you need to deploy into the Gardener cluster in order to make Gardener work with metal-stack:

Warning

The following list assumes you have Gardener installed in a Kubernetes cluster and that you have a basic understanding of how Gardener works. If you need further help with the following steps, you can also come and ask in our Slack channel.

  1. Deploy the validator from the gardener-extension-provider-metal repository to your cluster via Helm
  2. Add a cloud profile called metal containing all your machine images, machine types and regions (region names can be chosen freely, the zone names need to match your partition names) together with our metal-stack-specific provider config as defined here
  3. Register the gardener-extension-provider-metal controller by deploying the controller-registration into your Gardener cluster, parametrize the embedded chart in the controller registration's values section if necessary (this is the corresponding values file)
  4. metal-stack does not provide an own backup storage infrastructure for now. If you want to enable ETCD backups (which you should do because metal-stack also does not have persistent storage out of the box, which makes these backups even more valuable), you should deploy an extension-provider of another cloud provider and configure it to only reconcile the backup buckets (you can reference this backup infrastructure used for the metal shoot in the shoot spec)
  5. Register the os-extension-provider-metal controller by deploying the controller-registration into your Gardener cluster, this controller can transform the operating system configuration from Gardener into Ignition user data
  6. You need to use the Gardener's networking-calico controller for setting up shoot CNI, you will have to put specific provider configuration into the shoot spec to make it work with metal-stack:
    networking:
    +  type: calico
    +  # we can peer with the frr within 10.244.0.0/16, which we do with the metallb
    +  # the networks for the shoot need to be disjunct with the networks of the seed, otherwise the VPN connection will not work properly
    +  # the seeds are typically deployed with podCIDR 10.244.128.0/18 and serviceCIDR 10.244.192.0/18
    +  # the shoots are typically deployed with podCIDR 10.244.0.0/18 and serviceCIDR 10.244.64.0/18
    +  pods: 10.244.0.0/18
    +  services: 10.244.64.0/18
    +  providerConfig:
    +    apiVersion: calico.networking.extensions.gardener.cloud/v1alpha1
    +    kind: NetworkConfig
    +    backend: vxlan
    +    ipv4:
    +      pool: vxlan
    +      mode: Always
    +      autoDetectionMethod: interface=lo
    +    typha:
    +      enabled: false
  7. For your seed cluster you will need to provide the provider secret for metal-stack containing the key metalAPIHMac, which is the API HMAC to grant editor access to the metal-api
  8. Checkout our current provider configuration for infrastructure and control-plane before deploying your shoot
Tip

We are officially supported by Gardener dashboard. The dashboard can also help you setting up some of the resources mentioned above.

diff --git a/v0.18.15/installation/mgmt_net_layer3.drawio b/v0.18.15/installation/mgmt_net_layer3.drawio new file mode 100644 index 0000000000..2edade7233 --- /dev/null +++ b/v0.18.15/installation/mgmt_net_layer3.drawio @@ -0,0 +1 @@ +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 \ No newline at end of file diff --git a/v0.18.15/installation/mgmt_net_layer3.png b/v0.18.15/installation/mgmt_net_layer3.png new file mode 100644 index 0000000000000000000000000000000000000000..e2e455f99e5d1f09f0125dfab43994c45d4a7fc2 GIT binary patch literal 298312 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

c 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%0A= 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 VYmK8^%G?A0q$T9V3q +Monitoring · metal-stack

Monitoring the metal-stack

We are currently working on providing the sources of our monitoring deployment for public usage. Please come back later.

diff --git a/v0.18.15/installation/troubleshoot/index.html b/v0.18.15/installation/troubleshoot/index.html new file mode 100644 index 0000000000..142d8dc4ae --- /dev/null +++ b/v0.18.15/installation/troubleshoot/index.html @@ -0,0 +1,35 @@ + +Troubleshoot · metal-stack

Troubleshoot

This document summarizes help when something goes wrong and provides advice on debugging the metal-stack in certain situations.

Of course, it is also advisable to check out the issues on the Github projects for help.

If you still can't find a solution to your problem, please reach out to us and our community. We have a public Slack Channel to discuss problems, but you can also reach us via mail. Check out metal-stack.io for contact information.

Deployment

Ansible fails when the metal control plane helm chart gets applied

There can be many reasons for this. Since you are deploying the metal control plane into a Kubernetes cluster, the first step should be to install kubectl and check the pods in your cluster. Depending on the metal-stack version and Kubernetes cluster, your control-plane should look something like this after the deployment (this is in a Kind cluster):

kubectl get pod -A
+NAMESPACE             NAME                                         READY   STATUS      RESTARTS   AGE
+ingress-nginx         nginx-ingress-controller-56966f7dc7-khfp9    1/1     Running     0          2m34s
+kube-system           coredns-66bff467f8-grn7q                     1/1     Running     0          2m34s
+kube-system           coredns-66bff467f8-n7n77                     1/1     Running     0          2m34s
+kube-system           etcd-kind-control-plane                      1/1     Running     0          2m42s
+kube-system           kindnet-4dv7m                                1/1     Running     0          2m34s
+kube-system           kube-apiserver-kind-control-plane            1/1     Running     0          2m42s
+kube-system           kube-controller-manager-kind-control-plane   1/1     Running     0          2m42s
+kube-system           kube-proxy-jz7kp                             1/1     Running     0          2m34s
+kube-system           kube-scheduler-kind-control-plane            1/1     Running     0          2m42s
+local-path-storage    local-path-provisioner-bd4bb6b75-cwfb7       1/1     Running     0          2m34s
+metal-control-plane   ipam-db-0                                    2/2     Running     0          2m31s
+metal-control-plane   masterdata-api-6dd4b54db5-rwk45              1/1     Running     0          33s
+metal-control-plane   masterdata-db-0                              2/2     Running     0          2m29s
+metal-control-plane   metal-api-998cb46c4-jj2tt                    1/1     Running     0          33s
+metal-control-plane   metal-api-initdb-r9sc6                       0/1     Completed   0          2m24s
+metal-control-plane   metal-api-liveliness-1590479940-brhc7        0/1     Completed   0          6s
+metal-control-plane   metal-console-7955cbb7d7-p6hxp               1/1     Running     0          33s
+metal-control-plane   metal-db-0                                   2/2     Running     0          2m34s
+metal-control-plane   nsq-lookupd-5b4ccbfb64-n6prg                 1/1     Running     0          2m34s
+metal-control-plane   nsqd-6cd87f69c4-vtn9k                        2/2     Running     0          2m33s

If there are any failing pods, investigate those and look into container logs. This information should point you to the place where the deployment goes wrong.

Info

Sometimes, you see a helm errors like "no deployed releases" or something like this. When a helm chart fails after the first deployment it could be that you have a chart installation still pending. Also, the control plane helm chart uses pre- and post-hooks, which creates jobs that helm expects to be completed before attempting another deployment. Delete the helm chart (use Helm 3) with helm delete -n metal-control-plane metal-control-plane and delete the jobs in the metal-control-plane namespace before retrying the deployment.

In the mini-lab the control-plane deployment fails because my system can't resolve api.172.17.0.1.nip.io

The control-plane deployment returns an error like this:

deploy-control-plane | fatal: [localhost]: FAILED! => changed=false
+deploy-control-plane |   attempts: 60
+deploy-control-plane |   content: ''
+deploy-control-plane |   elapsed: 0
+deploy-control-plane |   msg: 'Status code was -1 and not [200]: Request failed: <urlopen error [Errno -5] No address associated with hostname>'
+deploy-control-plane |   redirected: false
+deploy-control-plane |   status: -1
+deploy-control-plane |   url: http://api.172.17.0.1.nip.io:8080/metal/v1/health
+deploy-control-plane |
+deploy-control-plane | PLAY RECAP *********************************************************************
+deploy-control-plane | localhost                  : ok=29   changed=4    unreachable=0    failed=1    skipped=7    rescued=0    ignored=0
+deploy-control-plane |
+deploy-control-plane exited with code 2

Some home routers have a security feature that prevents DNS Servers to resolve anything in the router's local IP range (DNS-Rebind-Protection).

You need to add an exception for nip.io in your router configuration or add 127.0.0.1 api.172.17.0.1.nip.io to your /etc/hosts.

FritzBox

Home Network -> Network -> Network Settings -> Additional Settings -> DNS Rebind Protection -> Host name exceptions -> nip.io

Operations

Fixing Machine Issues

The metalctl machine issues command gives you an overview over machines in your metal-stack environment that are in an unusual state.

Tip

Machines that are known not to function properly, should be locked through metalctl machine lock and annotated with a description of the problem. This way, you can mark machine for replacement without being in danger of having a user allocating the faulty machine.

In the following sections, you can look up the machine issues that are returned by metalctl and find out how to deal with them properly.

no-event-container

Every machine in the metal-stack database usually has a corresponding event container where provisioning events are stored. This database entity gets created lazily as soon as a machine is registered by the metal-hammer or a provisioning event for the machine arrives at the metal-api.

When there is no event container, this means that the machine has never registered nor received a provisioning event. As an operator you should evaluate why this machine is not booting into the metal-hammer.

This issue is special in a way that it prevents other issues from being evaluated for this machine because the issue calculation usually requires information from the machine event container.

no-partition

When a machine has no partition, the metal-hammer has not yet registered the machine at the metal-api. Instead, the machine was created through metal-stack's event machinery, which does not have a lot of information about a machine (e.g. a PXE boot event was reported from the pixiecore), or just by the metal-bmc which discovered the machine through DHCP.

This can usually happen on the very first boot of a machine and the machine's hardware is not supported by metal-stack, leading to the metal-bmc being unable to report BMC details to the metal-api (a metal-bmc report sets the partition id of a machine) and the metal-hammer not finishing the machine registration phase.

To resolve this issue, you need to identify the machine in your metal-stack partition that emits PXE boot events and find the reason why it is not properly booting into the metal-hammer. The console logs of this machine should enable you to find out the root cause.

liveliness-dead

For machines without an allocation, the metal-hammer consistently reports whether a machine is still being responsive or not. When the liveliness is Dead, there were no events received from this machine for longer than ~5 minutes.

Reasons for this can be:

  • The network connection between the partition and metal-stack control plane is interrupted
  • The machine was removed from your data center
  • The machine has changed its UUID metal-hammer#52
  • The machine is turned off
  • The machine hangs / freezes
  • The machine booted to BIOS or UEFI shell and does not try to PXE boot again
  • The issue only appears temporarily
    • The machine takes longer than 5 minutes for the reboot
    • The machine is performing a firmware upgrade, which usually takes longer than 5 minutes to succeed
Info

In order to minimize maintenance overhead, a machine which is dead for longer than an hour will be rebooted through the metal-api.

In case you want to prevent this action from happening for a machine, you can lock the machine through metalctl machine lock.

If the machine is dead for a long time and you are sure that it will never come back, you can clean up the machine through metalctl machine rm --remove-from-database.

liveliness-unknown

For machines that are allocated by a user, the ownership has gone over to this user and as an operator you cannot access the machine anymore. This makes it harder to detect whether a machine is in a healthy state or not. Typically, all official metal-stack OS images deploy an LLDP daemon, that consistently emits alive messages. These messages are caught by the metal-core and turned into a Phoned Home event. Internally, the metal-api uses these events as an indicator to decide whether the machine is still responsive or not.

When the LLDP daemon stopped sending packages, the reasons are identical to those of dead machines. However, it's not possible anymore to decide whether the user is responsible for reaching this state or not.

In most of the cases, there is not much that can be done from the operator's perspective. You will need to wait for the user to report an issue with the machine. When you do support, you can use this issue type to quickly identify this machine.

liveliness-not-available

This is more of a theoretical issue. When the machine liveliness is not available check that the Kubernetes CronJob in the metal-stack control plane for evaluating the machine liveliness is running regularly and not containing error logs. Make the machine boot into the metal-hammer and this issue should not appear.

failed-machine-reclaim

If a machine remains in the Phoned Home state without having an allocation, this indicates that the metal-bmc was not able to put the machine back into PXE boot mode after metalctl machine rm. The machine is still running the operating system and it does not return back into the allocatable machine pool. Effectively, you lost a machine in your environment and no-one pays for it. Therefore, you should resolve this issue as soon as possible.

In bad scenarios, when the machine was a firewall, the machine can still reach the internet through the PXE boot network and also attract traffic, which it cannot route anymore inside the tenant VRF. This can cause traffic loss inside a tenant network.

In most of the cases, it should be sufficient to run another metalctl machine rm on this machine in order to retry booting into PXE mode. If this still does not succeed, you can boot the machine into the BIOS and manually and change the boot order to PXE boot. This should force booting the metal-hammer again and add the machine back into your pool of allocatable machines.

For further reference, see metal-api#145.

crashloop

Under bad circumstances, a machine diverges from its typical machine lifecycle. When this happens, the internal state-machine of the metal-api detects that the machine reboots unexpectedly during the provisioning phase. It is likely that the machine has entered a crash loop where it PXE boots again and again without the machine ever becoming usable.

Reasons for this can be:

  • The machine's hardware is not supported and the metal-hammer crashes during the machine discovery
  • The machine registration fails through the metal-hammer because an orphaned / dead machine is still present in the metal-api's data base. The machine is connected to the same switch ports that were used by the orphaned machine. In this case, you should clean up the orphaned machine through metalctl machine rm --remove-from-database.

Please also consider console logs of the machine for investigating the issue.

The incomplete cycle count is reset as soon as the machine reaches Phoned Home state or there is a Planned Reboot of the machine (planned reboot is also done by the metal-hammer once a day in order to reboot with the latest version).

last-event-error

The machine had an error during the provisioning lifecycle recently or events are arriving out of order at the metal-api. This can be an interesting hint for the operator that something during machine provisioning went wrong. You can look at the error through metalctl machine describe or metalctl machine logs.

This error will disappear after a certain time period from machine issues. You can still look up the error as described above.

asn-not-unique

This issue was introduced by a bug in earlier versions of metal-stack and was fixed in PR105

To resolve the issue, you need to recreate the firewalls that use the same ASN.

bmc-without-mac

The metal-bmc is responsible to report connection data for the machine's BMC.

If it's uncapable of discovering this information, your hardware might not be supported. Please investigate the logs of the metal-bmc to find out what's going wrong with this machine.

bmc-without-ip

The metal-bmc is responsible to report connection data for the machine's BMC.

If it's uncapable of discovering this information, your hardware might not be supported. Please investigate the logs of the metal-bmc to find out what's going wrong with this machine.

bmc-no-distinct-ip

The metal-bmc is responsible to report connection data for the machine's BMC.

When there is no distinct IP address for the BMC, it can be that an orphaned machine used this IP in the past. In this case, you need to clean up the orphaned machine through metalctl machine rm --remove-from-database.

bmc-info-outdated

The metal-bmc is responsible to report bmc details for the machine's BMC.

When the metal-bmc was not able to fetch the bmc info for longer than 20 minutes, something is wrong with the BMC configuration of the machine. This can be caused by one of the following reasons:

  • Wrong password for the root user is configured in the BMC
  • ip address of the BMC is either wrong or not present
  • the device on the given ip address is not a machine, maybe a switch or a management component which is not managed by the metal-api

In either case, please check the logs for the given machine UUID on the metal-bmc for further details. Also check that the metal-bmc is configured to only consider BMC IPs in the range they are configured from the DHCP server in the partition. This prevents grabbing unrelated BMCs.

A machine has registered with a different UUID after reboot

metal-stack heavily relies on steady machine UUIDs as the UUID is the primary key of the machine entity in the metal-api.

For further reference also see metal-stack/metal-hammer#52.

Reasons

There are some scenarios (can be vendor-specific), which can cause a machine UUID to change over time, e.g.:

  • When the UUID partly contains of a network card's mac address, it can happen when:
    • Exchanging network cards
    • Disabling network cards through BIOS
  • Changing the UUID through vendor-specific CLI tool

Solution

  1. After five minutes, the orphaned machine UUID will be marked dead (💀) because machine events will be sent only to the most recent UUID
  2. Identify the dead machine through metalctl machine ls
  3. Remove the dead machine forcefully with metalctl machine rm --remove-from-database --yes-i-really-mean-it <uuid>

Fixing Switch Issues

switch-sync-failing

For your network infrastructure it is key to adapt to new configuration. In case this sync process fails for more than 10 minutes, it is likely to require manual investigation.

Depending on your switch operating system, the error sources might differ a lot. Try to connect to your switch using the console or ssh and investigate the logs. Check if the hard drive is full.

diff --git a/v0.18.15/installation/updates/index.html b/v0.18.15/installation/updates/index.html new file mode 100644 index 0000000000..7c41bd03bd --- /dev/null +++ b/v0.18.15/installation/updates/index.html @@ -0,0 +1,2 @@ + +Releases and Updates · metal-stack

Releases and Updates

Your are currently reading the documentation for the metal-stack v0.18.15 release.

Releases and integration tests are published through our release repository. You can also find the release notes for this metal-stack version in there. The release notes contain information about new features, upgrade paths and bug fixes.

If you want, you can sign up at our Slack channel where we are announcing every new release. Often, we provide additional information for metal-stack administrators and adopters at this place, too.

Update Policy

For new features and breaking changes we create a new minor release of metal-stack. For every minor release we present excerpts of the changes in a corresponding blog article published on metal-stack.io. It is not necessary to cycle through the patch releases if you depend on the pure metal-stack components.

In case you depend on the Gardener integration though, especially when using metal-stack roles for deploying Gardener, it may be necessary to cycle through the patch release versions of our metal-stack releases. We regularly increment our Gardener dependency version by version which is the recommended way to update Gardener.

Warning

If you use the Gardener integration of metal-stack do not skip patch releases.

diff --git a/v0.18.15/objects.inv b/v0.18.15/objects.inv new file mode 100644 index 0000000000000000000000000000000000000000..ffeb623b854d0d2451d089b9762c4058f5fbb6d4 GIT binary patch literal 7940 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 literal 0 HcmV?d00001 diff --git a/v0.18.15/overview/2-layer-leaf-spine.drawio b/v0.18.15/overview/2-layer-leaf-spine.drawio new file mode 100644 index 0000000000..7412dc92e3 --- /dev/null +++ b/v0.18.15/overview/2-layer-leaf-spine.drawio @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/v0.18.15/overview/2-layer-leaf-spine.svg b/v0.18.15/overview/2-layer-leaf-spine.svg new file mode 100644 index 0000000000..6806230e2d --- /dev/null +++ b/v0.18.15/overview/2-layer-leaf-spine.svg @@ -0,0 +1 @@ +
Spine 1
Spine 1
Spine 2
Spine 2
Leaf 2
Leaf 2
Leaf 1
Leaf 1
Viewer does not support full SVG 1.1
\ No newline at end of file diff --git a/v0.18.15/overview/3-layer-leaf-spine.drawio b/v0.18.15/overview/3-layer-leaf-spine.drawio new file mode 100644 index 0000000000..fbdb6eae62 --- /dev/null +++ b/v0.18.15/overview/3-layer-leaf-spine.drawio @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/v0.18.15/overview/3-layer-leaf-spine.svg b/v0.18.15/overview/3-layer-leaf-spine.svg new file mode 100644 index 0000000000..40a4c28ecb --- /dev/null +++ b/v0.18.15/overview/3-layer-leaf-spine.svg @@ -0,0 +1 @@ +
Spine 1
Spine 1
Spine 2
Spine 2
Leaf 2
Leaf 2
Leaf 1
Leaf 1
Machine 2
Machine 2
Machine 1
Machine 1
Viewer does not support full SVG 1.1
\ No newline at end of file diff --git a/v0.18.15/overview/architecture/index.html b/v0.18.15/overview/architecture/index.html new file mode 100644 index 0000000000..845f2b36a3 --- /dev/null +++ b/v0.18.15/overview/architecture/index.html @@ -0,0 +1,4 @@ + +Architecture · metal-stack

Architecture

The metal-stack is a compound of microservices predominantly written in Golang.

This page gives you an overview over which microservices exist, how they communicate with each other and where they are deployed.

Target Deployment Platforms

For our environments, we chose to deploy the metal-stack into a Kubernetes cluster. This means that also our entire installation was developed for metal-stack being run on Kubernetes. Running applications on Kubernetes gives you a lot of benefits regarding ease-of-deployment, scalability, reliability and so on.

However, very early we decided that we do not want to depend on technical Kubernetes functionality with our software (i.e. we did not implement the stack "kube-native" by using controllers and Kubernetes CRDs and things like that). With the following paragraph we want to point out the reasoning behind this "philosophical" decision that may sound conservative at first glance. But not relying on Kubernetes technology:

  • Makes deployments of the stack without Kubernetes theoretically possible.
    • We believe that cloud providers should be able to act beneath Kubernetes
    • This way it is possible to use metal-stack for providing your own Kubernetes offering without relying on Kubernetes yourself (breaks the chicken-egg problem)
  • Follows an important claim in microservice development: "Be agnostic to your choice of technology"
    • For applications that are purely made for being run on Kubernetes, it does not matter to rely on this technology (we even do the same a lot with our applications that integrate the metal-stack with Gardener) but as soon as you start using things like the underlying reconciliation abilities (which admittedly are fanstatic) you are locking your code into a certain technology
    • We don't know what comes after Kubernetes but we believe that a cloud offering should have the potential to survive a choice of technology
    • By this decision we ensured that we can migrate the stack to another future technology and survive the change

One more word towards determining the location for your metal control plane: It is not strictly required to run the control plane inside the same data center as your servers. It even makes sense not to do so because this way you can place your control plane and your servers into a different failure domains, which makes your installation more robust to data center meltdown. Externally hosting the control plane brings you up and running quickly plus having the advantage of higher security through geo-distribution.

Metal Control Plane

The foundation of the metal-stack is what we call the metal control plane.

The control plane contains a couple of essential microservices for the metal-stack including:

  • metal-api The API to manage control plane resources like machines, switches, operating system images, machine sizes, networks, IP addresses and more. The exposed API is an old-fashioned REST API with different authentication methods. The metal-api stores the state of these entities in a RethinkDB database. The metal-api also has its own IP address management (go-ipam), which writes IP address and network allocations into a PostgreSQL backend.
  • masterdata-api Manages tenant and project entities, which can be described as entities used for company-specific resource separation and grouping. Having these "higher level entities" managed by a separate microservice was a design choice that allows to re-use the information by other microservices without having them to know the metal-api at all. The masterdata gets persisted in a dedicated PostgreSQL database.
  • metal-console Provides access for users to a machine's serial console via SSH. It can be seen as an optional component.
  • nsq A message queuing system (not developed by the metal-stack) used for decoupling microservices and distributing tasks.

The following figure shows the relationships between these microservices:

Metal Control Plane

Figure 1: The metal control plane deployed in a Kubernetes environment with an ingress-controller exposing additional services via service exposal.

Some notes on this picture:

  • Users can access the metal-api with the CLI client called metalctl.
  • You can programmatically access the metal-api with client libraries (e.g. metal-go).
  • Our databases are wrapped in a specially built backup-restore-sidecar, which is consistently backing up the databases in external blob storage.
  • The metal-api can be scaled out using replicas when being deployed in Kubernetes.

Partitions

A partition is our term for describing hardware in the data center controlled by the metal-stack with all the hardware participating in the same network topology. Being in the same network topology causes the hardware inside a partition to build a failure domain. Even though the network topology for running the metal-stack is required to be redundant by design, you should consider setting up multiple partitions. With multiple partitions it is possible for users to maintain availability of their applications by spreading them across the partitions. Installing partitions in multiple data centers would be even better in regards of fail-safe application performance, which would even tolerate the meltdown of a data center.

Tip

In our setups, we encode the name of a region and a zone name into our partition names. However, we do not have dedicated entities for regions and zones in our APIs.

A region is a geographic area in which data centers are located.

Zones are geographic locations in a region usually in different fire compartments. Regions can consist of several zones.

A zone can consist of several partitions. Usually, a partition spans a rack or a group of racks.

We strongly advise to group your hardware into racks that are specifically assembled for running metal-stack. When using modular rack design, the amount of compute resources of a partition can easily be extended by adding more racks to your partition.

Info

The hardware that we currently support to be placed inside a partition is described in the hardware document.

Info

How large you can grow your partitions and how the network topology inside a partition looks like is described in the networking document.

The metal-stack has microservices running on the leaf switches in a partition. For this reason, your leaf switches are required to run a Linux distribution that you have full access to. Additionally, there are a servers not added to the pool of user-allocatable machines, which are instead required for running metal-stack and we call them management servers. We also call the entirety of switches inside a partition the switch plane.

The microservices running inside a partition are:

  • metal-hammer (runs on a server when not allocated by user, often referred to as discovery image) An initrd, which is booted up in PXE mode, preparing and registering a machine. When a user allocates a machine, the metal-hammer will install the target operating system on this machine and kexec into the new operating system kernel.
  • metal-core (runs on leaf switches) Dynamically configures the leaf switch from information provided by the metal-api. It also proxies requests from the metal-hammer to the metal-api including publishment of machine lifecycle events and machine registration requests.
  • pixiecore (preferably runs on management servers, forked by metal-stack) Provides the capability of PXE booting servers in the PXE boot network.
  • metal-bmc (runs on management servers) Reports the ip addresses that are leased to ipmi devices together with their machine uuids to the metal-api. This provides machine discovery in the partition machines and keeps all IPMI interface access data up-to-date. Also forwards metal-console requests to the actual machine, allowing user access to the machine's serial console. Furthermore it processes firmware updates and power on/off, led on/off, boot order changes.

Partition

Figure 2: Simplified illustration of services running inside a partition.

Some notes on this picture:

  • This figure is slightly simplified. The switch plane consists of spine switches, exit routers, management firewalls and a bastion router with more software components deployed on these entities. Please refer to the networking document to see the full overview over the switch plane.
  • The image-cache is an optional component consisting of multiple services to allow caching images from the public image store inside a partition. This brings increased download performance on machine allocation and increases independence of a partition on the internet connection.

Complete View

The following figure shows several partitions connected to a single metal control plane. Of course, it is also possible to have multiple metal control planes, which can be useful for staging.

metal-stack

Figure 3: Reduced view on the communication between the metal control plane and multiple partitions.

Some notes on this picture:

  • By design, a partition only has very few ports open for incoming-connections from the internet. This contributes to a smaller attack surface and higher security of your infrastructure.
  • With the help of NSQ, it is not required to have connections from the metal control plane to the metal-core. The metal-core instances register at the message bus and can then consume partition-specific topics, e.g. when a machine deletion gets issued by a user.

Machine Provisioning Sequence

The following sequence diagram illustrates some of the main principles of the machine provisioning lifecycle.

provisioning sequence

Figure 4: Sequence diagram of the machine provisioning sequence.

Here is a video showing a screen capture of a machine's serial console while running the metal-hammer in "wait mode". Then, a user allocates the machine and the metal-hammer installs the target operating system and the machine boots into the new operating system kernel via the kexec system call.

+ +
diff --git a/v0.18.15/overview/comparison/index.html b/v0.18.15/overview/comparison/index.html new file mode 100644 index 0000000000..a5b06859c5 --- /dev/null +++ b/v0.18.15/overview/comparison/index.html @@ -0,0 +1,2 @@ + +Comparison · metal-stack

Comparison with Commercial Solutions

As metal-stack is the foundation to build Kubernetes clusters on premise on bare metal, there are several commercial solutions available which offer management of Kubernetes. In this document we describe the differences between some of the most popular solutions. It´s is not a complete list.

Comparison between Gardener on Metal Stack and Openshift running on VMWare.

Gardener

Gardener is a Kubernetes cluster manager to organize a fleet of Kubernetes clusters at scale. It is designed to scale to thousands of clusters at a variety of IaaS Providers regardless where - in the cloud or on premise, virtualized or bare metal. It not only manages the creation and deletion of Kubernetes clusters, it also takes care of updating or upgrading Kubernetes and the operating system of the involved worker nodes in a automatic manner. Gardener is designed cloud-native and as such, it defines clusters, workers and all other components as Kubernetes resources (like pods and deployments) and reconciles these resources to the desired state.

Kubernetes

Kubernetes is the de facto open-source standard for container scheduling and orchestration in the data center.

Openshift

A fork of Kubernetes with proprietary addons, created by RedHat. For all details see: https://en.wikipedia.org/wiki/OpenShift.

metal-stack

Is an IaaS provider for bare metal focused to create Kubernetes cluster on premise. Gardener support is built in.

VMWare

The most used virtualization technology in the enterprise data centers.

Comparison of Gardener on Metal Stack vs. Openshift on VMWare

FeatureGardener on Metal StackOpenshift on VMWare
Container Runtimedocker, containerd, gvisorcri-o
Host Operating SystemUbuntu, Debian , also see OSRHEL, Fedora-Core
Network PluginsCalico, Cilium(soon)Openshift SDN
StorageLocal NVME, Lightbits NVMEoTCP, all CSI compatible Solutions, also see StorageCSI compatible
LoadbalancingBGP built inrequires extra HW like F5, VMWare NSX
IO at Native SpeedPods run on bare metalall IO must go through the Hypervisor
Hard MultitenancyWorkers, firewall and load balancers are dedicated for every cluster on bare metalShared virtualization hosts, shared load balancers
UIGardener DashboardOpenshift Console
Multi-cluster managementYes (through Gardener)Requires extra licences SW: Redhat Advanced Cluster Manager
Automatic Kubernetes UpdatesYesYes
Automatic Worker Nodes UpdatesYesYes
Supported IaaS ProvidersGCP, AWS, Azure, Alibaba, Openstack, VMWare, metal-stack and moreGCP, AWS, Azure Openstack, VMWare
Monitoring / Logging StackGrafana/Loki, Kibana/ElasticKibana/Elastic
GitOPSTool of choice via Helm InstallOpenshift GitOPS
Container Registryall public accessible registries, private deployed registry of choiceall public accessible registries, in cluster registry
CI/CDTool of choice via Helm InstallJenkins
SecurityK8s control plane isolated from tenant, PSP enabled by defaultStrong cluster defaults
CNCF Kubernetes certifiedYes (Gardener)Yes
Local developmentminikube, kindminishift
Proprietary extensionsNoDeploymentConfig and others
kubectl accessYesYes
diff --git a/v0.18.15/overview/evpn-vtep.drawio b/v0.18.15/overview/evpn-vtep.drawio new file mode 100644 index 0000000000..5c28d97886 --- /dev/null +++ b/v0.18.15/overview/evpn-vtep.drawio @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/v0.18.15/overview/evpn-vtep.svg b/v0.18.15/overview/evpn-vtep.svg new file mode 100644 index 0000000000..5e71d814cf --- /dev/null +++ b/v0.18.15/overview/evpn-vtep.svg @@ -0,0 +1 @@ +
leaf 1
leaf 1
«VLAN aware»
Bridge
«VLAN aware»...
lo: 10.0.0.41
lo: 10.0.0.41
vrf 104001
vrf 104001
«SVI»
vlan4001
«SVI»...
swp1
swp1
vni104001

VXLAN-Interface
VTEP-Endpoint: 10.0.0.41
vni104001...
Device 1
Device 1
Viewer does not support full SVG 1.1
\ No newline at end of file diff --git a/v0.18.15/overview/gpu-support/index.html b/v0.18.15/overview/gpu-support/index.html new file mode 100644 index 0000000000..50411ce51e --- /dev/null +++ b/v0.18.15/overview/gpu-support/index.html @@ -0,0 +1,23 @@ + +GPU Support · metal-stack

GPU Support

For workloads which require the assistance of GPUs, support for GPUs in bare metal servers was added to metal-stack.io v0.18.0.

GPU Operator installation

With the nvidia image a worker has basic GPU support. This means that the required kernel driver, the containerd shim and the required containerd configuration are already installed and configured.

To enable Pods that require GPU support to be scheduled on a worker node with a GPU, a `gpu-operator' must be installed. This has to be done by the cluster owner after the cluster is up and running.

The simplest way to install this operator is as follows:

helm repo add nvidia https://helm.ngc.nvidia.com/nvidia
+helm repo update
+
+kubectl create ns gpu-operator
+kubectl label --overwrite ns gpu-operator pod-security.kubernetes.io/enforce=privileged
+
+helm install --wait \
+  --generate-name \
+  --namespace gpu-operator \
+  --create-namespace \
+    nvidia/gpu-operator \
+    --set driver.enabled=false \
+    --set toolkit.enabled=false

After that kubectl describe node must show the gpu in the capacity like so:

...
+Capacity:
+  cpu:                64
+  ephemeral-storage:  100205640Ki
+  hugepages-1Gi:      0
+  hugepages-2Mi:      0
+  memory:             263802860Ki
+  nvidia.com/gpu:     1
+  pods:               510
+...

With this basic installation, the worker node is ready to process GPU workloads.

Warning

However, there is a caveat - only one 'Pod' can access the GPU. If this is all you need, no additional configuration is required. On the other hand, if you are planning to deploy multiple applications that require GPU support, and there are not that many GPUs available, you will need to configure the gpu-operator to allow the GPU to be shared between multiple Pods.

There are several approaches to sharing GPUs, please consult the official Nvidia documentation for further reference.

https://developer.nvidia.com/blog/improving-gpu-utilization-in-kubernetes https://docs.nvidia.com/datacenter/cloud-native/gpu-operator/latest/gpu-operator-mig.html https://docs.nvidia.com/datacenter/cloud-native/gpu-operator/latest/gpu-sharing.html

With this, happy AI processing.

diff --git a/v0.18.15/overview/hardware/index.html b/v0.18.15/overview/hardware/index.html new file mode 100644 index 0000000000..af72a737cb --- /dev/null +++ b/v0.18.15/overview/hardware/index.html @@ -0,0 +1,2 @@ + +Hardware Support · metal-stack

Hardware Support

In order to keep the automation and maintenance overhead small, we strongly advise against building highly heterogeneous environments with metal-stack. Having a lot of different vendors and server models in your partitions will heavily increase the time and effort for introducing metal-stack in your infrastructure. From experience we can tell that the interfaces for automating hardware provisioning are usually inconsistent between vendors and even between server models of the same vendor. Therefore, we encourage adopters to start off with only a small amount of machine types. If you want to be on the safe side, you should consider buying the hardware that we officially support.

We came up with a repository called go-hal, which includes the interface required for metal-stack to support a machine vendor. If you plan to implement support for new vendors, please check out this repository and contribute back your efforts in order to make the community benefit from extended vendor support as well.

Servers

The following server types are officially supported and verified by the metal-stack project:

VendorSeriesModelBoard TypeStatus
SupermicroBig-TwinSYS-2029BT-HNRX11DPT-Bstable
SupermicroBig-TwinSYS-220BT-HNTRX12DPT-B6stable
SupermicroSuperServerSSG-5019D8-TR12PX11SDV-8C-TP8Fstable
SupermicroSuperServer2029UZ-TN20R25MX11DPUstable
SupermicroSuperServerSYS-621C-TN12RX13DDW-Astable
SupermicroMicrocloud5039MD8-H8TNRX11SDD-8C-Fstable
LenovoThinkSystemSD530alpha

Other server series and models might work but were not reported to us.

GPUs

The following GPU types are officially supported and verified by the metal-stack project:

VendorModelStatus
NVIDIARTX 6000stable

Other GPU models might work but were not reported to us. For a detailed description howto use GPU support in a kubernetes cluster please check this documentation

Switches

The following switch types are officially supported and verified by the metal-stack project:

VendorSeriesModelOSStatus
Edge-CoreAS7700 SeriesAS7712-32XCumulus 3.7.13stable
Edge-CoreAS7700 SeriesAS7726-32XCumulus 4.1.1stable
Edge-CoreAS7700 SeriesAS7712-32XEdgecore SONiCstable
Edge-CoreAS7700 SeriesAS7726-32XEdgecore SONiCstable

Other switch series and models might work but were not reported to us.

Warning

On our switches we run SONiC. The metal-core writes network configuration specifically implemented for this operating system. Please also consider running SONiC on your switches if you do not want to run into any issues with networking.

Our previous support for Cumulus Linux will come to an end.

Of course, contributions for supporting other switch vendors and operating systems are highly appreciated.

Portable metal-stack Setup DIY

A minimal physical hardware setup may contain at least the following components:

Warning

This setup should work as the components are very similar to the currently supported ones but it's currently untested.

#VendorSeriesModelFunction
2xEdge-CoreAS5500 SeriesAS5512-54x (10G)Leaf / Exit switches
1xSupermicroMicrocloudSYS-5039MA16-H12RFTUsable machines
1xUnifiEdgemaxEdgerouter ProFront router for internet and out-of-band access to servers and switches

Besides that, a 6HE rack with 1000mm depth and a portable LTE modem is needed.

This MVP will yield in 12 usable machines, one of them will be reserved as management server.

diff --git a/v0.18.15/overview/isolated-kubernetes.drawio.svg b/v0.18.15/overview/isolated-kubernetes.drawio.svg new file mode 100644 index 0000000000..a34a14d1da --- /dev/null +++ b/v0.18.15/overview/isolated-kubernetes.drawio.svg @@ -0,0 +1,284 @@ + + + + + + + + +
+
+
+ Isolated Cluster +
+
+
+
+ + Isolated Cluster + +
+
+ + + + +
+
+
+ Firewall +
+
+
+
+ + Firewall + +
+
+ + + + +
+
+
+ Service Type Loadbalancer +
+
+
+
+ + Service Type Load... + +
+
+ + + + + +
+
+
+ Pod +
+
+
+
+ + Pod + +
+
+ + + + +
+
+
+ Pod +
+
+
+
+ + Pod + +
+
+ + + + + + + +
+
+
+ CWNP +
+
+
+
+ + CWNP + +
+
+ + + + +
+
+
+ Infrastructure Cluster +
+
+
+
+ + Infrastructure Cluster + +
+
+ + + + +
+
+
+ NTP Server +
+
+
+
+ + NTP Server + +
+
+ + + + +
+
+
+ DNS Server +
+
+
+
+ + DNS Server + +
+
+ + + + +
+
+
+ Registry Mirror +
+
+
+
+ + Registry Mirror + +
+
+ + + + +
+
+
+ Firewall +
+
+
+
+ + Firewall + +
+
+ + + + + + + +
+
+
+ Ingress-Controller +
+
+
+
+ + Ingress-Controller + +
+
+ + + + +
+
+
+ + Internet + +
+
+
+
+ + Internet + +
+
+ + + + +
+
+
+ + Private Network + +
+
+
+
+ + Private Network + +
+
+ + + + + + + +
+
+
+ Private Registry +
+
+
+
+ + Private Registry + +
+
+ +
+ + + + + Text is not SVG - cannot display + + + +
\ No newline at end of file diff --git a/v0.18.15/overview/isolated-kubernetes/index.html b/v0.18.15/overview/isolated-kubernetes/index.html new file mode 100644 index 0000000000..f88440b64f --- /dev/null +++ b/v0.18.15/overview/isolated-kubernetes/index.html @@ -0,0 +1,179 @@ + +Isolated Kubernetes · metal-stack

Isolated Kubernetes Clusters

Some customers have the need to run their workloads in a very restricted environment. These restrictions are driven by regulatory requirements in some industries such as finance, healthcare, energy and more. Regulatory requirements often mandate that the workload must not be exposed to the public internet, nor is capable to reach the public internet in any case.

For this purpose we implemented a possibility to start Kubernetes clusters in such a manner. This is referred to as cluster isolation.

Design Choices

When talking about highly secure Kubernetes environments people often raise the term "Air Gapped Cluster". This would mean that no physical connection exists between the Kubernetes control plane and the Kubernetes worker nodes with the outside world. This requirement exists in extreme environments such as ships, moon bases or nuclear plants. The effort to produce this in a completely automated manner is extremely challenging.

We decided to follow a different approach which is more practical, still very secure but much simpler to implement and operate. The solution we created is called "Isolated Cluster" which means that there are still physical connections between the Kubernetes cluster, but guarded to prohibit malicious traffic. It is also not possible to enable malicious traffic by accident, e.g. if a cluster user configures network policies or load balancers to untrusted environments.

Network Design

In order to be able to restrict ingress and egress internet traffic, but still make it possible to create a working Kubernetes cluster we implemented the following network design.

  • All strictly required container images are mirrored to a registry which is only accessible from the Kubernetes clusters.
  • DNS and NTP servers are produced alongside the registry.
  • The containerd configuration on every worker node is configured to pull all of the strictly required container images from this private registry mirror.
  • DNS and NTP configuration is also adopted to use the DNS and NTP servers on this private environment.
  • A list of networks which are allowed to reach is managed, this list reflects the networks of the cloud provider and is not modifiable by the cluster user. This list usually contains the internet prefixes of the provider and one or more RFC address ranges.

Network Design

Users are advised to attach an additional network to the Kubernetes cluster in order to be able to pull container images for the application workloads from private registries.

Strictly Required Container Images

In general the creation of a Kubernetes cluster requires the ability to pull container images for several applications which are necessary to make a machine a Kubernetes worker node. To mention the most important:

  • Kubelet: the main controller on each worker node to manage the workload
  • CNI (Container Network Interface): controller and daemon set to setup and run the container networking
  • CSI (Container Storage Interface): controller and daemon set to setup and run the container storage
  • CoreDNS: DNS for containers
  • MetalLB: Service Type LoadBalancer Implementation
  • node-exporter and metrics-server: Monitoring for the worker node
  • Metal-Stack Addons: for firewall and auditing events

Flavors

With the introduction of Isolated Kubernetes Clusters, cluster users must decide upon cluster creation which type of isolation he needs for his workload. There are three different flavours available:

  • Internet access baseline: This is the default cluster creation mode, which does not change any aspects of network and registry access.
  • Internet access forbidden: No internet access is possible, neither ingress nor egress.
  • Internet access restricted: No internet access is possible, neither ingress nor egress, but can be enabled by the cluster user.

Please see the detailed description of these flavors below.

Cluster Wide Network Policies CWNP

To restrict which egress traffic is allowed, Custom Resources ClusterWideNetworkPolicy are deployed and can be deployed by the cluster user. The set of deployed CWNPs differs between baseline and forbidden/restricted.

baseline CWNPs:

Rule NameDestinationPurpose
allow-to-http0.0.0.0/0egress via http
allow-to-https0.0.0.0/0egress via https
allow-to-apiserverIP of the Kubernetes API Server on the control planeAPI Server communication of kubelet and other controllers
allow-to-dnsIP of the Google DNS ServersDNS resolution from the Kubernetes worker nodes and containers
allow-to-ntpIP of the Cloudflare NTP ServersTime synchronization
allow-to-storagenetwork of the container storagepersistent volumes with the cni driver
allow-to-vpnIP of the vpn endpoint on the control planeallow communication from the api server to the kubelet for container logs and container exec

forbidden and restricted CWNPs:

Rule NameDestinationPurpose
allow-to-apiserverIP of the Kubernetes API Server on the control planeAPI Server communication of kubelet and other controllers
allow-to-dnsIP of the private DNS ServerDNS resolution from the Kubernetes worker nodes and containers
allow-to-ntpIP of the private NTP ServerTime synchronization
allow-to-registryIP of the private Registry MirrorPulling strictly required container images
allow-to-storagenetwork of the container storagepersistent volumes with the cni driver
allow-to-vpnIP of the vpn endpoint on the control planeallow communication from the api server to the kubelet for container logs and container exec

All of these CWNPs are managed by the gardener-extension-provider-metal, every manual modification will be reverted immediately.

Internet Access Baseline

This is the default configuration of a Kubernetes cluster, egress traffic is controlled by multiple CWNPs (ClusterWideNetworkPolicy), ingress traffic is possible by deploying a Service Type LoadBalancer. The cluster user can add additional CWNPs without any restrictions and is responsible for them.

Container images can be pulled from any reachable container registry. The containerd is not reconfigured to point to our private registry mirror.

DNS and NTP are configured to internet DNS resolvers and NTP servers.

Internet Access Forbidden

This configuration can only be achieved by creating a new Kubernetes cluster, it is not possible to modify a existing cluster (with internet access baseline or restricted) to this configuration. It is also required to specify the most recent version of Kubernetes, older versions of Kubernetes are not supported.

Every network access modification triggered by a cluster user, either by adding or modifying CWNPs or adding a Service Type LoadBalancer, is validated against the list of allowed networks.

containerd is configured so that all required images are pulled from the private registry mirror. This registry contains only the strictly required images, therefore no additional (workload) images can be pulled from public registries.

Egress traffic

Egress traffic is only allowed to the private registry mirror and the DNS and NTP servers. Additional CWNPs can be added to reach destinations in the internal networks if specified. If a CWNP was created which points to a destination outside of the allowed networks, the CWNP will still be present but stays in the status ignored.

> kubectl get clusterwidenetworkpolicies.metal-stack.io
+NAME                 STATUS     MESSAGE
+allow-to-apiserver   deployed
+allow-to-dns         deployed
+allow-to-ntp         deployed
+allow-to-registry    deployed
+allow-to-storage     deployed
+allow-to-vpn         deployed
+allow-to-google      ignored    ingress/egress does not match allowed networks

Also an event is created which describes why the CWNP was ignored:

> kubectl get events
+5s         Warning   ForbiddenCIDR         clusterwidenetworkpolicy/allow-to-google    address:"8.8.8.8/32" is outside of the allowed network range:"10.0.0.0/8,100.64.0.0/10,212.34.83.0/27", ignoring

Ingress traffic

Ingress traffic is only allowed from the internal networks if specified. To specify the address where the Service Type LoadBalancer is listening to, the cluster user must use one of his statically acquired ip addresses. Of course, this ip address is only considered if it is contained in the list of allowed networks. Then this ip address must be configured in the service:

apiVersion: v1
+kind: Service
+spec:
+  type: LoadBalancer
+  loadBalancerIP: 10.1.1.1 # ip from the internal network

By default, no ip address will be automatically selected for such clusters and the ip of the service will stay in pending mode until the ip was specified as shown above.

> kubectl get svc
+NAME              TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)         AGE
+example-service   LoadBalancer   10.244.75.171   <pending>     443:32179/TCP   4s
+
+> kubectl get events
+8s          Warning   AllocationFailed         service/example-service   Failed to allocate IP for "default/example-service": no available IPs
+3s          Warning   SyncLoadBalancerFailed   service/example-service   Error syncing load balancer: failed to ensure load balancer: no default network for ip acquisition specified, acquire an ip for your cluster's project and specify it directly in "spec.loadBalancerIP"

Internet Access Restricted

This configuration can only be achieved by creating a new Kubernetes cluster, it is not possible to modify a existing cluster (with internet access baseline or forbidden) to this configuration. It is also required to specify the most recent version of Kubernetes, older versions of Kubernetes are not supported.

The same default CWNPs are deployed and the container images are pulled from the private registry. Also DNS and NTP are configured to use the private DNS and NTP servers. The only difference to the forbidden mode is that CWNPs and Service Type LoadBalancers can be created without the restriction that only allowed networks are allowed.

Pulling container images is theoretically possible if a cluster user creates a CWNP which allows network access to an external registry. But most container registries serve the container images from large CDN networks, which have a lot of ip addresses. Simply adding the ip address of docker.io is therefore not sufficient.

Application Container Images

In order to deploy application containers into a cluster with Internet Access forbidden a private registry must be provided. This private registry must be located in the list of allowed networks. The DNS name of the registry must resolve in the public DNS servers. The registry must be secured with a TLS certificate that is also valid with the CA certificates from the worker node, e.g. vanilla debian ca-certificates.

Implementation

To achieve this functionality modifications have been implemented in various components in metal-stack, this includes:

Gardener Extension Provider Metal

The ControlPlane API is adopted to enable a user to configure a shoot with the internet access type forbidden or restricted. The CloudProfile can now be extended to carry the list of allowed networks, the dns and ntp servers, the registry with the mirrored registries.

ControlPlane:

// ControlPlaneConfig contains configuration settings for the control plane.
+type ControlPlaneConfig struct {
+    metav1.TypeMeta
+
+    // NetworkAccessType defines how the cluster can reach external networks.
+    // +optional
+    NetworkAccessType *NetworkAccessType
+}
+type (
+    // NetworkAccessType defines how a cluster is capable of accessing external networks
+    NetworkAccessType string
+)
+
+const (
+    // NetworkAccessBaseline allows the cluster to access external networks in a baseline manner
+    NetworkAccessBaseline = NetworkAccessType("baseline")
+    // NetworkAccessRestricted access to external networks is by default restricted to registries, dns and ntp to partition only destinations.
+    // Therefore registries, dns and ntp destinations must be specified in the cloud-profile accordingly.
+    // If this is not the case, restricting the access must not be possible.
+    // Image overrides for all images which are required to create such a shoot, must be specified. No other images are provided in the given registry.
+    // customers can define own rules to access external networks as in the baseline.
+    // Service type LoadBalancers are also not restricted.
+    NetworkAccessRestricted = NetworkAccessType("restricted")
+    // NetworkAccessForbidden in this configuration a customer can no longer create rules to access external networks.
+    // which are outside of a given list of allowed networks. This is enforced by the firewall.
+    // Service type LoadBalancers are also not possible to open a service ip which is not in the list of allowed networks.
+    // This is also enforced by the firewall.
+    NetworkAccessForbidden = NetworkAccessType("forbidden")
+)

A sample Shoot Spec:

---
+apiVersion: core.gardener.cloud/v1beta1
+kind: Shoot
+metadata:
+  name: isolated
+  namespace: sample
+spec:
+  provider:
+    type: metal
+      controlPlaneConfig:
+        networkAccessType: forbidden
+...

CloudProfile:

type NetworkIsolation struct {
+    // AllowedNetworks is a list of networks which are allowed to connect in restricted or forbidden NetworkIsolated clusters.
+    AllowedNetworks AllowedNetworks
+    // DNSServers
+    DNSServers []string
+    // NTPServers
+    NTPServers []string
+    // The registry which serves the images required to create a shoot.
+    RegistryMirrors []RegistryMirror
+}
+
+// AllowedNetworks is a list of networks which are allowed to connect in restricted or forbidden NetworkIsolated clusters.
+type AllowedNetworks struct {
+    // Ingress defines a list of networks which are allowed for incoming traffic like service type LoadBalancer
+    // to allow all you must specify 0.0.0.0/0 or ::/0
+    Ingress []string
+    // Egress defines a list of networks which are allowed for outgoing traffic
+    // to allow all you must specify 0.0.0.0/0 or ::/0
+    Egress []string
+}
+
+type RegistryMirror struct {
+    // Name describes this server
+    Name string
+    // Endpoint is typically the url of the registry in the form https://hostname
+    Endpoint string
+    // IP is the ipv4 or ipv6 address of this server
+    IP string
+    // Port at which port the service is reachable
+    Port int32
+    // This Registry Mirror mirrors the following registries
+    MirrorOf []string   
+}

A sample configuration in the CloudProfile would look like:

  network-isolation:
+    allowedNetworks:
+      egress:
+      - 1.2.3.0/24 # Internet CIDR of the Provider
+      - 100.64.0.0/10
+      - 10.0.0.0/8
+      ingress:
+      - 100.64.0.0/10
+    dnsServers:
+      - "1.2.3.1"
+      - "1.2.3.2"
+      - "1.2.3.3"
+    ntpServers:
+      - "1.2.3.1"
+      - "1.2.3.2"
+      - "1.2.3.3"
+    registryMirrors:
+      - name: test registry
+        endpoint: https://some.private.registry
+        ip: "1.2.3.4"
+        port: 443
+        mirrorOf:
+            - "docker.io"
+            - "quay.io"
+            - "eu.gcr.io"
+            - "ghcr.io"
+            - "registry.k8s.io"

OS Metal Extension

Based on the configuration of a cluster the configuration of the containerd must be changed to pull images from the private registry mirror. If a cluster is either configured with restricted or forbidden, the configuration of containerd will be created as such:

config.toml

imports = ["/etc/containerd/conf.d/*.toml"]
+version = 2
+
+[plugins."io.containerd.grpc.v1.cri".registry]
+  [plugins."io.containerd.grpc.v1.cri".reg
+    [plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]
+      endpoint = ["https://some.private.registry"]
+    [plugins."io.containerd.grpc.v1.cri".registry.mirrors."quay.io"]
+      endpoint = ["https://some.private.registry"]
+    [plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.lightbitslabs.com"]
+      endpoint = ["https://some.private.registry"]
+    [plugins."io.containerd.grpc.v1.cri".registry.mirrors."eu.gcr.io"]
+      endpoint = ["https://some.private.registry"]
+    [plugins."io.containerd.grpc.v1.cri".registry.mirrors."ghcr.io"]
+      endpoint = ["https://some.private.registry"]
+    [plugins."io.containerd.grpc.v1.cri".registry.mirrors."registry.k8s.io"]
+      endpoint = ["https://some.private.registry"]
+    [plugins."io.containerd.grpc.v1.cri".registry.mirrors."r.metal-stack.io"]
+      endpoint = ["https://some.private.registry"]

DNS and NTP must also be adopted according to the configuration in the CloudProfile.

Firewall Controller Manager and Firewall Controller

The Firewall Controller Manager has extended the FirewallSpec to configure the Firewall Controller which must enforce the restrictions regarding allowed networks.

// FirewallSpec defines parameters for the firewall creation along with configuration for the firewall-controller.
+type FirewallSpec struct {
+    // AllowedNetworks defines which networks are allowed to connect to, and allow incoming traffic from.
+    // Is enforced with NetworkAccessForbidden.
+    // The node network is always allowed.
+    AllowedNetworks AllowedNetworks `json:"allowedNetworks,omitempty"`
+}
+
+// AllowedNetworks is a list of networks which are allowed to connect when NetworkAccessType is NetworkAccessForbidden.
+type AllowedNetworks struct {
+    // Ingress defines a list of cidrs which are allowed for incoming traffic like service type LoadBalancer
+    Ingress []string `json:"ingress,omitempty"`
+    // Egress defines a list of cidrs which are allowed for outgoing traffic
+    Egress []string `json:"egress,omitempty"`
+}

Also the ClusterwideNetworkPolicy in the Firewall Controller was changed to show the deployment status of a CWNP.


+type ClusterwideNetworkPolicy struct {
+    metav1.TypeMeta   `json:",inline"`
+    metav1.ObjectMeta `json:"metadata,omitempty"`   
+
+    Spec   PolicySpec   `json:"spec,omitempty"`
+    Status PolicyStatus `json:"status,omitempty"`
+}
+
+// PolicyDeploymentState describes the state of a CWNP deployment
+type PolicyDeploymentState string
+
+const (
+    // PolicyDeploymentStateDeployed the CWNP was deployed to a native nftable rule
+    PolicyDeploymentStateDeployed = PolicyDeploymentState("deployed")
+    // PolicyDeploymentStateIgnored the CWNP was not deployed to a native nftable rule because it is outside of the allowed networks
+    PolicyDeploymentStateIgnored  = PolicyDeploymentState("ignored")
+)
+
+// PolicyStatus defines the observed state for CWNP resource
+type PolicyStatus struct {
+    // FQDNState stores mapping from FQDN rules to nftables sets used for a firewall rule.
+    // Key is either MatchName or MatchPattern
+    // +optional
+    FQDNState FQDNState `json:"fqdn_state,omitempty"`   
+    // State of the CWNP, can be either deployed or ignored
+    State PolicyDeploymentState `json:"state"`  
+    // Message describe why the state changed
+    Message string `json:"message,omitempty"`
+}

Cloud Controller Manager

This component was adopted to allow to be started without a default network specified. This was actually always the internet network and if no ip address was specified in the Service Type LoadBalancer, one ip was allocated from this default network. For isolated clusters this is not provided and a cluster user must always specify this ip to get a working load balancer.

OCI Mirror

The OCI Mirror is a new application which acts as a scheduled job that pulls a given list of container images and pushes them to a private registry (which will then serve as the private registry mirror). The detailed description can be read on the project website.

diff --git a/v0.18.15/overview/kubernetes/index.html b/v0.18.15/overview/kubernetes/index.html new file mode 100644 index 0000000000..cf73206a7e --- /dev/null +++ b/v0.18.15/overview/kubernetes/index.html @@ -0,0 +1,2 @@ + +Kubernetes Integration · metal-stack

Kubernetes Integration

With the help of the Gardener project, metal-stack can be used for spinning up Kubernetes clusters quickly and reliably on bare metal machines.

To make this happen, we implemented a couple of components, which are described here.

metal-ccm

CCM stands for cloud-controller-manager and is the bridge between Kubernetes and a cloud-provider.

We implemented the cloud provider interface in the metal-ccm repository. With the help of the cloud-controller-controller we provide metal-stack-specific properties for Kubernetes clusters, e.g. load balancer configuration through MetalLB or node properties.

firewall-controller

To make the firewalls created with metal-stack easily configurable through Kubernetes resources, we add our firewall-controller to the firewall image. The controller watches special CRDs, enabling users to manage:

  • nftables rules
  • Intrusion-detection with suricata
  • network metric collection

Please check out the guide on how to use it.

Gardener components

There are some Gardener resources that need be reconciled when you act as a cloud provider for the Gardener. This section briefly describes the controllers implemented for deploying Kubernetes clusters through Gardener.

If you want to learn how to deploy metal-stack with Gardener, please check out the installation section.

gardener-extension-provider-metal

The gardener-extension-provider-metal contains of a set of webhooks and controllers for reconciling or mutating Gardener-specific resources.

The project also contains a validator for metal-type Gardener resources, which you should also deploy in case you want to use metal-stack in combination with Gardener.

os-metal-extension

Due to the reason we use ignition in our operating system images for userdata, we had to provide an own extension controller for metal-stack, which you can find at Github in the os-metal-extension repository.

machine-controller-manager-provider-metal

Worker nodes are managed through Gardener's machine-controller-manager (MCM). The MCM allows out-of-tree provider implementation via sidecar, which is what we implemented in the machine-controller-manager-provider-metal repository.

diff --git a/v0.18.15/overview/metal-stack-architecture.drawio.svg b/v0.18.15/overview/metal-stack-architecture.drawio.svg new file mode 100644 index 0000000000..5bfbec87b6 --- /dev/null +++ b/v0.18.15/overview/metal-stack-architecture.drawio.svg @@ -0,0 +1,1103 @@ + + + + + + + + +
+
+
+ Clients +
+
+
+
+ + Clients + +
+
+ + + + +
+
+
+ metalctl +
+
+
+
+ + metalctl + +
+
+ + + + +
+
+
+ metal-go +
+
+
+
+ + metal-go + +
+
+ + + + +
+
+
+ metal-python +
+
+
+
+ + metal-python + +
+
+ + + +
+
+
+ CLI +
+
+
+
+ + CLI + +
+
+ + + +
+
+
+ Libraries +
+
+
+
+ + Libraries + +
+
+ + + + + + + + + + + + +
+
+
+ Console Access +
+
+
+
+ + Console Access + +
+
+ + + + +
+
+
+ ssh +
+
+
+
+ + ssh + +
+
+ + + + + +
+
+
+ Switch Plane +
+
+
+
+ + Switch Plane + +
+
+ + + + +
+
+
+ mgmtspine01 +
+
+
+
+ + mgmtspine01 + +
+
+ + + + +
+
+
+ mgmtspine02 +
+
+
+
+ + mgmtspine02 + +
+
+ + + + +
+
+
+ mgmtleaf01 +
+
+
+
+ + mgmtleaf01 + +
+
+ + + + +
+
+
+ mgmtleaf02 +
+
+
+
+ + mgmtleaf02 + +
+
+ + + + + + + + +
+
+
+ exit01 +
+
+
+
+ + exit01 + +
+
+ + + + +
+
+
+ exit02 +
+
+
+
+ + exit02 + +
+
+ + + + +
+
+
+ spine01 +
+
+
+
+ + spine01 + +
+
+ + + + +
+
+
+ spine02 +
+
+
+
+ + spine02 + +
+
+ + + + + + + + + + + + + +
+
+
+ leaf01 +
+
+
+
+ + leaf01 + +
+
+ + + +
+
+
+ leaf02 +
+
+
+
+ + leaf02 + +
+
+ + + + +
+
+
+ metal-core +
+
+
+
+ + metal-core + +
+
+ + + + +
+
+
+ metal-core +
+
+
+
+ + metal-core + +
+
+ + + + + + + + + + + + + + + + +
+
+
+ mgmtfirewall +
+
+
+
+ + mgmtfirewall + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+ Server +
+ Pool +
+
+
+
+ + Server... + +
+
+ + + + + +
+
+
+ + Management Server 01/02 + +
+
+
+
+ + Management Server 01/02 + +
+
+ + + + + +
+
+
+ metal-cache-image-sync +
+
+
+
+ + metal-cache-image-sync + +
+
+ + + + +
+
+
+ CoreDNS +
+
+
+
+ + CoreDNS + +
+
+ + + + + + +
+
+
+ HAProxy +
+
+
+
+ + HAProxy + +
+
+ + + +
+
+
+ Image Cache +
+
+
+
+ + Image Cache + +
+
+ + + + +
+
+
+ metal-bmc +
+
+
+
+ + metal-bmc + +
+
+ + + + + + +
+
+
+ metal-hammer +
+
+
+
+ + metal-hammer + +
+
+ + + + + + +
+
+
+ User OS +
+
+
+
+ + User OS + +
+
+ + + +
+
+
+ Metal Partition +
+
+
+
+ + Metal Partition + +
+
+ + + + + + + + + + + + + + + + + +
+
+
+ pixiecore +
+
+
+
+ + pixiecore + +
+
+ + + + + + + + +
+
+
+ Metal Control Plane +
+
+
+
+ + Metal Control Plane + +
+
+ + + + + + + + + + + + + + + + + + +
+
+
+ metal-api +
+
+
+
+ + metal-api + +
+
+ + + + + + +
+
+
+ masterdata-api +
+
+
+
+ + masterdata-api + +
+
+ + + + + + + +
+
+
+ postgres +
+
+
+
+ + postgres + +
+
+ + + + + + +
+
+
+ backup-restore-sidecar +
+
+
+
+ + backup-restore-sidecar + +
+
+ + + +
+
+
+ masterdata-db +
+
+
+
+ + masterdata-db + +
+
+ + + + + +
+
+
+ nsqd +
+
+
+
+ + nsqd + +
+
+ + + + + + +
+
+
+ metal-console +
+
+
+
+ + metal-console + +
+
+ + + + + + +
+
+
+ rethinkDB +
+
+
+
+ + rethinkDB + +
+
+ + + + +
+
+
+ backup-restore-sidecar +
+
+
+
+ + backup-restore-sidecar + +
+
+ + + +
+
+
+ metal-db +
+
+
+
+ + metal-db + +
+
+ + + + + + +
+
+
+ postgres +
+
+
+
+ + postgres + +
+
+ + + + +
+
+
+ backup-restore-sidecar +
+
+
+
+ + backup-restore-sidecar + +
+
+ + + +
+
+
+ ipam-db +
+
+
+
+ + ipam-db + +
+
+ + + + +
+
+
+ Ingress-Controller (NGINX) +
+
+
+
+ + Ingress-Controller (NGINX) + +
+
+ + + + + + +
+
+
+ + meilisearch + +
+
+
+
+ + meilisear... + +
+
+ + + + +
+
+
+ backup-restore-sidecar +
+
+
+
+ + backup-restore-sidecar + +
+
+ + + +
+
+
+ auditing +
+
+
+
+ + auditing + +
+
+ + + + + + + + + + + + +
+
+
+ ipam +
+
+
+
+ + ipam + +
+
+ + + + + + + + + + +
+
+
+ CI +
+
+
+
+ + CI + +
+
+ + + + + + + +
+
+
+ GCP Buckets +
+
+
+
+ + GCP Buckets + +
+
+ + + + + + + + + +
+
+
+ OS Images +
+
+
+
+ + OS Images + +
+
+ + + + +
+
+
+ + ISP + +
+
+
+
+ + ISP + +
+
+ +
+ + + + + Text is not SVG - cannot display + + + +
diff --git a/v0.18.15/overview/metal-stack-control-plane.svg b/v0.18.15/overview/metal-stack-control-plane.svg new file mode 100644 index 0000000000..7556e91641 --- /dev/null +++ b/v0.18.15/overview/metal-stack-control-plane.svg @@ -0,0 +1 @@ +
Metal Control Plane
Metal Control Plane
metal-api
metal-api
masterdata-api
masterdata-api
postgres
postgres
backup-restore-sidecar
backup-restore-sidecar
masterdata-db
masterdata-db
nsqd
nsqd
metal-console
metal-console
rethinkDB
rethinkDB
backup-restore-sidecar
backup-restore-sidecar
metal-db
metal-db
postgres
postgres
backup-restore-sidecar
backup-restore-sidecar
ipam-db
ipam-db
Ingress-Controller (NGINX)
Ingress-Controller (NGINX)
meilisearch
meilisear...
backup-restore-sidecar
backup-restore-sidecar
auditing
auditing
ipam
ipam
Text is not SVG - cannot display
\ No newline at end of file diff --git a/v0.18.15/overview/metal-stack-partition.svg b/v0.18.15/overview/metal-stack-partition.svg new file mode 100644 index 0000000000..221146ed9e --- /dev/null +++ b/v0.18.15/overview/metal-stack-partition.svg @@ -0,0 +1 @@ +
Switch Plane
Switch Plane
mgmtspine01
mgmtspine01
mgmtspine02
mgmtspine02
mgmtleaf01
mgmtleaf01
mgmtleaf02
mgmtleaf02
exit01
exit01
exit02
exit02
spine01
spine01
spine02
spine02
leaf01
leaf01
leaf02
leaf02
metal-core
metal-core
metal-core
metal-core
mgmtfirewall
mgmtfirewall
Server
Pool
Server...
Management Server 01/02
Management Server 01/02
metal-cache-image-sync
metal-cache-image-sync
CoreDNS
CoreDNS
HAProxy
HAProxy
Image Cache
Image Cache
metal-bmc
metal-bmc
metal-hammer
metal-hammer
User OS
User OS
Metal Partition
Metal Partition
pixiecore
pixiecore
Text is not SVG - cannot display
\ No newline at end of file diff --git a/v0.18.15/overview/networking/index.html b/v0.18.15/overview/networking/index.html new file mode 100644 index 0000000000..cf3592695f --- /dev/null +++ b/v0.18.15/overview/networking/index.html @@ -0,0 +1,354 @@ + +Networking · metal-stack

Networking

We spent a lot of time on trying to provide state-of-the-art networking in the data center. This document describes the requirements, ideas and implementation details of the network topology that hosts the metal-stack.

The document is separated into three main sections describing the constraints, theoretical ideas and implementation details.

Requirements

Finding the requirements for this greenfield project was kicked off with a handful of design parameters that included:

  • Investigation of the idea of a layer-3 based infrastructure to overcome the drawbacks of traditional layer-2 architectures.
  • Application of a routing technology that involves a single stand-alone protocol BGP for operational simplicity.
  • Utilization of the overlay virtual network technology EVPN to support cost-effective scaling, efficient network information exchange and a manageable amount of administration effort.
  • Applying the routing topology on top of a completely new physical infrastructure that is designed as a CLOS network topology.

Evaluation of those parameters led to more specific requirements:

  • Physical Wiring:
    • The data center is made of a leaf-spine CLOS topology containing:
      • leaf switches
      • spine switches
      • exit switches
      • management server
      • management switch
      • tenant servers
      • tenant firewalls.
    • Bare metal servers are dual-attached to leaf switches. The bare metal servers either become tenant servers or firewalls for a group of tenant servers.
    • All network switches are connected to a management switch. A management server provides access to this management network.
  • Network Operation Characteristics:
    • IPv4 based network.
    • No IPv6 deployment.
    • Utilization of external BGP.
    • Numbered BGP only for peerings at exit switches with third parties (Internet Service Provider).
    • Overall BGP unnumbered.
    • 4-byte private ASN instead of default 2-byte ASN for BGP.
    • Network operation relies on SONiC Linux.
    • Bleeding edge Routing-to-the-Host/EVPN-to-the-Host with ordinary Linux distributions.
    • Layer-3 routing using BGP and VXLAN/EVPN.
    • Every VTEP acts as a layer-3 gateway and does routing. Routing is done on both the ingress and the egress VTEP (aka distributed symmetric routing).
    • Tenant isolation is realized with VRF.
    • Internet Access is implemented with route leak on the firewall servers and during the PXE-Process with route leak on the exit switches.
    • MTU 9216 is used for VXLAN-facing interfaces, otherwise MTU 9000 is used.

Furthermore, requirements such as operational simplicity and network stability that a small group of people can effectively support have been identified being a primary focus for building metal-stack.

Concept

The theoretical concept targets the aforementioned requirements. New technologies have been evaluated to apply the best solutions. The process was heavily inspired by the work of Dinesh G. Dutt regarding BGP (bgp-ebook) and EVPN (evpn-ebook).

External BGP together with network overlay concepts as EVPN can address the essential demands. These revolutionary concepts are part of the next evolutionary step in data center design. It overcomes common issues of traditional layer 2 architectures (e.g. VLAN limitations, network visibility for operations, firewall requirements) by introducing a layer 3 based network topology.

CLOS

A CLOS topology is named after the pioneer Charles Clos (short: CLOS) who first formalized this approach. CLOS defines a multistage network topology that is used today to improve performance and resilience while enabling a cost effective scalability. A CLOS topology comprises network switches aggregated into spine and leaf layers. Each leaf switch (short: leaf) is connected to all spine switches (short: spine) but there is no direct leaf-to-leaf or spine-to-spine connection (See: picture 1).

2 Layer CLOS Topology

Picture 1: Fragment of CLOS to show leaf-spine layer.

This data center network architecture, based on a leaf-spine architecture, is also know as "two-tier" CLOS topology.

3 Layer CLOS Topology

Picture 2: Fragment to show a 3-stage, 2-layer CLOS topology.

Tenant servers are dual-attached to the leaf layer in order to have redundancy and load balancing capability (Picture 2). The set of leaves, spine switches and tenant servers define stages. From top down each server is reachable with 3 hops (spine -> leaf -> server). This is why that CLOS design is called a 3-stage CLOS. Consistent latency throughout the data center are an outcome of this design.

It is not only important to have a scalable and resilient infrastructure but also to support planning and operation teams. Visibility within the network is of significant meaning for them. Consequently layer-3 routing in favor of layer-2 bridging provides this kind of tooling.

BGP

For routing the Border Gateway Protocol (BGP), more specific: External BGP was selected. Extensive testing and operational experiences have shown that External BGP is well suited as a stand-alone routing protocol (see: RFC7938).

Not all tenant servers are connected to the same leaf. Instead they can be distributed among any of the leaves of the data center. To not let this detail restrict the intra-tenant communication it is required to interconnect those layer-2 domains. In the context of BGP there is a concept of overlay networking with VXLAN/ EVPN that was evaluated to satisfy the needs of the metal-stack.

BGP Unnumbered

In BGP traditionally each BGP peer-facing interface requires a separate IPv4 address. This consumes a lot of IP addresses. RFC 5549 defines the BGP unnumbered standard. It allows to use interface's IPv6 link local address (LLA) to set up a BGP session with a peer. With BGP unnumbered the IPv6 LLA of the remote is automatically discovered via Router Advertisement (RA) protocol. Important: This does not (!) mean that IPv6 must be deployed in the network. BGP uses RFC 5549 to encode IPv4 routes as reachable over IPv6 next-hop using the LLA. Having unnumbered interfaces does not mean no IPv4 address may be in place. It is a good practice to configure an IP address to the never failing and always present local loopback interface (lo). This lo address is reachable over BGP from other peers because the RFC 5549 standard provides an encoding scheme to allow a router to advertise IPv4 routes with an IPv6 next-hop. BGP unnumbered also has an advantage from security perspective. It removes IPv4 and global IPv6 addresses from router interfaces, thus reducing the attack vector.

To sum it up:

  • BGP unnumbered uses IPv6 next-hops to announce IPv4 routes.
  • There is no IPv6 deployment in the network required.
  • IPv6 just has to be enabled on the BGP peers to provide LLA and RA.

In BGP, ASN is how BGP peers know each other.

ASN Numbering

Within the data center each BGP router is identified by a private autonomous system number (ASN). This ASN is used for internal communication. The default is to have 2-byte ASN. To avoid having to find workarounds in case the ASN address space is exhausted, a 4-byte ASN that supports up to 95 million ASNs (4200000000–4294967294) is used from the beginning.

ASN numbering in a CLOS topology should follow a model to avoid routing problems (path hunting) due to it's redundant nature. Within a CLOS topology the following ASN numbering model is suggested to solve path hunting problems:

  • Leaves have unique ASN
  • Spines share an ASN
  • Exit switches share an ASN

Address-Families

As stated, BGP is a multi-protocol routing protocol. Since it is planned to use IPv4 and overlay networks using EVPN/VXLAN several address-families have to be activated for the BGP sessions to use:

  • IPv4 unicast address-family
  • L2 EVPN address-family

EVPN

Ethernet VPN (EVPN) is an overlay virtual network that connects layer-2 segments over layer-3 infrastructure. EVPN is an answer to common problems of entire layer-2 data centers.

Why do we need EVPN

Challenges such as large failure domains, spanning tree complexities, difficult troubleshooting and scaling issues are addressed by EVPN:

  • administration: less routers are involved in configuration (with VLAN every switch on routing-paths needs VLAN awareness). The configuration is less error prone due to the nature of EVPN and the good support in FRR.
  • scaling: EVPN overcomes scaling issues with traditional VLANs (max. 4094 VLANs).
  • cost-effectiveness: EVPN is an overlay virtual network. Not every switch on the routing path needs EVPN awareness. This enables the use of standard routers (in contrast to traditional VLAN); e.g.: spine switches act only as evpn information replicator and do not need to have knowledge of specific virtual networks.
  • efficiency: EVPN information is exclusively exchanged via BGP (Multiprotocol BGP). Only a single eBGP session is needed to advertise layer-2 reachability. No other protocols beneath BGP are involved and flood traffic is reduced to a minimum (no "flood-and-learn", no BUM traffic).

Virtual routing permits multiple network paths without the need of multiple switches. Hence the servers are logically isolated by assigning their networks to dedicated virtual routers using virtual routing and forwarding (short: VRF).

How do we use EVPN

EVPN (technology) is based on BGP as control plane protocol (underlay) and VXLAN as data plane protocol (overlay).

As EVPN is an overlay network, only the VXLAN Tunnel End Points (VTEPs) must be configured. In the case of two-tier CLOS networks leaf switches are tunnel endpoints.

In EVPN routing is assumed to occur in the context of a VRF. VRF enables true multitenancy. Therewith, VRF is the first step for EVPN configuration and there is a 1:1 relationship between tenant and VRF.

To enable layer-2 connectivity, we need a special interface to route between layer-2 networks. This interface is called Switched VLAN Interface (SVI). The SVI is realized with a VLAN. It is part of a VRF (layer-3).

The VTEP configuration requires the setup of a VXLAN interface. A VLAN aware bridge interconnects the VXLAN interface and the SVI.

Required Interfaces to establish the EVPN control plane:

  • VRF: because routing happens in the context of this interface.
  • SVI: because remote host routes for symmetric routing are installed over this interface.
  • VLAN-aware bridge: because router MAC addresses of remote VTEPs are installed over this interface.
  • VXLAN Interface / VXLAN Tunnel Endpoint: because the VRF to layer-3 VNI mapping has to be consistent across all VTEPs)

EVPN VTEP

Picture 3: Required interfaces on the switch to wire up the vrf to swp 1 connectivity with a given vxlan

Integrated routing and bridging (IRB) is the most complex part of EVPN. You could choose between centralized or distributed routing, and between asymmetrical (routing on ingress) or symmetrical (routing on ingress and egress) routing. We expect a lot of traffic within the data center itself which implies the need to avoid zigzag routing. This is why we go with distributed routing model. Further it is recommended to use the symmetric model since it makes the cut in most cases and has advantages in scalability (see "EVPN in the Data Center", Dinesh G. Dutt).

MTU

In a layer-3 network it is important to associate each interface with a proper Maximum Transmission Unit (MTU) to avoid fragmentation of IP packets. Typical modern networks do not fragment IP packets and the introduction of VXLAN adds another additional header to the packets that must not exceed the MTU. If the MTU is exceeded, VXLAN might just fail without error. This already represents a difficult-to-diagnose connectivity issue that has to be avoided.

It is common practice to set the MTU for VXLAN facing interfaces (e.g. inter-switch links) to a value of 9216 to compensate the additional VXLAN overhead and an MTU of 9000 as a default to other interfaces (e.g. server facing ports). The common MTU of 1500 is not sufficient for traffic inside a data center!

VRF

Routing is needed for communication between VXLAN tunnels or between a VXLAN tunnel and an external networks. VXLAN routing supports layer-3 multi-tenancy. All routing occurs in the context of a VRF. There is a 1:1 relation of a VRF to a tenant. Picture 3 illustrates this. Servers A and B belong to the same vrf VRF1. Server C is enslaved into VRF2. There is no communication possible between members of VRF1 and those of VRF2.

Two routing tables

Picture 4: Illustration of two distinct routing tables of VRF1 (enslaved: servers A and B) and VRF2 (enslaved: server C)

To leaverage the potential and power of BGP, VRF, EVPN/VXLAN without a vendor lock-in the implementation relies on hardware that is supported by open network operating system: SONiC.

Implementation

Implementation of the network operation requires the data center infrastructure to be in place. To implement a functional meaning for the parts of the CLOS network, all members must be wired accordingly.

Physical Wiring

Reference: See the CLOS overview picture in ./README.md.

NameWiring
Tenant server (aka Machine)Bare metal server that is associated to a tenant. Dual-connected to leafs.
Tenant firewallBare metal server that is associated to a tenant. Dual-connected to leafs.
LeafNetwork Switch that interconnects tenant servers and firewalls. Connected to spines.
SpineNetwork switch that interconnects leafs and exit switches.
ExitNetwork switch that connects to spines and interconnects to external networks.
Management ServerJump-host to access all network switches within the CLOS topology for administrative purpose.
Management SwitchConnected to the management port of each of the network switches.

Tenant servers are organized into a layer called projects. In case those tenant servers require access to or from external networks, a new tenant server to function as a firewall is created. Leaf and spine switches form the fundament of the CLOS network to facilitate redundancy, resilience and scalability. Exit switches establish connectivity to or from external networks. Management Switch and Management Server are mandatory parts that build a management network to access the network switches for administration.

To operate the CLOS topology, software defined configuration to enable BGP, VRF, EVPN and VXLAN must be set up.

Network Operating Systems

SONiC as the network operating system will be installed on all network switches (leaves, spines, exit switches) within the CLOS topology. SONiC cannot be installed on bare metal servers that require BGP/EVPN but does not have a switching silicon.

Components without a switching silicon are:

  • tenant servers
  • tenant firewalls
  • management server

There exist two paradigms to use BGP and/or VXLAN/EVPN on non switching bare metal servers: BGP-to-the-host and EVPN-to-the-host. Both describe a setup of Free Range Routing Framework (see frrouting.org) and its configuration. FRR seamlessly integrates with the native Linux IP networking stacks.

Starting with an explanation of the tenant server's BGP-to-the-Host helps to get an insight into the setup of the CLOS network from a bottom-up perspective.

Tenant Servers: BGP-to-the-Host

Tenant servers are dual-connected to leaf switches. To communicate with other servers or reach out to external networks they must join a BGP session with each of the leaf switches. Thus, it is required to bring BGP to those hosts (aka BGP-to-the-Host). Each tenant server becomes a BGP router (aka BGP speaker).

BGP-to-the-Host is established by installing and configuring FRR. The required FRR configuration for tenant servers is limited to a basic setup to peer with BGP next-hops:

# /etc/network/interfaces
+
+auto lo
+iface lo inet static
+  address 10.0.0.1/32
+
+auto lan0
+iface lan0 inet6 auto
+  mtu 9000
+
+auto lan1
+iface lan1 inet6 auto
+  mtu 9000

Listing 1: Network interfaces of a tenant server.

Listing 1 shows the local interfaces configuration. lan0 and lan1 connect to the leaves. As described, there is no IPv4 address assigned to them (BGP unnumbered). The local loopback has an IPv4 address assigned that is announced by BGP.

The required BGP configuration:

# /etc/frr/frr.conf
+
+frr version 7.0
+frr defaults datacenter
+log syslog debugging
+service integrated-vtysh-config
+!
+interface lan0
+  ipv6 nd ra-interval 6
+  no ipv6 nd suppress-ra
+!
+interface lan1
+  ipv6 nd ra-interval 6
+  no ipv6 nd suppress-ra
+!
+router bgp 4200000001
+  bgp router-id 10.0.0.1
+  bgp bestpath as-path multipath-relax
+  neighbor TOR peer-group
+  neighbor TOR remote-as external
+  neighbor TOR timers 1 3
+  neighbor lan0 interface peer-group TOR
+  neighbor lan1 interface peer-group TOR
+  neighbor LOCAL peer-group
+  neighbor LOCAL remote-as internal
+  neighbor LOCAL timers 1 3
+  neighbor LOCAL route-map local-in in
+  bgp listen range 10.244.0.0/16 peer-group LOCAL
+  address-family ipv4 unicast
+    redistribute connected
+    neighbor TOR route-map only-self-out out
+  exit-address-family
+!
+bgp as-path access-list SELF permit ^$
+!
+route-map local-in permit 10
+  set weight 32768
+!
+route-map only-self-out permit 10
+ match as-path SELF
+!
+route-map only-self-out deny 99
+!

Listing 2: FRR configuration of a tenant server.

The frr configuration in Listing 2 starts with frr defaults datacenter. This is a marker that enables compile-time provided settings that e.g. set specific values for BGP session timers. This is followed by a directive to state that instead of several configuration files for different purposes a single frr.conf file is used: service integrated-vtysh-config. The two interface specific blocks starting with interface ... enable the RA mechanism that is required for BGP unnumbered peer discovery. There is a global BGP instance configuration router bgp 4200000001 that sets the private ASN. The BGP router configuration contains a setup that identifies the BGP speaker bgp router-id 10.0.0.1. This router id should be unique. It is a good practice to assign the local loopback IPv4 as router-id. To apply the same configuration to several interfaces a peer group named TOR is defined via neighbor TOR peer-group. remote-as external activates external BGP for this peer group. To have a fast convergence, limits of default timers are reduced by timer 1 3 section. The two BGP-peer-facing interfaces are enslaved into the peer-group to inherit the peer-group's setup. Activation of IPv4 unicast protocol is completed with address-family ipv4 unicast. To prevent a tenant server from announcing other paths than lo interface a route-map only-self-out is defined. This route map is activated within the ipv4 address family: neighbor TOR route-map only-self-out out.

Application of the route map only-self-out enables to announce only local ip(s). This is to avoid that a tenant server announces paths to other servers (prevents unwanted traffic). To achieve this:

  • the route-map named only-self-out permits only matches against an access list named SELF

  • access list SELF permits only empty path announcements

  • the path of the tenant server itself has no ASN. It is always empty (see line *> 10.0.0.2/32 0.0.0.0 0 32768 ?):

    root@machine:~# vtysh -c 'show bgp ipv4 unicast'
    +BGP table version is 7, local router ID is 10.0.0.2, vrf id 0
    +Default local pref 100, local AS 4200000002
    +Status codes:  s suppressed, d damped, h history, * valid, > best, = multipath,
    +              i internal, r RIB-failure, S Stale, R Removed
    +Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
    +Origin codes:  i - IGP, e - EGP, ? - incomplete
    +
    +  Network          Next Hop            Metric LocPrf Weight Path
    +*= 0.0.0.0/0        lan1                                   0 4200000012 4200000040 i
    +*>                  lan0                                   0 4200000011 4200000040 i
    +*= 10.0.0.1/32      lan1                                   0 4200000012 4200000001 ?
    +*>                  lan0                                   0 4200000011 4200000001 ?
    +*> 10.0.0.2/32      0.0.0.0                  0         32768 ?
    +*= 10.0.0.78/32     lan1                                   0 4200000012 4200000001 ?
    +*>                  lan0                                   0 4200000011 4200000001 ?
    +
    +Displayed  4 routes and 7 total paths

    That is why only the self ip (loopback ip) is announced.

To allow for peering between FRR and other routing daemons on a tenant server a listen range is specified to accept iBGP sessions on the network 10.244.0.0/16. Therewith it gets possible that pods / containers like metal-lb with IPs of this range may peer with FRR.

This is the only place where we use iBGP in our topology. For local peering this has the advantage, that we don't need an additional ASN that has to be handled / pruned in the AS-path of routes. Routes coming from other routing daemons look as if they are configured on the tenant server's lo interface from the viewpoint of the leaves. iBGP routes are differently handled than eBGP routes in BGPs best path algorithm. Generally BGP has the rule to prefer eBGP routes over iBGP routes (s. 'eBGP over iBGP' ). BGP adds automatically an weight based on the route type. To overcome this issue, we set the weight of iBGP routes to the same weight that eBGP routes have, namely 32768 (set weight 32768). Without this configuration we will only get a single route to the IPs announced via iBGP. So this setting is essential for HA/failover!

Statistics of the established BGP session can be viewed locally from the tenant server via: sudo vtysh -c 'show bgp ipv4 unicast'

To establish this BGP session a BGP setup is required on the leaves as well.

Leaf Setup

Every leaf switch is connected to every spine switch. Tenant servers can be distributed within the data center and thus be connected to different leaves. Routing for tenant servers is isolated in unique VRFs. These constraints imply several configuration requirements for the leaf and spine switches:

  • leaves define tenant VRFs
  • leaves terminate VXLAN tunnels (aka "VXLAN tunnel endpoint" = VTEP)

The leaf setup requires the definition of a tenant VRF that enslaves the tenant server facing interfaces:

# /etc/network/interfaces
+
+# [...]
+
+iface vrf3981
+    vrf-table auto
+
+iface swp1
+    mtu 9000
+    post-up sysctl -w net.ipv6.conf.swp1.disable_ipv6=0
+    vrf vrf3981
+
+# [...]

Listing 3: Fragment that shows swp1 being member of vrf vrf3981.

There is a VRF definition iface vrf3981 to create a distinct routing table and a section vrf vrf3981 that enslaves swp1 (connects the tenant server) into the VRF. Those host facing ports are also called edge ports.

Unfortunately, due to a kernel bug, IPv6 is not reliably enabled, so it is enforced explicitly via post-up sysctl -w net.ipv6.conf.swp1.disable_ipv6=0. If this post-up trigger is missing the LLA of the interface might be absent.

Additional to the VRF definition the leaf must be configured to provide and connect a VXLAN interface to establish a VXLAN tunnel. This network virtualization begins at the leaves. Therefore, the leaves are also called Network Virtualization Edges (NVEs). The leaves encapsulate and decapsulate VXLAN packets.

# /etc/network/interfaces
+
+# [...]
+
+iface bridge
+    bridge-ports vni3981
+    bridge-vids 1001
+    bridge-vlan-aware yes
+
+iface vlan1001
+    mtu 9000
+    vlan-id 1001
+    vlan-raw-device bridge
+    vrf vrf3981
+
+iface vni3981
+    mtu 9000
+    bridge-access 1001
+    bridge-arp-nd-suppress on
+    bridge-learning off
+    mstpctl-bpduguard yes
+    mstpctl-portbpdufilter yes
+    vxlan-id 3981
+    vxlan-local-tunnelip 10.0.0.11
+
+# [...]

Listing 4: Fragment that shows VXLAN setup for vrf vrf3981.

All routing happens in the context of the tenant VRF. To send and receive packets of a VRF, several interface are in place.

A bridge is used to attach VXLAN interface bridge-ports vni3981 and map its local VLAN to a VNI. Router MAC addresses of remote VTEPs are installed over this interface.

The Routed VLAN Interface or Switched Virtual Interface (SVI) iface vlan1001 is configured corresponding to the per-tenant VXLAN interface. It is attached to the tenant VRF. Remote host routes are installed over this SVI. The vlan-raw-device bridge is used to associate the SVI with the VLAN aware bridge. For a packet received from a locally attached host the SVI interface corresponding to the VLAN determines the VRF vrf vrf3981.

The VXLAN interface iface vni3981 defines a tunnel address that is used for the VXLAN tunnel header vlxan-local-tunnelip 10.0.0.11. This VTEP IP address is typically the loopback device address of the switch. When EVPN is provisioned, data plane MAC learning for VXLAN interfaces must be disabled because the purpose of EVPN is to exchange MACs between VTEPs in the control plane: bridge-learning off. EVPN is responsible for installing remote MACs. bridge-arp-nd-suppress suppresses ARP flooding over VXLAN tunnels. Instead, a local proxy handles ARP requests received from locally attached hosts for remote hosts. ARP suppression is the implementation for IPv4; ND suppression is the implementation for IPv6. It is recommended to enable ARP suppression on all VXLAN interfaces. Bridge Protocol Data Unit (BPDU) are not transmitted over VXLAN interfaces. So as a good practice bpduguard and pbdufilter are enabled with mstpctl-bpduguard yes and mstpctl-portbpdufilter yes. These settings filter BPDU and guard the spanning tree topology from unauthorized switches affecting the forwarding path. vxlan-id 3981 specifies the VXLAN Network Identifier (VNI). The type of VNI can either be layer-2 (L2) or layer-3 (L3). This is an implicit thing. A VNI is a L3 VNI (L3VNI) when a mapping exists that maps the VNI to a VRF (configured in /etc/frr/frr.conf) otherwise it is a L2 VNI (L2VNI).

# /etc/frr/frr.conf
+# [...]
+vrf vrf3981
+ vni 3981
+ exit-vrf
+#[...]
+router bgp 4200000011
+# [...]
+ address-family ipv4 unicast
+  redistribute connected route-map LOOPBACKS
+ # [...]
+ address-family l2vpn evpn
+  neighbor FABRIC activate
+  advertise-all-vni
+ exit-address-family
+# [...]
+router bgp 4200000011 vrf vrf3981
+ # [...]
+ address-family ipv4 unicast
+  redistribute connected
+  neighbor MACHINE maximum-prefix 100
+ exit-address-family
+ !
+ address-family l2vpn evpn
+  advertise ipv4 unicast
+ exit-address-family
+
+# [...]
+route-map LOOPBACKS permit 10
+ match interface lo
+# [...]

Listing 5: Leaf FRR configuration.

Listing 5 shows the required FRR configuration of the BGP control plane. Only content not discussed so far is explained. The section vrf vrf3981 contains the mapping from layer-3 VNI to VRF. This is required to be able to install EVPN IP prefix routes (type-5 routes) into the routing table. Further the file contains a global BGP instance router bgp 4200000011 definition. A new setting redistribute connected route-map LOOPBACKS is in place to filter the redistribution of routes that are not matching the local loopback interface. The route-map is defined with route-map LOOPBACKS permit 10. With the configuration line address-family l2vpn evpn, the EVPN address family is enabled between BGP neighbours. advertise-all-vni makes the switch a VTEP configures it in such a way, that all locally configured VNIs should be advertised by the BGP control plane.

The second BGP instance configuration is specific to the tenant VRF router bgp 4200000011 vrf vrf3981. This VRF BGP instance configures the l2vpn evpn address family with advertise ipv4 unicast to announce IP prefixes in BGP's routing information base (RIB). This is required to apply learned routes to the routing tables of connected hosts. The Maximum-Prefix feature is useful to avoid that a router receives more routes than the router memory can take. The maximum number of prefixes a tenant server is allowed to announce is limited to 100 with: neighbor MACHINE maximum-prefix 100.

Spine setup

On the spine switches the setup is quite simple. /etc/network/interfaces contains the loopback interface definition to support BGP unnumbered and listings for connected switch ports to provide proper MTUs (Listing 6). I.e. swp1 is configured with an MTU of 9216 as it is a VXLAN-facing interface.

# /etc/network/interfaces
+# [...]
+iface swp1
+    mtu 9216

Listing 6: Fragment of spine interface configuration.

The spines are important to forward EVPN routes and transport VXLAN packets between the VTEPs. They are not configured as VTEPs. The FRR configuration only contains the already known global BGP instance configuration router bgp 4200000020 plus the activation of the l2vpn evpn address family address-family l2vpn evpn to enable EVPN type-5 route forwarding (Listing 7).

hostname spine01
+username admin nopassword
+!
+# [...]
+interface swp1
+ ipv6 nd ra-interval 6
+ no ipv6 nd suppress-ra
+!
+# [...]
+!
+router bgp 4200000020
+ # [...]
+!
+ address-family l2vpn evpn
+  neighbor FABRIC activate
+ exit-address-family
+!
+# [...]

Listing 7: Fragment of spine FRR configuration to show the activated L2VPN EVPN address-family.

Tenant Firewalls: EVPN-to-the-Host

In case a tenant server needs to reach out to external networks as the Internet, a tenant firewall is provisioned. The firewall is a bare metal server without a switching silicon. Thus, there is no installation of SONiC. FRR provides the BGP / EVPN functionality known as EVPN-to-the-host. The firewall is configured as a VTEP and applies dynamic route-leaking to install routes of an foreign VRF. The set of routes that are leaked are restricted with route-maps.

As Listing 8 shows, the firewall is configured with VXLAN interfaces as known from the leaf setup. Additionally, a VXLAN setup for VRF vrfInternet is added to provide Internet access. vrfInternet contains a route to the Internet that will be leaked into the tenant VRF.

Traffic that originates from the tenant network 10.0.0.0/22 will be masqueraded before leaving the interface vlanInternet towards the internet.

# /etc/network/interfaces
+# [...]
+iface bridge
+# [...]
+iface vlan1001
+# [...]
+iface vni3981
+# [...]
+iface vrf3981
+# [...]
+iface vlanInternet
+    mtu 9000
+    vlan-id 4009
+    vlan-raw-device bridge
+    vrf vrfInternet
+    address 185.1.2.3
+    post-up iptables -t nat -A POSTROUTING -s 10.0.0.0/22 -o vlanInternet -j MASQUERADE
+    pre-down iptables -t nat -D POSTROUTING -s 10.0.0.0/22 -o vlanInternet -j MASQUERADE
+
+iface vniInternet
+    mtu 9000
+    bridge-access 4009
+    mstpctl-bpduguard yes
+    mstpctl-portbpdufilter yes
+    vxlan-id 104009
+    vxlan-local-tunnelip 10.0.0.40
+
+iface vrfInternet
+    mtu 9000
+    vrf-table auto

Listing 8: Interfaces configuration of firewall to show the VTEP interface configuration.

To install a default route into the routing table of tenant VRF vrf3981 a dynamic route leak is established for it (import vrf vrfInternet). With the help of a route-map import vrf route-map vrf3981-import-map only the default route will be leaked:

root@firewall01:~# vtysh -c 'show ip route vrf vrf3981'
+# [...]
+VRF vrf3981:
+S>* 0.0.0.0/0 [1/0] is directly connected, vrfInternet(vrf vrfInternet), 03:19:26
+B>* 10.0.0.1/32 [20/0] via 10.0.0.12, vlan1001 onlink, 02:34:48
+  *                    via 10.0.0.11, vlan1001 onlink, 02:34:48
+B>* 10.0.0.2/32 [20/0] via 10.0.0.12, vlan1001 onlink, 02:34:49
+  *                    via 10.0.0.11, vlan1001 onlink, 02:34:49

To receive responses from vrfInternet in vrf3981 a route is leaked into vrfInternet as well (import vrf vrf3981) restricted with the route-map vrfInternet-import-map that allows leaking of the tenant routes as well as internet prefixes used on worker nodes of the tenant. To limit the prefixes that are announced from the firewall within the global BGP instance a route-map only-self-out is defined and applied within the ipv4 and l2vpn evpn address family. Together with the definition of an as path access list bgp as-path access-list it avoids the announcement of prefixes to non VRF BGP peers.

# /etc/frr/frr.conf
+!
+vrf vrf3981
+ vni 3981
+!
+vrf vrfInternet
+ vni 104009
+!
+# [...]
+!
+router bgp 4200000040
+ # [...]
+ !
+ address-family ipv4 unicast
+  # [...]
+  neighbor FABRIC route-map only-self-out out
+ exit-address-family
+ !
+!
+router bgp 4200000040 vrf vrf3981
+ # [...]
+ address-family ipv4 unicast
+  redistribute connected
+  import vrf vrfInternet
+  import vrf route-map vrf3981-import-map
+ # [...]
+ address-family l2vpn evpn
+  advertise ipv4 unicast
+ # [...]
+router bgp 4200000040 vrf vrfInternet
+ # [...]
+ address-family ipv4 unicast
+  redistribute connected
+  import vrf vrf3981
+  import vrf route-map vrfInternet-import-map
+ # [...]
+ address-family l2vpn evpn
+  advertise ipv4 unicast
+ # [...]
+ bgp as-path access-list SELF permit ^$
+!
+route-map only-self-out permit 10
+ match as-path SELF
+!
+route-map only-self-out deny 99
+!
+route-map LOOPBACKS permit 10
+ match interface lo
+!
+ip prefix-list vrf3981-import-prefixes seq 100 permit 0.0.0.0/0
+!
+route-map vrf3981-import-map permit 10
+ match ip address prefix-list vrf3981-import-prefixes
+!
+route-map vrf3981-import-map deny 99
+!
+ip prefix-list vrfInternet-import-prefixes seq 100 permit 10.0.0.0/22 le 32
+ip prefix-list vrfInternet-import-prefixes seq 101 permit 185.1.2.0/24 le 32
+ip prefix-list vrfInternet-import-prefixes seq 102 permit 185.27.0.0/27 le 32
+!
+route-map vrfInternet-import-map permit 10
+ match ip address prefix-list vrfInternet-import-prefixes
+!
+route-map vrfInternet-import-map deny 99
+!
+line vty
+!

Listing 9: FRR configuration of a tenant firewall to show route leak and prefix announcement filtering.

Exit Switch

Traffic to external networks is routed via the firewalls to the exit switch. The exit switch, as an exception, connects to the Internet Service Provider using numbered BGP. Numbered BGP implies to assign IPv4 addresses to network interfaces (See Listing 10, swp1). Interface swp1 is enslaved into vrf vrfInternet to include the port that is connected to the ISP within the VRF that is expected to contain a way into the Internet. The exit switch is configured to be a VTEP to terminate traffic coming from the firewall VRF vrfInternet.

# /etc/network/interfaces
+# [...]
+iface swp1
+    mtu 9000
+    vrf vrfInternet
+    address 172.100.0.2/30
+# [...]
+iface vlan4000
+    mtu 9000
+    address 10.0.0.71/24
+    vlan-id 4000
+    vlan-raw-device bridge
+# [...]
+iface vlanInternet
+# [...]
+iface vniInternet
+# [...]
+iface vrfInternet
+# [...]

Listing 10: Fragment of interfaces configuration of exit switch.

The configuration of FRR is equivalent to the previously discussed ones. It contains a global BGP instance configuration that enables IPv4 unicast and l2vpn evpn address families. The vrfInternet BGP instance defines neighbor 172.100.0.1 peer-group INTERNET to use "old style BGP" transit network.

# [..]
+vrf vrfInternet
+ vni 104009
+!
+# [...]
+router bgp 4200000031
+ bgp router-id 10.0.0.31
+ neighbor FABRIC peer-group
+ neighbor FABRIC remote-as external
+ neighbor FABRIC timers 1 3
+ # [...]
+ !
+ address-family ipv4 unicast
+  neighbor FABRIC activate
+  redistribute connected route-map LOOPBACKS
+ exit-address-family
+ !
+ address-family l2vpn evpn
+  neighbor FABRIC activate
+  advertise-all-vni
+ exit-address-family
+!
+router bgp 4200000031 vrf vrfInternet
+ bgp router-id 10.0.0.31
+ bgp bestpath as-path multipath-relax
+ neighbor INTERNET peer-group
+ neighbor INTERNET remote-as external
+ neighbor INTERNET timers 1 3
+ neighbor 172.100.0.1 peer-group INTERNET
+ !
+ address-family ipv4 unicast
+  neighbor INTERNET route-map PREPEND-PATH-TO-DISFAVOR-IN in
+  neighbor INTERNET route-map PREPEND-PATH-TO-DISFAVOR-OUT out
+ exit-address-family
+
+ !
+ address-family l2vpn evpn
+  advertise ipv4 unicast
+ exit-address-family
+!
+route-map LOOPBACKS permit 10
+ match interface lo
+!
+route-map PREPEND-PATH-TO-DISFAVOR-IN permit 10
+ set as-path prepend last-as 2
+!
+route-map PREPEND-PATH-TO-DISFAVOR-OUT permit 10
+ set as-path prepend last-as 2
+!
+vrf mgmt
+ ip route 10.0.0.0/24 10.0.0.71 nexthop-vrf default
+ exit-vrf
+!
+ip route 0.0.0.0/0 192.168.0.254 nexthop-vrf mgmt
+!
+line vty
+!

Listing 11: Fragment of FRR configuration on exit switch to give an example for numbered BGP and route leak.

In addition to the standard BGP setup the exit switches have configured static route leak to support internet access during PXE. There is one route leak from default VRF into the mgmt VRF defined with: ip route 0.0.0.0/0 192.168.0.254 nexthop-vrf mgmt and another one from mgmt VRF into the default VRF: ip route 10.0.0.0/24 10.0.0.71 nexthop-vrf default. The first one adds a default route into the default VRF and the second one routes traffic destined to the PXE network back from mgmt VRF into the default VRF.

To reach out into external networks each of the exit nodes joins a BGP session with a distinct external router. There is a different latency to each of these routers. To favor routes of exit nodes connected with lower latency over exit nodes with higher latency two route maps PREPEND-PATH-TO-DISFAVOR-IN and PREPEND-PATH-TO-DISFAVOR-OUT are added to high latency exit nodes. These route maps apply actions to prolong the path of the incoming and outgoing routes. Because of this path extension BGP will calculate a lower weight for these paths and favors paths via other exit nodes. It is important to know that within an address family only one route map (the last) will be applied. To apply more than one actions within a route-map the required entries can be applied to a single route-map.

PXE Boot Mode

Before a bare metal server can act as tenant server or tenant firewall, it has to be provisioned. Within the Metal domain, this provisioning mode is called "PXE Mode" since it is based on Preboot eXecution Environment (PXE). PXE uses protocols like DHCP. This requires all bare metal servers that need provisioning to be located in a layer-2 domain where DHCP is available. This domain is a VLAN vlan4000. A DHCP server for PXE Mode is installed on the exit switches to work in this specific VLAN.

# /etc/default/isc-dhcp-server
+INTERFACES="vlan4000"

Listing 13: DHCP server configuration of exit switches.

As shown in listing 13, the PXE DHCP server is located on the exit switches and enforced to bind to interface vlan4000. This represents a layer-2 separation that allows only DHCP clients in the same VLAN to request IP addresses. Only unprovisionned bare metal servers are configured to be member of this VLAN. Thus unwanted or accidental provisionning is impossible.

To provide vlan4000 on the leaves (that face the bare metal servers) the exit and leaf switches are configured as VTEPs and share an interface configuration that contains the required interfaces (Listing 13). Since no EVPN routing is in place vni104000 is configured as an L2 VNI (there is no mapping for this VNI in /etc/frr/frr.conf).

# /etc/network/interfaces
+# [...]
+iface bridge
+    bridge-ports vni104000 [...]
+    bridge-vids 4000 [...]
+    bridge-vlan-aware yes
+
+iface vlan4000
+# [...]
+
+iface vni104000
+# [...]

Listing 13: Interfaces configuration on exit and leaf switches to show DHCP/PXE related fragments.

On the leaf switches the bare metal server facing ports are configured as VLAN access ports to carry the traffic for only the PXE VLAN vlan4000 (listing 14)to separate unprovisioned from other bare metal servers.

# /etc/network/interfaces
+# [...]
+auto swp1
+iface swp1
+    mtu 9000
+    bridge-access 4000
+# [...]

Listing 14: VLAN access setup for bare metal server facing ports on leaves.

Once a bare metal server is provisioned it is deconfigured from PXE VLAN vlan4000 to avoid accidental or unwanted provisioning.

During provisioning bare metal servers get internet access via the management network of the exit switches. This is because the exit switches are announced as DHCP gateway to the DHCP clients.

Management Network

To manage network switches beside the out-of-band system console access a further management access is required. For this purpose the concept of Management VRF is applied. The Management VRF is a subset of VRF. It provides a separation between out-of-band management network and the in-band data plane network by introducing another routing table mgmt. SONiC supports eth0 to be used as the management interface.

To enable and use the Management VRF all switches have to be connected via their eth0 interface to a management-switch. The management switch is connected to a management server. All access is established from within the management server. Logins to the switch are set into the Management VRF context once the Management VRF is enabled.

diff --git a/v0.18.15/overview/os/index.html b/v0.18.15/overview/os/index.html new file mode 100644 index 0000000000..8cae516697 --- /dev/null +++ b/v0.18.15/overview/os/index.html @@ -0,0 +1,2 @@ + +Operating Systems · metal-stack

Operating Systems

Our operating system images are built on regular basis from the metal-images repository.

All images are hosted on GKE at images.metal-stack.io. Feel free to use this as a mirror for your metal-stack partitions if you want. The metal-stack developers continuously have an eye on the supported images. They are updated regularly and scanned for vulnerabilities.

Supported OS Images

The operating system images that we build are trimmed down to their bare essentials for serving as Kubernetes worker nodes. Small image sizes make machine provisioning blazingly fast.

The supported images for worker nodes currently are:

PlatformDistributionVersion
LinuxDebian11
LinuxUbuntu22.04

The supported images for firewalls are:

PlatformDistributionVersionBased On
LinuxUbuntu322.04

Building Your Own Images

It is fully possible to build your own operating system images and provide them through the metal-stack.

There are some conventions though that you need to follow in order to make your image installable through the metal-hammer. You should understand the machine provisioning sequence before starting to write your own images.

  1. Images need to be compressed to a tarball using the lz4 compression algorithm
  2. An md5 checksum file with the same name as the image archive needs to be provided in the download path along with the actual os image
  3. A packages.txt containing the packages contained in the OS image should be provided in the download path (not strictly required)
  4. Consider semantic image versioning, which we use in our algorithms to select latest images (e.g. os-major.minor.patch ➡️ ubuntu-19.10.20191018)
  5. Consider installing packages used by the metal-stack infrastructure
    • FRR to enable routing-to-the-host in our network topology
    • go-lldpd to enable checking if the machine is still alive after user allocation
    • ignition for enabling users to run user-specific initialization instructions before bootup. It's pretty small in size, which is why we use it. However, you are free to use other cloud instance initialization tools if you want to.
  6. You have to provide an install.sh script, which applies user-specific configuration in the installed image
    • This script should consume parameters from the install.yaml file that the metal-hammer writes to /etc/metal/install.yaml
    • Please check this contract between image and the metal-hammer here
  7. For the time being, your image must be able to support kexec into the new operating system kernel, the kexec command is issued by the metal-hammer after running the install.sh. We do this because kexec is much faster than rebooting a machine.
  8. We recommend building images from Dockerfiles as it is done in metal-images repository.
Info

Building own operating system images is an advanced topic. When you have just started with metal-stack, we recommend using the public operating system images first.

diff --git a/v0.18.15/overview/provisioning_sequence.drawio.svg b/v0.18.15/overview/provisioning_sequence.drawio.svg new file mode 100644 index 0000000000..dbe4e7fe2f --- /dev/null +++ b/v0.18.15/overview/provisioning_sequence.drawio.svg @@ -0,0 +1,921 @@ + + + + + + + + + + +
+
+
+ install +
+
+
+
+ + install + +
+
+ + + + + + +
+
+
+ wait +
+
+
+
+ + wait + +
+
+ + + + + + + +
+
+
+ register +
+
+
+
+ + register + +
+
+ + + + + + +
+
+
+ done +
+
+
+
+ + done + +
+
+ + + + + + +
+
+
+ prepare +
+
+
+
+ + prepare + +
+
+ + + + + + +
+
+
+ pxe +
+
+
+
+ + pxe + +
+
+ + + + + +
+
+
+ switch +
+
+
+
+ + switch + +
+
+ + + + + +
+
+
+ metal-api +
+
+
+
+ + metal-api + +
+
+ + + + + + +
+
+
+ success +
+
+
+
+ + success + +
+
+ + + + + + + +
+
+
+ allocate +
+
+
+
+ + allocate + +
+
+ + + + + +
+
+
+ set allocatable flag +
+ to true +
+
+
+
+ + set allocatable... + +
+
+ + + + + +
+
+
+ elect machine candidate +
+
+
+
+ + elect machine c... + +
+
+ + + + + +
+
+
+ pixiecore +
+
+
+
+ + pixiecore + +
+
+ + + + + + +
+
+
+ metal-core +
+
+
+
+ + metal-core + +
+
+ + + + + + + +
+
+
+ reconcile network +
+
+
+
+ + reconcile network + +
+
+ + + + + +
+
+
+ metal-hammer +
+
+
+
+ + metal-hammer + +
+
+ + + + + +
+
+
+ download and burn target os image +
+
+
+
+ + download and bu... + +
+
+ + + + + +
+
+
+ run image install.sh and ignition +
+
+
+
+ + run image insta... + +
+
+ + + + + +
+
+
+ report install success, finalize machine allocation +
+
+
+
+ + report install... + +
+
+ + + + + +
+
+
+ use +
+
+
+
+ + use + +
+
+ + + + + +
+
+
+ machine +
+
+
+
+ + machine + +
+
+ + + + + + +
+
+
+ booting metal-hammer +
+
+
+
+ + booting metal-hammer + +
+
+ + + + + + +
+
+
+ machine pxe boot event +
+
+
+
+ + machine pxe boo... + +
+
+ + + + + +
+
+
+ discovery image url +
+
+
+
+ + discovery image url + +
+
+ + + + + +
+
+
+ request boot image +
+
+
+
+ + request boot image + +
+
+ + + + + +
+
+
+ machine state and partition info +
+
+
+
+ + machine state and partition info + +
+
+ + + + + +
+
+
+ lookup partition boot image and machine +
+
+
+
+ + lookup partition boot image and machine + +
+
+ + + + + +
+
+
+ pxe request +
+
+
+
+ + pxe request + +
+
+ + + + + +
+
+
+ pxe response +
+
+
+
+ + pxe response + +
+
+ + + + + +
+
+
+ machine prepare event +
+
+
+
+ + machine prepare... + +
+
+ + + + + + +
+
+
+ run init process +
+
+
+
+ + run init process + +
+
+ + + + + +
+
+
+ machine register event +
+
+
+
+ + machine registe... + +
+
+ + + + + +
+
+
+ machine register +
+
+
+
+ + machine register + +
+
+ + + + + +
+
+
+ success +
+
+
+
+ + success + +
+
+ + + + + +
+
+
+ machine wait event +
+
+
+
+ + machine wait ev... + +
+
+ + + + +
+
+
+ [ until allocated ] +
+
+
+
+ + [ until allocat... + +
+
+ + + + + +
+
+
+ machine wait for allocation +
+
+
+
+ + machine wait for allocation + +
+
+ + + + + +
+
+
+ allocation data +
+
+
+
+ + allocation data + +
+
+ + + + + +
+
+
+ machine install event +
+
+
+
+ + machine install... + +
+
+ + + + + +
+
+
+ ensure boot from HD +
+
+
+
+ + ensure boot fro... + +
+
+ + + + + +
+
+
+ kexec os kernel +
+
+
+
+ + kexec os kernel + +
+
+ + + + + +
+
+
+ machine boot os kernel event +
+
+
+
+ + machine boot os... + +
+
+ + + + + +
+
+
+ report machine phone home event +
+ [ if go-lldp running in target os ] +
+
+
+
+ + report machine... + +
+
+ + + + + + + +
+
+
+ start interfaces and +
+ find LLDP neighbors +
+
+
+
+ + start interface... + +
+
+ + + + + +
+
+
+ discover system +
+ hardware +
+
+
+
+ + discover system... + +
+
+ + + + + +
+
+
+ wipe disks +
+
+
+
+ + wipe disks + +
+
+ + + + + +
+
+
+ ensure UEFI boot +
+
+
+
+ + ensure UEFI boot + +
+
+ + + + + +
+
+
+ reconfigure switch +
+
+
+
+ + reconfigure swi... + +
+
+ + + + + +
+
+
+ run target os kernel +
+
+
+
+ + run target os kernel + +
+
+
+ + + + + Text is not SVG - cannot display + + + +
\ No newline at end of file diff --git a/v0.18.15/overview/storage/index.html b/v0.18.15/overview/storage/index.html new file mode 100644 index 0000000000..8da7160954 --- /dev/null +++ b/v0.18.15/overview/storage/index.html @@ -0,0 +1,12 @@ + +Storage · metal-stack

Storage

When working with bare-metal servers, providing cloud storage is a challenge. With physical machines there is no opportunity that a hypervisor can mount storage devices into the servers and thus, we have to implement other mechanisms that are capable of dynamically mounting storage onto the machines.

In the meantime, we have started to integrate third-party solutions into our metal-stack landscape. They help us to provide modern, well-integrated and scalable storage solutions to our end-users.

    Lightbits Labs NVMe over TCP Storage Integration

    Lightbits Labs offers a proprietary implementation of persistent storage using NVMe over TCP. The solution has some very superior traits that fit very well to metal-stack. The strongest advantages are:

    • High performance
    • Built-in multi-tenant capabilities
    • Configurable compression and replication factors

    We are maintaining an open source integration for running LightOS in our Gardener cluster provisioning. You can enable it through the controller registration of the gardener-extension-provider-metal.

    With the integration in place, the extension-provider deploys a duros-controller along with a Duros Storage CRD into the seed's shoot namespace. The duros-controller takes care of creating projects and managing credentials at the Lightbits Duros API. It also provides storage classes as configured in the extension-provider's controller registration to the customer's shoot cluster such that users can start consuming the Lightbits storage immediately.

    Simple Node Local Storage with csi-driver-lvm

    If you wish to quickly start off with cluster provisioning without caring so much about complex cloud storage solutions, we recommend using a small storage driver we wrote called csi-driver-lvm. It provides a storage class that manages node-local storage through LVM.

    A definition of a PVC can look like this:

    apiVersion: v1
    +kind: PersistentVolumeClaim
    +metadata:
    +  name: csi-pvc
    +spec:
    +  accessModes:
    +  - ReadWriteOnce
    +  resources:
    +    requests:
    +      storage: 100Mi
    +  storageClassName: csi-lvm-sc-linear

    The solution does not provide cloud-storage or whatsoever, but it improves the user's accessibility of local storage on bare-metal machines through Kubernetes. Check out the driver's documentation here.

    diff --git a/v0.18.15/overview/vrf-simple.drawio b/v0.18.15/overview/vrf-simple.drawio new file mode 100644 index 0000000000..edaefe2402 --- /dev/null +++ b/v0.18.15/overview/vrf-simple.drawio @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/v0.18.15/overview/vrf-simple.svg b/v0.18.15/overview/vrf-simple.svg new file mode 100644 index 0000000000..1e31019a10 --- /dev/null +++ b/v0.18.15/overview/vrf-simple.svg @@ -0,0 +1 @@ +
    Machine 2
    Machine 2
    Machine 1
    Machine 1
    leaf
    leaf
    VRF 1
    VRF 1
    VRF 2
    VRF 2
    Machine 3
    Machine 3
    Viewer does not support full SVG 1.1
    \ No newline at end of file diff --git a/v0.18.15/quickstart/index.html b/v0.18.15/quickstart/index.html new file mode 100644 index 0000000000..de6bc4d4fa --- /dev/null +++ b/v0.18.15/quickstart/index.html @@ -0,0 +1,2 @@ + +Quickstart · metal-stack

    Getting Started

    Before starting to buy any hardware, you should try out the metal-stack on your notebook and familiarize with the software.

    For this, we made the mini-lab.

    The mini-lab is a fully virtual setup of metal-stack and is supposed to be run locally on a single machine. For this reason, the setup was slightly simplified in comparison to full-blown setups on real hardware. However, the lab should help to understand all ideas behind the metal-stack.

    Get your hands dirty and follow the guide on how to get on with the mini-lab here.

    diff --git a/v0.18.15/search_index.js b/v0.18.15/search_index.js new file mode 100644 index 0000000000..fa33928d26 --- /dev/null +++ b/v0.18.15/search_index.js @@ -0,0 +1,3 @@ +var documenterSearchIndex = {"docs": +[{"location":"external/metalctl/docs/metalctl_network_edit/#metalctl-network-edit","page":"metalctl network edit","title":"metalctl network edit","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_network_edit/","page":"metalctl network edit","title":"metalctl network edit","text":"edit the network through an editor and update","category":"page"},{"location":"external/metalctl/docs/metalctl_network_edit/","page":"metalctl network edit","title":"metalctl network edit","text":"metalctl network edit [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_network_edit/#Options","page":"metalctl network edit","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_network_edit/","page":"metalctl network edit","title":"metalctl network edit","text":" -h, --help help for edit","category":"page"},{"location":"external/metalctl/docs/metalctl_network_edit/#Options-inherited-from-parent-commands","page":"metalctl network edit","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_network_edit/","page":"metalctl network edit","title":"metalctl network edit","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_network_edit/#SEE-ALSO","page":"metalctl network edit","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_network_edit/","page":"metalctl network edit","title":"metalctl network edit","text":"metalctl network\t - manage network entities","category":"page"},{"location":"external/metalctl/docs/metalctl_filesystemlayout_list/#metalctl-filesystemlayout-list","page":"metalctl filesystemlayout list","title":"metalctl filesystemlayout list","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_filesystemlayout_list/","page":"metalctl filesystemlayout list","title":"metalctl filesystemlayout list","text":"list all filesystemlayouts","category":"page"},{"location":"external/metalctl/docs/metalctl_filesystemlayout_list/","page":"metalctl filesystemlayout list","title":"metalctl filesystemlayout list","text":"metalctl filesystemlayout list [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_filesystemlayout_list/#Options","page":"metalctl filesystemlayout list","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_filesystemlayout_list/","page":"metalctl filesystemlayout list","title":"metalctl filesystemlayout list","text":" -h, --help help for list\n --sort-by strings sort by (comma separated) column(s), sort direction can be changed by appending :asc or :desc behind the column identifier. possible values: description|id|name","category":"page"},{"location":"external/metalctl/docs/metalctl_filesystemlayout_list/#Options-inherited-from-parent-commands","page":"metalctl filesystemlayout list","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_filesystemlayout_list/","page":"metalctl filesystemlayout list","title":"metalctl filesystemlayout list","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_filesystemlayout_list/#SEE-ALSO","page":"metalctl filesystemlayout list","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_filesystemlayout_list/","page":"metalctl filesystemlayout list","title":"metalctl filesystemlayout list","text":"metalctl filesystemlayout\t - manage filesystemlayout entities","category":"page"},{"location":"development/proposals/MEP10/README/#SONiC-Support","page":"SONiC Support","title":"SONiC Support","text":"","category":"section"},{"location":"development/proposals/MEP10/README/","page":"SONiC Support","title":"SONiC Support","text":"As writing this proposal, metal-stack only supports Cumulus on Broadcom ASICs. Unfortunately, after the acquisition of Cumulus Networks by Nvidia, Broadcom decided to cut its relationship with Cumulus, and therefore Cumulus 4.2 is the last version that supports Broadcom ASICs. Since trashing the existing hardware is not a solution, adding support for a different network operating system is necessary.","category":"page"},{"location":"development/proposals/MEP10/README/","page":"SONiC Support","title":"SONiC Support","text":"One of the remaining big players is SONiC, which Microsoft created to scale the network of Azure. It's an open-source project and is now part of the Linux Foundation.","category":"page"},{"location":"development/proposals/MEP10/README/","page":"SONiC Support","title":"SONiC Support","text":"For a general introduction to SONiC, please follow the Architecture official documentation.","category":"page"},{"location":"development/proposals/MEP10/README/#ConfigDB","page":"SONiC Support","title":"ConfigDB","text":"","category":"section"},{"location":"development/proposals/MEP10/README/","page":"SONiC Support","title":"SONiC Support","text":"On a cold start, the content of /etc/sonic/config_db.json will be loaded into the Redis database CONFIG_DB, and both contain the switch's configuration except the BGP unnumbered configuration, which still has to be configured directly by the frr configuration files. The SONiC community is working to remove this exception, but no release date is known.","category":"page"},{"location":"development/proposals/MEP10/README/#BGP-Configuration","page":"SONiC Support","title":"BGP Configuration","text":"","category":"section"},{"location":"development/proposals/MEP10/README/","page":"SONiC Support","title":"SONiC Support","text":"Frr runs inside a container, and a shell script configured it on the container startup. For BGP unnumbered, we must set the configuration variable docker_routing_config_mode to split to prevent SONiC from overwriting our configuration files created by metal-core. But by using the split mode, the integrated configuration mode of frr is deactivated, and we have to write our BGP configuration to the daemon-specific files bgp.conf, staticd.conf, and zebra.conf instead to frr.conf.","category":"page"},{"location":"development/proposals/MEP10/README/","page":"SONiC Support","title":"SONiC Support","text":"elif [ \"$CONFIG_TYPE\" == \"split\" ]; then\n echo \"no service integrated-vtysh-config\" > /etc/frr/vtysh.conf\n rm -f /etc/frr/frr.conf","category":"page"},{"location":"development/proposals/MEP10/README/","page":"SONiC Support","title":"SONiC Support","text":"Reference: docker-init","category":"page"},{"location":"development/proposals/MEP10/README/","page":"SONiC Support","title":"SONiC Support","text":"Adding support for the integrated configuration mode, we must at least adjust the startup shell script and the supervisor configuration:","category":"page"},{"location":"development/proposals/MEP10/README/","page":"SONiC Support","title":"SONiC Support","text":"{% if DEVICE_METADATA.localhost.docker_routing_config_mode is defined and DEVICE_METADATA.localhost.docker_routing_config_mode == \"unified\" %}\n[program:vtysh_b]\ncommand=/usr/bin/vtysh -b","category":"page"},{"location":"development/proposals/MEP10/README/","page":"SONiC Support","title":"SONiC Support","text":"Reference: supervisord.conf","category":"page"},{"location":"development/proposals/MEP10/README/#Non-BGP-Configuration","page":"SONiC Support","title":"Non-BGP Configuration","text":"","category":"section"},{"location":"development/proposals/MEP10/README/","page":"SONiC Support","title":"SONiC Support","text":"For the Non-BGP configuration we have to write it into the Redis database directly or via one of the following interfaces:","category":"page"},{"location":"development/proposals/MEP10/README/","page":"SONiC Support","title":"SONiC Support","text":"config replace \nthe Mgmt Framework\nthe SONiC restapi","category":"page"},{"location":"development/proposals/MEP10/README/","page":"SONiC Support","title":"SONiC Support","text":"Directly writing into the Redis database isn't a stable interface, and we must determine the create, delete, and update operations on our own. The last point is also valid for the Mgmt Framework and the SONiC restapi. Furthermore, the Mgmt Framework doesn't start anymore for several months, and a potential fix is still not merged. And the SONiC restapi isn't enabled by default, and we must build and maintain our own SONiC images.","category":"page"},{"location":"development/proposals/MEP10/README/","page":"SONiC Support","title":"SONiC Support","text":"Using config replace would reduce the complexity in the metal-core codebase because we don't have to determine the actual changes between the running and the desired configuration. The approach's drawbacks are using a version of SONiC that contains the PR Yang support for VXLAN, and we must provide the whole new startup configuration to prevent unwanted deconfiguration.","category":"page"},{"location":"development/proposals/MEP10/README/#Configure-Loopback-interface-and-activate-VXLAN","page":"SONiC Support","title":"Configure Loopback interface and activate VXLAN","text":"","category":"section"},{"location":"development/proposals/MEP10/README/","page":"SONiC Support","title":"SONiC Support","text":"{\n \"LOOPBACK_INTERFACE\": {\n \"Loopback0\": {},\n \"Loopback0|\": {}\n },\n \"VXLAN_TUNNEL\": {\n \"vtep\": {\n \"src_ip\": \"\"\n }\n }\n}","category":"page"},{"location":"development/proposals/MEP10/README/#Configure-MTU","page":"SONiC Support","title":"Configure MTU","text":"","category":"section"},{"location":"development/proposals/MEP10/README/","page":"SONiC Support","title":"SONiC Support","text":"{\n \"PORT\": {\n \"Ethernet0\": {\n \"mtu\": \"9000\"\n }\n }\n}","category":"page"},{"location":"development/proposals/MEP10/README/#Configure-PXE-Vlan","page":"SONiC Support","title":"Configure PXE Vlan","text":"","category":"section"},{"location":"development/proposals/MEP10/README/","page":"SONiC Support","title":"SONiC Support","text":"{\n \"VLAN\": {\n \"Vlan4000\": {\n \"vlanid\": \"4000\"\n }\n },\n \"VLAN_INTERFACE\": {\n \"Vlan4000\": {},\n \"Vlan4000|\": {}\n },\n \"VLAN_MEMBER\": {\n \"Vlan4000|\": {\n \"tagging_mode\": \"untagged\"\n }\n },\n \"VXLAN_TUNNEL_MAP\": {\n \"vtep|map_104000_Vlan4000\": {\n \"vlan\": \"Vlan4000\",\n \"vni\": \"104000\"\n }\n }\n}","category":"page"},{"location":"development/proposals/MEP10/README/#Configure-VRF","page":"SONiC Support","title":"Configure VRF","text":"","category":"section"},{"location":"development/proposals/MEP10/README/","page":"SONiC Support","title":"SONiC Support","text":"{\n \"INTERFACE\": {\n \"Ethernet0\": {\n \"vrf_name\": \"vrf104001\"\n }\n },\n \"VLAN\": {\n \"Vlan4001\": {\n \"vlanid\": \"4001\"\n }\n },\n \"VLAN_INTERFACE\": {\n \"Vlan4001\": {\n \"vrf_name\": \"vrf104001\"\n }\n },\n \"VRF\": {\n \"vrf104001\": {\n \"vni\": \"104001\"\n }\n },\n \"VXLAN_TUNNEL_MAP\": {\n \"vtep|map_104001_Vlan4001\": {\n \"vlan\": \"Vlan4001\",\n \"vni\": \"104001\"\n }\n }\n}","category":"page"},{"location":"development/proposals/MEP10/README/#DHCP-Relay","page":"SONiC Support","title":"DHCP Relay","text":"","category":"section"},{"location":"development/proposals/MEP10/README/","page":"SONiC Support","title":"SONiC Support","text":"The DHCP relay container only starts if DEVICE_METADATA.localhost.type is equal to ToRRouter.","category":"page"},{"location":"development/proposals/MEP10/README/#LLDP","page":"SONiC Support","title":"LLDP","text":"","category":"section"},{"location":"development/proposals/MEP10/README/","page":"SONiC Support","title":"SONiC Support","text":"SONiC always uses the local port subtype for LLDP and sets it to some freely configurable alias field of the interface.","category":"page"},{"location":"development/proposals/MEP10/README/","page":"SONiC Support","title":"SONiC Support","text":"# Get the port alias. If None or empty string, use port name instead\nport_alias = port_table_dict.get(\"alias\")\nif not port_alias:\n self.log_info(\"Unable to retrieve port alias for port '{}'. Using port name instead.\".format(port_name))\n port_alias = port_name\n\nlldpcli_cmd = \"lldpcli configure ports {0} lldp portidsubtype local {1}\".format(port_name, port_alias)","category":"page"},{"location":"development/proposals/MEP10/README/","page":"SONiC Support","title":"SONiC Support","text":"Reference: lldpmgr","category":"page"},{"location":"development/proposals/MEP10/README/#Mgmt-Interface","page":"SONiC Support","title":"Mgmt Interface","text":"","category":"section"},{"location":"development/proposals/MEP10/README/","page":"SONiC Support","title":"SONiC Support","text":"The mgmt interface is eth0. To configure a static IP address and activate the Mgmt VRF, use:","category":"page"},{"location":"development/proposals/MEP10/README/","page":"SONiC Support","title":"SONiC Support","text":"{\n \"MGMT_INTERFACE\": {\n \"eth0|\": {\n \"gwaddr\": \"\"\n }\n },\n \"MGMT_VRF_CONFIG\": {\n \"vrf_global\": {\n \"mgmtVrfEnabled\": \"true\"\n }\n }\n}","category":"page"},{"location":"development/proposals/MEP10/README/","page":"SONiC Support","title":"SONiC Support","text":"IP forwarding is deactivated on eth0, and no IP Masquerade is configured.","category":"page"},{"location":"external/metalctl/docs/metalctl_update_check/#metalctl-update-check","page":"metalctl update check","title":"metalctl update check","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_update_check/","page":"metalctl update check","title":"metalctl update check","text":"check for update of the program","category":"page"},{"location":"external/metalctl/docs/metalctl_update_check/","page":"metalctl update check","title":"metalctl update check","text":"metalctl update check [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_update_check/#Options","page":"metalctl update check","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_update_check/","page":"metalctl update check","title":"metalctl update check","text":" -h, --help help for check","category":"page"},{"location":"external/metalctl/docs/metalctl_update_check/#Options-inherited-from-parent-commands","page":"metalctl update check","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_update_check/","page":"metalctl update check","title":"metalctl update check","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_update_check/#SEE-ALSO","page":"metalctl update check","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_update_check/","page":"metalctl update check","title":"metalctl update check","text":"metalctl update\t - update the program","category":"page"},{"location":"external/metalctl/docs/metalctl_tenant/#metalctl-tenant","page":"metalctl tenant","title":"metalctl tenant","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_tenant/","page":"metalctl tenant","title":"metalctl tenant","text":"manage tenant entities","category":"page"},{"location":"external/metalctl/docs/metalctl_tenant/#Synopsis","page":"metalctl tenant","title":"Synopsis","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_tenant/","page":"metalctl tenant","title":"metalctl tenant","text":"a tenant belongs to a tenant and groups together entities in metal-stack.","category":"page"},{"location":"external/metalctl/docs/metalctl_tenant/#Options","page":"metalctl tenant","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_tenant/","page":"metalctl tenant","title":"metalctl tenant","text":" -h, --help help for tenant","category":"page"},{"location":"external/metalctl/docs/metalctl_tenant/#Options-inherited-from-parent-commands","page":"metalctl tenant","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_tenant/","page":"metalctl tenant","title":"metalctl tenant","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_tenant/#SEE-ALSO","page":"metalctl tenant","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_tenant/","page":"metalctl tenant","title":"metalctl tenant","text":"metalctl\t - a cli to manage entities in the metal-stack api\nmetalctl tenant apply\t - applies one or more tenants from a given file\nmetalctl tenant create\t - creates the tenant\nmetalctl tenant delete\t - deletes the tenant\nmetalctl tenant describe\t - describes the tenant\nmetalctl tenant edit\t - edit the tenant through an editor and update\nmetalctl tenant list\t - list all tenants\nmetalctl tenant update\t - updates the tenant","category":"page"},{"location":"external/metalctl/docs/metalctl_switch/#metalctl-switch","page":"metalctl switch","title":"metalctl switch","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_switch/","page":"metalctl switch","title":"metalctl switch","text":"manage switch entities","category":"page"},{"location":"external/metalctl/docs/metalctl_switch/#Synopsis","page":"metalctl switch","title":"Synopsis","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_switch/","page":"metalctl switch","title":"metalctl switch","text":"switch are the leaf switches in the data center that are controlled by metal-stack.","category":"page"},{"location":"external/metalctl/docs/metalctl_switch/#Options","page":"metalctl switch","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_switch/","page":"metalctl switch","title":"metalctl switch","text":" -h, --help help for switch","category":"page"},{"location":"external/metalctl/docs/metalctl_switch/#Options-inherited-from-parent-commands","page":"metalctl switch","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_switch/","page":"metalctl switch","title":"metalctl switch","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_switch/#SEE-ALSO","page":"metalctl switch","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_switch/","page":"metalctl switch","title":"metalctl switch","text":"metalctl\t - a cli to manage entities in the metal-stack api\nmetalctl switch connected-machines\t - shows switches with their connected machines\nmetalctl switch console\t - connect to the switch console\nmetalctl switch delete\t - deletes the switch\nmetalctl switch describe\t - describes the switch\nmetalctl switch detail\t - switch details\nmetalctl switch edit\t - edit the switch through an editor and update\nmetalctl switch list\t - list all switches\nmetalctl switch port\t - sets the given switch port state up or down\nmetalctl switch replace\t - put a leaf switch into replace mode in preparation for physical replacement. For a description of the steps involved see the long help.\nmetalctl switch ssh\t - connect to the switch via ssh\nmetalctl switch update\t - updates the switch","category":"page"},{"location":"external/metalctl/docs/metalctl_audit_describe/#metalctl-audit-describe","page":"metalctl audit describe","title":"metalctl audit describe","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_audit_describe/","page":"metalctl audit describe","title":"metalctl audit describe","text":"describes the audit trace","category":"page"},{"location":"external/metalctl/docs/metalctl_audit_describe/","page":"metalctl audit describe","title":"metalctl audit describe","text":"metalctl audit describe [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_audit_describe/#Options","page":"metalctl audit describe","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_audit_describe/","page":"metalctl audit describe","title":"metalctl audit describe","text":" -h, --help help for describe\n --phase string phase of the audit trace. One of [request, response, single, error, opened, closed] (default \"response\")\n --prettify-body attempts to interpret the body as json and prettifies it","category":"page"},{"location":"external/metalctl/docs/metalctl_audit_describe/#Options-inherited-from-parent-commands","page":"metalctl audit describe","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_audit_describe/","page":"metalctl audit describe","title":"metalctl audit describe","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_audit_describe/#SEE-ALSO","page":"metalctl audit describe","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_audit_describe/","page":"metalctl audit describe","title":"metalctl audit describe","text":"metalctl audit\t - manage audit trace entities","category":"page"},{"location":"external/metalctl/docs/metalctl_network_free/#metalctl-network-free","page":"metalctl network free","title":"metalctl network free","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_network_free/","page":"metalctl network free","title":"metalctl network free","text":"free a network","category":"page"},{"location":"external/metalctl/docs/metalctl_network_free/","page":"metalctl network free","title":"metalctl network free","text":"metalctl network free [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_network_free/#Options","page":"metalctl network free","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_network_free/","page":"metalctl network free","title":"metalctl network free","text":" -h, --help help for free","category":"page"},{"location":"external/metalctl/docs/metalctl_network_free/#Options-inherited-from-parent-commands","page":"metalctl network free","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_network_free/","page":"metalctl network free","title":"metalctl network free","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_network_free/#SEE-ALSO","page":"metalctl network free","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_network_free/","page":"metalctl network free","title":"metalctl network free","text":"metalctl network\t - manage network entities","category":"page"},{"location":"external/metalctl/docs/metalctl_size_imageconstraint_describe/#metalctl-size-imageconstraint-describe","page":"metalctl size imageconstraint describe","title":"metalctl size imageconstraint describe","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_imageconstraint_describe/","page":"metalctl size imageconstraint describe","title":"metalctl size imageconstraint describe","text":"describes the imageconstraint","category":"page"},{"location":"external/metalctl/docs/metalctl_size_imageconstraint_describe/","page":"metalctl size imageconstraint describe","title":"metalctl size imageconstraint describe","text":"metalctl size imageconstraint describe [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_size_imageconstraint_describe/#Options","page":"metalctl size imageconstraint describe","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_imageconstraint_describe/","page":"metalctl size imageconstraint describe","title":"metalctl size imageconstraint describe","text":" -h, --help help for describe","category":"page"},{"location":"external/metalctl/docs/metalctl_size_imageconstraint_describe/#Options-inherited-from-parent-commands","page":"metalctl size imageconstraint describe","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_imageconstraint_describe/","page":"metalctl size imageconstraint describe","title":"metalctl size imageconstraint describe","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_size_imageconstraint_describe/#SEE-ALSO","page":"metalctl size imageconstraint describe","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_imageconstraint_describe/","page":"metalctl size imageconstraint describe","title":"metalctl size imageconstraint describe","text":"metalctl size imageconstraint\t - manage imageconstraint entities","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_consolepassword/#metalctl-machine-consolepassword","page":"metalctl machine consolepassword","title":"metalctl machine consolepassword","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_consolepassword/","page":"metalctl machine consolepassword","title":"metalctl machine consolepassword","text":"fetch the consolepassword for a machine","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_consolepassword/","page":"metalctl machine consolepassword","title":"metalctl machine consolepassword","text":"metalctl machine consolepassword [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_consolepassword/#Options","page":"metalctl machine consolepassword","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_consolepassword/","page":"metalctl machine consolepassword","title":"metalctl machine consolepassword","text":" -h, --help help for consolepassword\n --reason string a short description why access to the consolepassword is required","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_consolepassword/#Options-inherited-from-parent-commands","page":"metalctl machine consolepassword","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_consolepassword/","page":"metalctl machine consolepassword","title":"metalctl machine consolepassword","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_consolepassword/#SEE-ALSO","page":"metalctl machine consolepassword","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_consolepassword/","page":"metalctl machine consolepassword","title":"metalctl machine consolepassword","text":"metalctl machine\t - manage machine entities","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_power_bios/#metalctl-machine-power-bios","page":"metalctl machine power bios","title":"metalctl machine power bios","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_power_bios/","page":"metalctl machine power bios","title":"metalctl machine power bios","text":"boot a machine into BIOS","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_power_bios/#Synopsis","page":"metalctl machine power bios","title":"Synopsis","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_power_bios/","page":"metalctl machine power bios","title":"metalctl machine power bios","text":"the machine will boot into bios. (machine does not reboot automatically)","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_power_bios/","page":"metalctl machine power bios","title":"metalctl machine power bios","text":"metalctl machine power bios [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_power_bios/#Options","page":"metalctl machine power bios","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_power_bios/","page":"metalctl machine power bios","title":"metalctl machine power bios","text":" -h, --help help for bios","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_power_bios/#Options-inherited-from-parent-commands","page":"metalctl machine power bios","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_power_bios/","page":"metalctl machine power bios","title":"metalctl machine power bios","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_power_bios/#SEE-ALSO","page":"metalctl machine power bios","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_power_bios/","page":"metalctl machine power bios","title":"metalctl machine power bios","text":"metalctl machine power\t - manage machine power","category":"page"},{"location":"installation/updates/#Releases-and-Updates","page":"Releases and Updates","title":"Releases and Updates","text":"","category":"section"},{"location":"installation/updates/","page":"Releases and Updates","title":"Releases and Updates","text":"using Docs\n\nversion = releaseVersion()\n\nt = raw\"\"\"\nYour are currently reading the documentation for the metal-stack `%s` release.\n\"\"\"\n\nmarkdownTemplate(t, version)","category":"page"},{"location":"installation/updates/","page":"Releases and Updates","title":"Releases and Updates","text":"Releases and integration tests are published through our release repository. You can also find the release notes for this metal-stack version in there. The release notes contain information about new features, upgrade paths and bug fixes.","category":"page"},{"location":"installation/updates/","page":"Releases and Updates","title":"Releases and Updates","text":"If you want, you can sign up at our Slack channel where we are announcing every new release. Often, we provide additional information for metal-stack administrators and adopters at this place, too.","category":"page"},{"location":"installation/updates/#Update-Policy","page":"Releases and Updates","title":"Update Policy","text":"","category":"section"},{"location":"installation/updates/","page":"Releases and Updates","title":"Releases and Updates","text":"For new features and breaking changes we create a new minor release of metal-stack. For every minor release we present excerpts of the changes in a corresponding blog article published on metal-stack.io. It is not necessary to cycle through the patch releases if you depend on the pure metal-stack components.","category":"page"},{"location":"installation/updates/","page":"Releases and Updates","title":"Releases and Updates","text":"In case you depend on the Gardener integration though, especially when using metal-stack roles for deploying Gardener, it may be necessary to cycle through the patch release versions of our metal-stack releases. We regularly increment our Gardener dependency version by version which is the recommended way to update Gardener.","category":"page"},{"location":"installation/updates/","page":"Releases and Updates","title":"Releases and Updates","text":"warning: Warning\nIf you use the Gardener integration of metal-stack do not skip patch releases.","category":"page"},{"location":"external/metalctl/docs/metalctl_vpn_key/#metalctl-vpn-key","page":"metalctl vpn key","title":"metalctl vpn key","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_vpn_key/","page":"metalctl vpn key","title":"metalctl vpn key","text":"create an auth key","category":"page"},{"location":"external/metalctl/docs/metalctl_vpn_key/#Synopsis","page":"metalctl vpn key","title":"Synopsis","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_vpn_key/","page":"metalctl vpn key","title":"metalctl vpn key","text":"create an auth key to connect to VPN","category":"page"},{"location":"external/metalctl/docs/metalctl_vpn_key/","page":"metalctl vpn key","title":"metalctl vpn key","text":"metalctl vpn key [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_vpn_key/#Examples","page":"metalctl vpn key","title":"Examples","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_vpn_key/","page":"metalctl vpn key","title":"metalctl vpn key","text":"auth key for tailscale can be created by this command:\nmetalctl vpn key \\\n\t-- project cluster01\n","category":"page"},{"location":"external/metalctl/docs/metalctl_vpn_key/#Options","page":"metalctl vpn key","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_vpn_key/","page":"metalctl vpn key","title":"metalctl vpn key","text":" --ephemeral create an ephemeral key (default true)\n -h, --help help for key\n --project string project ID for which auth key should be created","category":"page"},{"location":"external/metalctl/docs/metalctl_vpn_key/#Options-inherited-from-parent-commands","page":"metalctl vpn key","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_vpn_key/","page":"metalctl vpn key","title":"metalctl vpn key","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_vpn_key/#SEE-ALSO","page":"metalctl vpn key","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_vpn_key/","page":"metalctl vpn key","title":"metalctl vpn key","text":"metalctl vpn\t - access VPN","category":"page"},{"location":"external/metalctl/docs/metalctl_network_ip_edit/#metalctl-network-ip-edit","page":"metalctl network ip edit","title":"metalctl network ip edit","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_network_ip_edit/","page":"metalctl network ip edit","title":"metalctl network ip edit","text":"edit the ip through an editor and update","category":"page"},{"location":"external/metalctl/docs/metalctl_network_ip_edit/","page":"metalctl network ip edit","title":"metalctl network ip edit","text":"metalctl network ip edit [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_network_ip_edit/#Options","page":"metalctl network ip edit","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_network_ip_edit/","page":"metalctl network ip edit","title":"metalctl network ip edit","text":" -h, --help help for edit","category":"page"},{"location":"external/metalctl/docs/metalctl_network_ip_edit/#Options-inherited-from-parent-commands","page":"metalctl network ip edit","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_network_ip_edit/","page":"metalctl network ip edit","title":"metalctl network ip edit","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_network_ip_edit/#SEE-ALSO","page":"metalctl network ip edit","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_network_ip_edit/","page":"metalctl network ip edit","title":"metalctl network ip edit","text":"metalctl network ip\t - manage ip entities","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_identify_on/#metalctl-machine-identify-on","page":"metalctl machine identify on","title":"metalctl machine identify on","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_identify_on/","page":"metalctl machine identify on","title":"metalctl machine identify on","text":"power on the machine chassis identify LED","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_identify_on/#Synopsis","page":"metalctl machine identify on","title":"Synopsis","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_identify_on/","page":"metalctl machine identify on","title":"metalctl machine identify on","text":"set the machine chassis identify LED to on state","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_identify_on/","page":"metalctl machine identify on","title":"metalctl machine identify on","text":"metalctl machine identify on [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_identify_on/#Options","page":"metalctl machine identify on","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_identify_on/","page":"metalctl machine identify on","title":"metalctl machine identify on","text":" -d, --description string description of the reason for chassis identify LED turn-on.\n -h, --help help for on","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_identify_on/#Options-inherited-from-parent-commands","page":"metalctl machine identify on","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_identify_on/","page":"metalctl machine identify on","title":"metalctl machine identify on","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_identify_on/#SEE-ALSO","page":"metalctl machine identify on","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_identify_on/","page":"metalctl machine identify on","title":"metalctl machine identify on","text":"metalctl machine identify\t - manage machine chassis identify LED power","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_update/#metalctl-machine-update","page":"metalctl machine update","title":"metalctl machine update","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_update/","page":"metalctl machine update","title":"metalctl machine update","text":"updates the machine","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_update/","page":"metalctl machine update","title":"metalctl machine update","text":"metalctl machine update [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_update/#Options","page":"metalctl machine update","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_update/","page":"metalctl machine update","title":"metalctl machine update","text":" --add-tags strings tags to be added to the machine [optional]\n --bulk-output when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.\n --description string the description of the machine [optional]\n -f, --file string filename of the create or update request in yaml format, or - for stdin.\n \n Example:\n $ metalctl machine describe machine-1 -o yaml > machine.yaml\n $ vi machine.yaml\n $ # either via stdin\n $ cat machine.yaml | metalctl machine update -f -\n $ # or via file\n $ metalctl machine update -f machine.yaml\n \n the file can also contain multiple documents and perform a bulk operation.\n \t\n -h, --help help for update\n --remove-tags strings tags to be removed from the machine [optional]\n --skip-security-prompts skips security prompt for bulk operations\n --timestamps when used with --file (bulk operation): prints timestamps in-between the operations","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_update/#Options-inherited-from-parent-commands","page":"metalctl machine update","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_update/","page":"metalctl machine update","title":"metalctl machine update","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_update/#SEE-ALSO","page":"metalctl machine update","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_update/","page":"metalctl machine update","title":"metalctl machine update","text":"metalctl machine\t - manage machine entities","category":"page"},{"location":"external/metalctl/docs/metalctl_tenant_describe/#metalctl-tenant-describe","page":"metalctl tenant describe","title":"metalctl tenant describe","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_tenant_describe/","page":"metalctl tenant describe","title":"metalctl tenant describe","text":"describes the tenant","category":"page"},{"location":"external/metalctl/docs/metalctl_tenant_describe/","page":"metalctl tenant describe","title":"metalctl tenant describe","text":"metalctl tenant describe [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_tenant_describe/#Options","page":"metalctl tenant describe","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_tenant_describe/","page":"metalctl tenant describe","title":"metalctl tenant describe","text":" -h, --help help for describe","category":"page"},{"location":"external/metalctl/docs/metalctl_tenant_describe/#Options-inherited-from-parent-commands","page":"metalctl tenant describe","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_tenant_describe/","page":"metalctl tenant describe","title":"metalctl tenant describe","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_tenant_describe/#SEE-ALSO","page":"metalctl tenant describe","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_tenant_describe/","page":"metalctl tenant describe","title":"metalctl tenant describe","text":"metalctl tenant\t - manage tenant entities","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_issues/#metalctl-machine-issues","page":"metalctl machine issues","title":"metalctl machine issues","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_issues/","page":"metalctl machine issues","title":"metalctl machine issues","text":"display machines which are in a potential bad state","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_issues/#Synopsis","page":"metalctl machine issues","title":"Synopsis","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_issues/","page":"metalctl machine issues","title":"metalctl machine issues","text":"display machines which are in a potential bad state","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_issues/","page":"metalctl machine issues","title":"metalctl machine issues","text":"Meaning of the emojis:","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_issues/","page":"metalctl machine issues","title":"metalctl machine issues","text":"🚧 Machine is reserved. Reserved machines are not considered for random allocation until the reservation flag is removed. 🔒 Machine is locked. Locked machines can not be deleted until the lock is removed. 💀 Machine is dead. The metal-api does not receive any events from this machine. ❗ Machine has a last event error. The machine has recently encountered an error during the provisioning lifecycle. ❓ Machine is in unknown condition. The metal-api does not receive phoned home events anymore or has never booted successfully. ⭕ Machine is in a provisioning crash loop. Flag can be reset through an API-triggered reboot or when the machine reaches the phoned home state. 🚑 Machine reclaim has failed. The machine was deleted but it is not going back into the available machine pool. 🛡 Machine is connected to our VPN, ssh access only possible via this VPN.","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_issues/","page":"metalctl machine issues","title":"metalctl machine issues","text":"metalctl machine issues [] [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_issues/#Options","page":"metalctl machine issues","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_issues/","page":"metalctl machine issues","title":"metalctl machine issues","text":" --bmc-address string bmc ipmi address (needs to include port) to filter [optional]\n --bmc-mac string bmc mac address to filter [optional]\n --board-part-number string fru board part number to filter [optional]\n -h, --help help for issues\n --hostname string allocation hostname to filter [optional]\n --id string ID to filter [optional]\n --image string allocation image to filter [optional]\n --last-event-error-threshold duration the duration up to how long in the past a machine last event error will be counted as an issue [optional]\n --mac string mac to filter [optional]\n --manufacturer string fru manufacturer to filter [optional]\n --name string allocation name to filter [optional]\n --network-destination-prefixes string network destination prefixes to filter [optional]\n --network-ids string network ids to filter [optional]\n --network-ips string network ips to filter [optional]\n --omit strings issue types to omit [optional]\n --only strings issue types to include [optional]\n --partition string partition to filter [optional]\n --product-part-number string fru product part number to filter [optional]\n --product-serial string fru product serial to filter [optional]\n --project string allocation project to filter [optional]\n --rack string rack to filter [optional]\n --role string allocation role to filter [optional]\n --severity string issue severity to include [optional]\n --size string size to filter [optional]\n --sort-by strings sort by (comma separated) column(s), sort direction can be changed by appending :asc or :desc behind the column identifier. possible values: age|bios|bmc|event|id|liveliness|partition|project|rack|size|when\n --state string state to filter [optional]\n --tags strings tags to filter, use it like: --tags \"tag1,tag2\" or --tags \"tag3\".","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_issues/#Options-inherited-from-parent-commands","page":"metalctl machine issues","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_issues/","page":"metalctl machine issues","title":"metalctl machine issues","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_issues/#SEE-ALSO","page":"metalctl machine issues","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_issues/","page":"metalctl machine issues","title":"metalctl machine issues","text":"metalctl machine\t - manage machine entities\nmetalctl machine issues list\t - list all machine issues that the metal-api can evaluate","category":"page"},{"location":"external/metalctl/docs/metalctl_switch_port/#metalctl-switch-port","page":"metalctl switch port","title":"metalctl switch port","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_switch_port/","page":"metalctl switch port","title":"metalctl switch port","text":"sets the given switch port state up or down","category":"page"},{"location":"external/metalctl/docs/metalctl_switch_port/#Options","page":"metalctl switch port","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_switch_port/","page":"metalctl switch port","title":"metalctl switch port","text":" -h, --help help for port\n --port string the port to be changed.","category":"page"},{"location":"external/metalctl/docs/metalctl_switch_port/#Options-inherited-from-parent-commands","page":"metalctl switch port","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_switch_port/","page":"metalctl switch port","title":"metalctl switch port","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_switch_port/#SEE-ALSO","page":"metalctl switch port","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_switch_port/","page":"metalctl switch port","title":"metalctl switch port","text":"metalctl switch\t - manage switch entities\nmetalctl switch port describe\t - gets the given switch port state\nmetalctl switch port down\t - sets the given switch port state down\nmetalctl switch port up\t - sets the given switch port state up","category":"page"},{"location":"external/metalctl/docs/metalctl_switch_port_describe/#metalctl-switch-port-describe","page":"metalctl switch port describe","title":"metalctl switch port describe","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_switch_port_describe/","page":"metalctl switch port describe","title":"metalctl switch port describe","text":"gets the given switch port state","category":"page"},{"location":"external/metalctl/docs/metalctl_switch_port_describe/#Synopsis","page":"metalctl switch port describe","title":"Synopsis","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_switch_port_describe/","page":"metalctl switch port describe","title":"metalctl switch port describe","text":"shows the current actual and desired state of the port of the given switch.","category":"page"},{"location":"external/metalctl/docs/metalctl_switch_port_describe/","page":"metalctl switch port describe","title":"metalctl switch port describe","text":"metalctl switch port describe [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_switch_port_describe/#Options","page":"metalctl switch port describe","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_switch_port_describe/","page":"metalctl switch port describe","title":"metalctl switch port describe","text":" -h, --help help for describe","category":"page"},{"location":"external/metalctl/docs/metalctl_switch_port_describe/#Options-inherited-from-parent-commands","page":"metalctl switch port describe","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_switch_port_describe/","page":"metalctl switch port describe","title":"metalctl switch port describe","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --port string the port to be changed.\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_switch_port_describe/#SEE-ALSO","page":"metalctl switch port describe","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_switch_port_describe/","page":"metalctl switch port describe","title":"metalctl switch port describe","text":"metalctl switch port\t - sets the given switch port state up or down","category":"page"},{"location":"external/metalctl/docs/metalctl_tenant_update/#metalctl-tenant-update","page":"metalctl tenant update","title":"metalctl tenant update","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_tenant_update/","page":"metalctl tenant update","title":"metalctl tenant update","text":"updates the tenant","category":"page"},{"location":"external/metalctl/docs/metalctl_tenant_update/","page":"metalctl tenant update","title":"metalctl tenant update","text":"metalctl tenant update [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_tenant_update/#Options","page":"metalctl tenant update","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_tenant_update/","page":"metalctl tenant update","title":"metalctl tenant update","text":" --bulk-output when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.\n -f, --file string filename of the create or update request in yaml format, or - for stdin.\n \n Example:\n $ metalctl tenant describe tenant-1 -o yaml > tenant.yaml\n $ vi tenant.yaml\n $ # either via stdin\n $ cat tenant.yaml | metalctl tenant update -f -\n $ # or via file\n $ metalctl tenant update -f tenant.yaml\n \n the file can also contain multiple documents and perform a bulk operation.\n \t\n -h, --help help for update\n --skip-security-prompts skips security prompt for bulk operations\n --timestamps when used with --file (bulk operation): prints timestamps in-between the operations","category":"page"},{"location":"external/metalctl/docs/metalctl_tenant_update/#Options-inherited-from-parent-commands","page":"metalctl tenant update","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_tenant_update/","page":"metalctl tenant update","title":"metalctl tenant update","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_tenant_update/#SEE-ALSO","page":"metalctl tenant update","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_tenant_update/","page":"metalctl tenant update","title":"metalctl tenant update","text":"metalctl tenant\t - manage tenant entities","category":"page"},{"location":"external/csi-driver-lvm/CONTRIBUTING/#Contributing","page":"Contributing","title":"Contributing","text":"","category":"section"},{"location":"external/csi-driver-lvm/CONTRIBUTING/","page":"Contributing","title":"Contributing","text":"Please check out the contributing section in our docs.","category":"page"},{"location":"external/metalctl/docs/metalctl_logout/#metalctl-logout","page":"metalctl logout","title":"metalctl logout","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_logout/","page":"metalctl logout","title":"metalctl logout","text":"logout user from OIDC SSO session","category":"page"},{"location":"external/metalctl/docs/metalctl_logout/","page":"metalctl logout","title":"metalctl logout","text":"metalctl logout [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_logout/#Options","page":"metalctl logout","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_logout/","page":"metalctl logout","title":"metalctl logout","text":" -h, --help help for logout","category":"page"},{"location":"external/metalctl/docs/metalctl_logout/#Options-inherited-from-parent-commands","page":"metalctl logout","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_logout/","page":"metalctl logout","title":"metalctl logout","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_logout/#SEE-ALSO","page":"metalctl logout","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_logout/","page":"metalctl logout","title":"metalctl logout","text":"metalctl\t - a cli to manage entities in the metal-stack api","category":"page"},{"location":"external/metalctl/docs/metalctl_partition_delete/#metalctl-partition-delete","page":"metalctl partition delete","title":"metalctl partition delete","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_partition_delete/","page":"metalctl partition delete","title":"metalctl partition delete","text":"deletes the partition","category":"page"},{"location":"external/metalctl/docs/metalctl_partition_delete/","page":"metalctl partition delete","title":"metalctl partition delete","text":"metalctl partition delete [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_partition_delete/#Options","page":"metalctl partition delete","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_partition_delete/","page":"metalctl partition delete","title":"metalctl partition delete","text":" --bulk-output when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.\n -f, --file string filename of the create or update request in yaml format, or - for stdin.\n \n Example:\n $ metalctl partition describe partition-1 -o yaml > partition.yaml\n $ vi partition.yaml\n $ # either via stdin\n $ cat partition.yaml | metalctl partition delete -f -\n $ # or via file\n $ metalctl partition delete -f partition.yaml\n \n the file can also contain multiple documents and perform a bulk operation.\n \t\n -h, --help help for delete\n --skip-security-prompts skips security prompt for bulk operations\n --timestamps when used with --file (bulk operation): prints timestamps in-between the operations","category":"page"},{"location":"external/metalctl/docs/metalctl_partition_delete/#Options-inherited-from-parent-commands","page":"metalctl partition delete","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_partition_delete/","page":"metalctl partition delete","title":"metalctl partition delete","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_partition_delete/#SEE-ALSO","page":"metalctl partition delete","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_partition_delete/","page":"metalctl partition delete","title":"metalctl partition delete","text":"metalctl partition\t - manage partition entities","category":"page"},{"location":"external/metalctl/docs/metalctl_project_create/#metalctl-project-create","page":"metalctl project create","title":"metalctl project create","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_project_create/","page":"metalctl project create","title":"metalctl project create","text":"creates the project","category":"page"},{"location":"external/metalctl/docs/metalctl_project_create/","page":"metalctl project create","title":"metalctl project create","text":"metalctl project create [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_project_create/#Options","page":"metalctl project create","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_project_create/","page":"metalctl project create","title":"metalctl project create","text":" --annotation strings add initial annotation, must be in the form of key=value, can be given multiple times to add multiple annotations, e.g. --annotation key=value --annotation foo=bar\n --bulk-output when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.\n --cluster-quota int32 cluster quota\n --description string description of the project.\n -f, --file string filename of the create or update request in yaml format, or - for stdin.\n \n Example:\n $ metalctl project describe project-1 -o yaml > project.yaml\n $ vi project.yaml\n $ # either via stdin\n $ cat project.yaml | metalctl project create -f -\n $ # or via file\n $ metalctl project create -f project.yaml\n \n the file can also contain multiple documents and perform a bulk operation.\n \t\n -h, --help help for create\n --ip-quota int32 ip quota\n --label strings add initial label, can be given multiple times to add multiple labels, e.g. --label=foo --label=bar\n --machine-quota int32 machine quota\n --name string name of the project, max 10 characters.\n --skip-security-prompts skips security prompt for bulk operations\n --tenant string create project for given tenant\n --timestamps when used with --file (bulk operation): prints timestamps in-between the operations","category":"page"},{"location":"external/metalctl/docs/metalctl_project_create/#Options-inherited-from-parent-commands","page":"metalctl project create","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_project_create/","page":"metalctl project create","title":"metalctl project create","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_project_create/#SEE-ALSO","page":"metalctl project create","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_project_create/","page":"metalctl project create","title":"metalctl project create","text":"metalctl project\t - manage project entities","category":"page"},{"location":"overview/isolated-kubernetes/#Isolated-Kubernetes-Clusters","page":"Isolated Kubernetes","title":"Isolated Kubernetes Clusters","text":"","category":"section"},{"location":"overview/isolated-kubernetes/","page":"Isolated Kubernetes","title":"Isolated Kubernetes","text":"Pages = [\"isolated-kubernetes.md\"]\nDepth = 5","category":"page"},{"location":"overview/isolated-kubernetes/","page":"Isolated Kubernetes","title":"Isolated Kubernetes","text":"Some customers have the need to run their workloads in a very restricted environment. These restrictions are driven by regulatory requirements in some industries such as finance, healthcare, energy and more. Regulatory requirements often mandate that the workload must not be exposed to the public internet, nor is capable to reach the public internet in any case.","category":"page"},{"location":"overview/isolated-kubernetes/","page":"Isolated Kubernetes","title":"Isolated Kubernetes","text":"For this purpose we implemented a possibility to start Kubernetes clusters in such a manner. This is referred to as cluster isolation.","category":"page"},{"location":"overview/isolated-kubernetes/#Design-Choices","page":"Isolated Kubernetes","title":"Design Choices","text":"","category":"section"},{"location":"overview/isolated-kubernetes/","page":"Isolated Kubernetes","title":"Isolated Kubernetes","text":"When talking about highly secure Kubernetes environments people often raise the term \"Air Gapped Cluster\". This would mean that no physical connection exists between the Kubernetes control plane and the Kubernetes worker nodes with the outside world. This requirement exists in extreme environments such as ships, moon bases or nuclear plants. The effort to produce this in a completely automated manner is extremely challenging.","category":"page"},{"location":"overview/isolated-kubernetes/","page":"Isolated Kubernetes","title":"Isolated Kubernetes","text":"We decided to follow a different approach which is more practical, still very secure but much simpler to implement and operate. The solution we created is called \"Isolated Cluster\" which means that there are still physical connections between the Kubernetes cluster, but guarded to prohibit malicious traffic. It is also not possible to enable malicious traffic by accident, e.g. if a cluster user configures network policies or load balancers to untrusted environments.","category":"page"},{"location":"overview/isolated-kubernetes/#Network-Design","page":"Isolated Kubernetes","title":"Network Design","text":"","category":"section"},{"location":"overview/isolated-kubernetes/","page":"Isolated Kubernetes","title":"Isolated Kubernetes","text":"In order to be able to restrict ingress and egress internet traffic, but still make it possible to create a working Kubernetes cluster we implemented the following network design.","category":"page"},{"location":"overview/isolated-kubernetes/","page":"Isolated Kubernetes","title":"Isolated Kubernetes","text":"All strictly required container images are mirrored to a registry which is only accessible from the Kubernetes clusters.\nDNS and NTP servers are produced alongside the registry.\nThe containerd configuration on every worker node is configured to pull all of the strictly required container images from this private registry mirror.\nDNS and NTP configuration is also adopted to use the DNS and NTP servers on this private environment.\nA list of networks which are allowed to reach is managed, this list reflects the networks of the cloud provider and is not modifiable by the cluster user. This list usually contains the internet prefixes of the provider and one or more RFC address ranges.","category":"page"},{"location":"overview/isolated-kubernetes/","page":"Isolated Kubernetes","title":"Isolated Kubernetes","text":"(Image: Network Design)","category":"page"},{"location":"overview/isolated-kubernetes/","page":"Isolated Kubernetes","title":"Isolated Kubernetes","text":"Users are advised to attach an additional network to the Kubernetes cluster in order to be able to pull container images for the application workloads from private registries.","category":"page"},{"location":"overview/isolated-kubernetes/#Strictly-Required-Container-Images","page":"Isolated Kubernetes","title":"Strictly Required Container Images","text":"","category":"section"},{"location":"overview/isolated-kubernetes/","page":"Isolated Kubernetes","title":"Isolated Kubernetes","text":"In general the creation of a Kubernetes cluster requires the ability to pull container images for several applications which are necessary to make a machine a Kubernetes worker node. To mention the most important:","category":"page"},{"location":"overview/isolated-kubernetes/","page":"Isolated Kubernetes","title":"Isolated Kubernetes","text":"Kubelet: the main controller on each worker node to manage the workload\nCNI (Container Network Interface): controller and daemon set to setup and run the container networking\nCSI (Container Storage Interface): controller and daemon set to setup and run the container storage\nCoreDNS: DNS for containers\nMetalLB: Service Type LoadBalancer Implementation\nnode-exporter and metrics-server: Monitoring for the worker node\nMetal-Stack Addons: for firewall and auditing events","category":"page"},{"location":"overview/isolated-kubernetes/#Flavors","page":"Isolated Kubernetes","title":"Flavors","text":"","category":"section"},{"location":"overview/isolated-kubernetes/","page":"Isolated Kubernetes","title":"Isolated Kubernetes","text":"With the introduction of Isolated Kubernetes Clusters, cluster users must decide upon cluster creation which type of isolation he needs for his workload. There are three different flavours available:","category":"page"},{"location":"overview/isolated-kubernetes/","page":"Isolated Kubernetes","title":"Isolated Kubernetes","text":"Internet access baseline: This is the default cluster creation mode, which does not change any aspects of network and registry access.\nInternet access forbidden: No internet access is possible, neither ingress nor egress.\nInternet access restricted: No internet access is possible, neither ingress nor egress, but can be enabled by the cluster user.","category":"page"},{"location":"overview/isolated-kubernetes/","page":"Isolated Kubernetes","title":"Isolated Kubernetes","text":"Please see the detailed description of these flavors below.","category":"page"},{"location":"overview/isolated-kubernetes/#Cluster-Wide-Network-Policies-CWNP","page":"Isolated Kubernetes","title":"Cluster Wide Network Policies CWNP","text":"","category":"section"},{"location":"overview/isolated-kubernetes/","page":"Isolated Kubernetes","title":"Isolated Kubernetes","text":"To restrict which egress traffic is allowed, Custom Resources ClusterWideNetworkPolicy are deployed and can be deployed by the cluster user. The set of deployed CWNPs differs between baseline and forbidden/restricted.","category":"page"},{"location":"overview/isolated-kubernetes/","page":"Isolated Kubernetes","title":"Isolated Kubernetes","text":"baseline CWNPs:","category":"page"},{"location":"overview/isolated-kubernetes/","page":"Isolated Kubernetes","title":"Isolated Kubernetes","text":"Rule Name Destination Purpose\nallow-to-http 0.0.0.0/0 egress via http\nallow-to-https 0.0.0.0/0 egress via https\nallow-to-apiserver IP of the Kubernetes API Server on the control plane API Server communication of kubelet and other controllers\nallow-to-dns IP of the Google DNS Servers DNS resolution from the Kubernetes worker nodes and containers\nallow-to-ntp IP of the Cloudflare NTP Servers Time synchronization\nallow-to-storage network of the container storage persistent volumes with the cni driver\nallow-to-vpn IP of the vpn endpoint on the control plane allow communication from the api server to the kubelet for container logs and container exec","category":"page"},{"location":"overview/isolated-kubernetes/","page":"Isolated Kubernetes","title":"Isolated Kubernetes","text":"forbidden and restricted CWNPs:","category":"page"},{"location":"overview/isolated-kubernetes/","page":"Isolated Kubernetes","title":"Isolated Kubernetes","text":"Rule Name Destination Purpose\nallow-to-apiserver IP of the Kubernetes API Server on the control plane API Server communication of kubelet and other controllers\nallow-to-dns IP of the private DNS Server DNS resolution from the Kubernetes worker nodes and containers\nallow-to-ntp IP of the private NTP Server Time synchronization\nallow-to-registry IP of the private Registry Mirror Pulling strictly required container images\nallow-to-storage network of the container storage persistent volumes with the cni driver\nallow-to-vpn IP of the vpn endpoint on the control plane allow communication from the api server to the kubelet for container logs and container exec","category":"page"},{"location":"overview/isolated-kubernetes/","page":"Isolated Kubernetes","title":"Isolated Kubernetes","text":"All of these CWNPs are managed by the gardener-extension-provider-metal, every manual modification will be reverted immediately.","category":"page"},{"location":"overview/isolated-kubernetes/#Internet-Access-Baseline","page":"Isolated Kubernetes","title":"Internet Access Baseline","text":"","category":"section"},{"location":"overview/isolated-kubernetes/","page":"Isolated Kubernetes","title":"Isolated Kubernetes","text":"This is the default configuration of a Kubernetes cluster, egress traffic is controlled by multiple CWNPs (ClusterWideNetworkPolicy), ingress traffic is possible by deploying a Service Type LoadBalancer. The cluster user can add additional CWNPs without any restrictions and is responsible for them.","category":"page"},{"location":"overview/isolated-kubernetes/","page":"Isolated Kubernetes","title":"Isolated Kubernetes","text":"Container images can be pulled from any reachable container registry. The containerd is not reconfigured to point to our private registry mirror.","category":"page"},{"location":"overview/isolated-kubernetes/","page":"Isolated Kubernetes","title":"Isolated Kubernetes","text":"DNS and NTP are configured to internet DNS resolvers and NTP servers.","category":"page"},{"location":"overview/isolated-kubernetes/#Internet-Access-Forbidden","page":"Isolated Kubernetes","title":"Internet Access Forbidden","text":"","category":"section"},{"location":"overview/isolated-kubernetes/","page":"Isolated Kubernetes","title":"Isolated Kubernetes","text":"This configuration can only be achieved by creating a new Kubernetes cluster, it is not possible to modify a existing cluster (with internet access baseline or restricted) to this configuration. It is also required to specify the most recent version of Kubernetes, older versions of Kubernetes are not supported.","category":"page"},{"location":"overview/isolated-kubernetes/","page":"Isolated Kubernetes","title":"Isolated Kubernetes","text":"Every network access modification triggered by a cluster user, either by adding or modifying CWNPs or adding a Service Type LoadBalancer, is validated against the list of allowed networks.","category":"page"},{"location":"overview/isolated-kubernetes/","page":"Isolated Kubernetes","title":"Isolated Kubernetes","text":"containerd is configured so that all required images are pulled from the private registry mirror. This registry contains only the strictly required images, therefore no additional (workload) images can be pulled from public registries.","category":"page"},{"location":"overview/isolated-kubernetes/#Egress-traffic","page":"Isolated Kubernetes","title":"Egress traffic","text":"","category":"section"},{"location":"overview/isolated-kubernetes/","page":"Isolated Kubernetes","title":"Isolated Kubernetes","text":"Egress traffic is only allowed to the private registry mirror and the DNS and NTP servers. Additional CWNPs can be added to reach destinations in the internal networks if specified. If a CWNP was created which points to a destination outside of the allowed networks, the CWNP will still be present but stays in the status ignored.","category":"page"},{"location":"overview/isolated-kubernetes/","page":"Isolated Kubernetes","title":"Isolated Kubernetes","text":"> kubectl get clusterwidenetworkpolicies.metal-stack.io\nNAME STATUS MESSAGE\nallow-to-apiserver deployed\nallow-to-dns deployed\nallow-to-ntp deployed\nallow-to-registry deployed\nallow-to-storage deployed\nallow-to-vpn deployed\nallow-to-google ignored ingress/egress does not match allowed networks","category":"page"},{"location":"overview/isolated-kubernetes/","page":"Isolated Kubernetes","title":"Isolated Kubernetes","text":"Also an event is created which describes why the CWNP was ignored:","category":"page"},{"location":"overview/isolated-kubernetes/","page":"Isolated Kubernetes","title":"Isolated Kubernetes","text":"> kubectl get events\n5s Warning ForbiddenCIDR clusterwidenetworkpolicy/allow-to-google address:\"8.8.8.8/32\" is outside of the allowed network range:\"10.0.0.0/8,100.64.0.0/10,212.34.83.0/27\", ignoring","category":"page"},{"location":"overview/isolated-kubernetes/#Ingress-traffic","page":"Isolated Kubernetes","title":"Ingress traffic","text":"","category":"section"},{"location":"overview/isolated-kubernetes/","page":"Isolated Kubernetes","title":"Isolated Kubernetes","text":"Ingress traffic is only allowed from the internal networks if specified. To specify the address where the Service Type LoadBalancer is listening to, the cluster user must use one of his statically acquired ip addresses. Of course, this ip address is only considered if it is contained in the list of allowed networks. Then this ip address must be configured in the service:","category":"page"},{"location":"overview/isolated-kubernetes/","page":"Isolated Kubernetes","title":"Isolated Kubernetes","text":"apiVersion: v1\nkind: Service\nspec:\n type: LoadBalancer\n loadBalancerIP: 10.1.1.1 # ip from the internal network","category":"page"},{"location":"overview/isolated-kubernetes/","page":"Isolated Kubernetes","title":"Isolated Kubernetes","text":"By default, no ip address will be automatically selected for such clusters and the ip of the service will stay in pending mode until the ip was specified as shown above.","category":"page"},{"location":"overview/isolated-kubernetes/","page":"Isolated Kubernetes","title":"Isolated Kubernetes","text":"> kubectl get svc\nNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE\nexample-service LoadBalancer 10.244.75.171 443:32179/TCP 4s\n\n> kubectl get events\n8s Warning AllocationFailed service/example-service Failed to allocate IP for \"default/example-service\": no available IPs\n3s Warning SyncLoadBalancerFailed service/example-service Error syncing load balancer: failed to ensure load balancer: no default network for ip acquisition specified, acquire an ip for your cluster's project and specify it directly in \"spec.loadBalancerIP\"","category":"page"},{"location":"overview/isolated-kubernetes/#Internet-Access-Restricted","page":"Isolated Kubernetes","title":"Internet Access Restricted","text":"","category":"section"},{"location":"overview/isolated-kubernetes/","page":"Isolated Kubernetes","title":"Isolated Kubernetes","text":"This configuration can only be achieved by creating a new Kubernetes cluster, it is not possible to modify a existing cluster (with internet access baseline or forbidden) to this configuration. It is also required to specify the most recent version of Kubernetes, older versions of Kubernetes are not supported.","category":"page"},{"location":"overview/isolated-kubernetes/","page":"Isolated Kubernetes","title":"Isolated Kubernetes","text":"The same default CWNPs are deployed and the container images are pulled from the private registry. Also DNS and NTP are configured to use the private DNS and NTP servers. The only difference to the forbidden mode is that CWNPs and Service Type LoadBalancers can be created without the restriction that only allowed networks are allowed.","category":"page"},{"location":"overview/isolated-kubernetes/","page":"Isolated Kubernetes","title":"Isolated Kubernetes","text":"Pulling container images is theoretically possible if a cluster user creates a CWNP which allows network access to an external registry. But most container registries serve the container images from large CDN networks, which have a lot of ip addresses. Simply adding the ip address of docker.io is therefore not sufficient.","category":"page"},{"location":"overview/isolated-kubernetes/#Application-Container-Images","page":"Isolated Kubernetes","title":"Application Container Images","text":"","category":"section"},{"location":"overview/isolated-kubernetes/","page":"Isolated Kubernetes","title":"Isolated Kubernetes","text":"In order to deploy application containers into a cluster with Internet Access forbidden a private registry must be provided. This private registry must be located in the list of allowed networks. The DNS name of the registry must resolve in the public DNS servers. The registry must be secured with a TLS certificate that is also valid with the CA certificates from the worker node, e.g. vanilla debian ca-certificates.","category":"page"},{"location":"overview/isolated-kubernetes/#Implementation","page":"Isolated Kubernetes","title":"Implementation","text":"","category":"section"},{"location":"overview/isolated-kubernetes/","page":"Isolated Kubernetes","title":"Isolated Kubernetes","text":"To achieve this functionality modifications have been implemented in various components in metal-stack, this includes:","category":"page"},{"location":"overview/isolated-kubernetes/#Gardener-Extension-Provider-Metal","page":"Isolated Kubernetes","title":"Gardener Extension Provider Metal","text":"","category":"section"},{"location":"overview/isolated-kubernetes/","page":"Isolated Kubernetes","title":"Isolated Kubernetes","text":"The ControlPlane API is adopted to enable a user to configure a shoot with the internet access type forbidden or restricted. The CloudProfile can now be extended to carry the list of allowed networks, the dns and ntp servers, the registry with the mirrored registries.","category":"page"},{"location":"overview/isolated-kubernetes/","page":"Isolated Kubernetes","title":"Isolated Kubernetes","text":"ControlPlane:","category":"page"},{"location":"overview/isolated-kubernetes/","page":"Isolated Kubernetes","title":"Isolated Kubernetes","text":"// ControlPlaneConfig contains configuration settings for the control plane.\ntype ControlPlaneConfig struct {\n metav1.TypeMeta\n\n // NetworkAccessType defines how the cluster can reach external networks.\n // +optional\n NetworkAccessType *NetworkAccessType\n}\ntype (\n // NetworkAccessType defines how a cluster is capable of accessing external networks\n NetworkAccessType string\n)\n\nconst (\n // NetworkAccessBaseline allows the cluster to access external networks in a baseline manner\n NetworkAccessBaseline = NetworkAccessType(\"baseline\")\n // NetworkAccessRestricted access to external networks is by default restricted to registries, dns and ntp to partition only destinations.\n // Therefore registries, dns and ntp destinations must be specified in the cloud-profile accordingly.\n // If this is not the case, restricting the access must not be possible.\n // Image overrides for all images which are required to create such a shoot, must be specified. No other images are provided in the given registry.\n // customers can define own rules to access external networks as in the baseline.\n // Service type LoadBalancers are also not restricted.\n NetworkAccessRestricted = NetworkAccessType(\"restricted\")\n // NetworkAccessForbidden in this configuration a customer can no longer create rules to access external networks.\n // which are outside of a given list of allowed networks. This is enforced by the firewall.\n // Service type LoadBalancers are also not possible to open a service ip which is not in the list of allowed networks.\n // This is also enforced by the firewall.\n NetworkAccessForbidden = NetworkAccessType(\"forbidden\")\n)","category":"page"},{"location":"overview/isolated-kubernetes/","page":"Isolated Kubernetes","title":"Isolated Kubernetes","text":"A sample Shoot Spec:","category":"page"},{"location":"overview/isolated-kubernetes/","page":"Isolated Kubernetes","title":"Isolated Kubernetes","text":"---\napiVersion: core.gardener.cloud/v1beta1\nkind: Shoot\nmetadata:\n name: isolated\n namespace: sample\nspec:\n provider:\n type: metal\n controlPlaneConfig:\n networkAccessType: forbidden\n...","category":"page"},{"location":"overview/isolated-kubernetes/","page":"Isolated Kubernetes","title":"Isolated Kubernetes","text":"CloudProfile:","category":"page"},{"location":"overview/isolated-kubernetes/","page":"Isolated Kubernetes","title":"Isolated Kubernetes","text":"type NetworkIsolation struct {\n // AllowedNetworks is a list of networks which are allowed to connect in restricted or forbidden NetworkIsolated clusters.\n AllowedNetworks AllowedNetworks\n // DNSServers\n DNSServers []string\n // NTPServers\n NTPServers []string\n // The registry which serves the images required to create a shoot.\n RegistryMirrors []RegistryMirror\n}\n\n// AllowedNetworks is a list of networks which are allowed to connect in restricted or forbidden NetworkIsolated clusters.\ntype AllowedNetworks struct {\n // Ingress defines a list of networks which are allowed for incoming traffic like service type LoadBalancer\n // to allow all you must specify 0.0.0.0/0 or ::/0\n Ingress []string\n // Egress defines a list of networks which are allowed for outgoing traffic\n // to allow all you must specify 0.0.0.0/0 or ::/0\n Egress []string\n}\n\ntype RegistryMirror struct {\n // Name describes this server\n Name string\n // Endpoint is typically the url of the registry in the form https://hostname\n Endpoint string\n // IP is the ipv4 or ipv6 address of this server\n IP string\n // Port at which port the service is reachable\n Port int32\n // This Registry Mirror mirrors the following registries\n MirrorOf []string \n}","category":"page"},{"location":"overview/isolated-kubernetes/","page":"Isolated Kubernetes","title":"Isolated Kubernetes","text":"A sample configuration in the CloudProfile would look like:","category":"page"},{"location":"overview/isolated-kubernetes/","page":"Isolated Kubernetes","title":"Isolated Kubernetes","text":" network-isolation:\n allowedNetworks:\n egress:\n - 1.2.3.0/24 # Internet CIDR of the Provider\n - 100.64.0.0/10\n - 10.0.0.0/8\n ingress:\n - 100.64.0.0/10\n dnsServers:\n - \"1.2.3.1\"\n - \"1.2.3.2\"\n - \"1.2.3.3\"\n ntpServers:\n - \"1.2.3.1\"\n - \"1.2.3.2\"\n - \"1.2.3.3\"\n registryMirrors:\n - name: test registry\n endpoint: https://some.private.registry\n ip: \"1.2.3.4\"\n port: 443\n mirrorOf:\n - \"docker.io\"\n - \"quay.io\"\n - \"eu.gcr.io\"\n - \"ghcr.io\"\n - \"registry.k8s.io\"","category":"page"},{"location":"overview/isolated-kubernetes/#OS-Metal-Extension","page":"Isolated Kubernetes","title":"OS Metal Extension","text":"","category":"section"},{"location":"overview/isolated-kubernetes/","page":"Isolated Kubernetes","title":"Isolated Kubernetes","text":"Based on the configuration of a cluster the configuration of the containerd must be changed to pull images from the private registry mirror. If a cluster is either configured with restricted or forbidden, the configuration of containerd will be created as such:","category":"page"},{"location":"overview/isolated-kubernetes/","page":"Isolated Kubernetes","title":"Isolated Kubernetes","text":"config.toml","category":"page"},{"location":"overview/isolated-kubernetes/","page":"Isolated Kubernetes","title":"Isolated Kubernetes","text":"imports = [\"/etc/containerd/conf.d/*.toml\"]\nversion = 2\n\n[plugins.\"io.containerd.grpc.v1.cri\".registry]\n [plugins.\"io.containerd.grpc.v1.cri\".reg\n [plugins.\"io.containerd.grpc.v1.cri\".registry.mirrors.\"docker.io\"]\n endpoint = [\"https://some.private.registry\"]\n [plugins.\"io.containerd.grpc.v1.cri\".registry.mirrors.\"quay.io\"]\n endpoint = [\"https://some.private.registry\"]\n [plugins.\"io.containerd.grpc.v1.cri\".registry.mirrors.\"docker.lightbitslabs.com\"]\n endpoint = [\"https://some.private.registry\"]\n [plugins.\"io.containerd.grpc.v1.cri\".registry.mirrors.\"eu.gcr.io\"]\n endpoint = [\"https://some.private.registry\"]\n [plugins.\"io.containerd.grpc.v1.cri\".registry.mirrors.\"ghcr.io\"]\n endpoint = [\"https://some.private.registry\"]\n [plugins.\"io.containerd.grpc.v1.cri\".registry.mirrors.\"registry.k8s.io\"]\n endpoint = [\"https://some.private.registry\"]\n [plugins.\"io.containerd.grpc.v1.cri\".registry.mirrors.\"r.metal-stack.io\"]\n endpoint = [\"https://some.private.registry\"]","category":"page"},{"location":"overview/isolated-kubernetes/","page":"Isolated Kubernetes","title":"Isolated Kubernetes","text":"DNS and NTP must also be adopted according to the configuration in the CloudProfile.","category":"page"},{"location":"overview/isolated-kubernetes/#Firewall-Controller-Manager-and-Firewall-Controller","page":"Isolated Kubernetes","title":"Firewall Controller Manager and Firewall Controller","text":"","category":"section"},{"location":"overview/isolated-kubernetes/","page":"Isolated Kubernetes","title":"Isolated Kubernetes","text":"The Firewall Controller Manager has extended the FirewallSpec to configure the Firewall Controller which must enforce the restrictions regarding allowed networks.","category":"page"},{"location":"overview/isolated-kubernetes/","page":"Isolated Kubernetes","title":"Isolated Kubernetes","text":"// FirewallSpec defines parameters for the firewall creation along with configuration for the firewall-controller.\ntype FirewallSpec struct {\n // AllowedNetworks defines which networks are allowed to connect to, and allow incoming traffic from.\n // Is enforced with NetworkAccessForbidden.\n // The node network is always allowed.\n AllowedNetworks AllowedNetworks `json:\"allowedNetworks,omitempty\"`\n}\n\n// AllowedNetworks is a list of networks which are allowed to connect when NetworkAccessType is NetworkAccessForbidden.\ntype AllowedNetworks struct {\n // Ingress defines a list of cidrs which are allowed for incoming traffic like service type LoadBalancer\n Ingress []string `json:\"ingress,omitempty\"`\n // Egress defines a list of cidrs which are allowed for outgoing traffic\n Egress []string `json:\"egress,omitempty\"`\n}","category":"page"},{"location":"overview/isolated-kubernetes/","page":"Isolated Kubernetes","title":"Isolated Kubernetes","text":"Also the ClusterwideNetworkPolicy in the Firewall Controller was changed to show the deployment status of a CWNP.","category":"page"},{"location":"overview/isolated-kubernetes/","page":"Isolated Kubernetes","title":"Isolated Kubernetes","text":"\ntype ClusterwideNetworkPolicy struct {\n metav1.TypeMeta `json:\",inline\"`\n metav1.ObjectMeta `json:\"metadata,omitempty\"` \n\n Spec PolicySpec `json:\"spec,omitempty\"`\n Status PolicyStatus `json:\"status,omitempty\"`\n}\n\n// PolicyDeploymentState describes the state of a CWNP deployment\ntype PolicyDeploymentState string\n\nconst (\n // PolicyDeploymentStateDeployed the CWNP was deployed to a native nftable rule\n PolicyDeploymentStateDeployed = PolicyDeploymentState(\"deployed\")\n // PolicyDeploymentStateIgnored the CWNP was not deployed to a native nftable rule because it is outside of the allowed networks\n PolicyDeploymentStateIgnored = PolicyDeploymentState(\"ignored\")\n)\n\n// PolicyStatus defines the observed state for CWNP resource\ntype PolicyStatus struct {\n // FQDNState stores mapping from FQDN rules to nftables sets used for a firewall rule.\n // Key is either MatchName or MatchPattern\n // +optional\n FQDNState FQDNState `json:\"fqdn_state,omitempty\"` \n // State of the CWNP, can be either deployed or ignored\n State PolicyDeploymentState `json:\"state\"` \n // Message describe why the state changed\n Message string `json:\"message,omitempty\"`\n}","category":"page"},{"location":"overview/isolated-kubernetes/#Cloud-Controller-Manager","page":"Isolated Kubernetes","title":"Cloud Controller Manager","text":"","category":"section"},{"location":"overview/isolated-kubernetes/","page":"Isolated Kubernetes","title":"Isolated Kubernetes","text":"This component was adopted to allow to be started without a default network specified. This was actually always the internet network and if no ip address was specified in the Service Type LoadBalancer, one ip was allocated from this default network. For isolated clusters this is not provided and a cluster user must always specify this ip to get a working load balancer.","category":"page"},{"location":"overview/isolated-kubernetes/#OCI-Mirror","page":"Isolated Kubernetes","title":"OCI Mirror","text":"","category":"section"},{"location":"overview/isolated-kubernetes/","page":"Isolated Kubernetes","title":"Isolated Kubernetes","text":"The OCI Mirror is a new application which acts as a scheduled job that pulls a given list of container images and pushes them to a private registry (which will then serve as the private registry mirror). The detailed description can be read on the project website.","category":"page"},{"location":"overview/isolated-kubernetes/#Related-Pull-Requests","page":"Isolated Kubernetes","title":"Related Pull Requests","text":"","category":"section"},{"location":"overview/isolated-kubernetes/","page":"Isolated Kubernetes","title":"Isolated Kubernetes","text":"Gardener Extension Provider\nFirewall Controller Manager\nFirewall Controller\nOS Metal Extension\nMetal Cloud Controller Manager\nMetal Networker\nMetal Images\nOCI Mirror","category":"page"},{"location":"external/metalctl/docs/metalctl_partition/#metalctl-partition","page":"metalctl partition","title":"metalctl partition","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_partition/","page":"metalctl partition","title":"metalctl partition","text":"manage partition entities","category":"page"},{"location":"external/metalctl/docs/metalctl_partition/#Synopsis","page":"metalctl partition","title":"Synopsis","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_partition/","page":"metalctl partition","title":"metalctl partition","text":"a partition is a failure domain in the data center.","category":"page"},{"location":"external/metalctl/docs/metalctl_partition/#Options","page":"metalctl partition","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_partition/","page":"metalctl partition","title":"metalctl partition","text":" -h, --help help for partition","category":"page"},{"location":"external/metalctl/docs/metalctl_partition/#Options-inherited-from-parent-commands","page":"metalctl partition","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_partition/","page":"metalctl partition","title":"metalctl partition","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_partition/#SEE-ALSO","page":"metalctl partition","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_partition/","page":"metalctl partition","title":"metalctl partition","text":"metalctl\t - a cli to manage entities in the metal-stack api\nmetalctl partition apply\t - applies one or more partitions from a given file\nmetalctl partition capacity\t - show partition capacity\nmetalctl partition create\t - creates the partition\nmetalctl partition delete\t - deletes the partition\nmetalctl partition describe\t - describes the partition\nmetalctl partition edit\t - edit the partition through an editor and update\nmetalctl partition list\t - list all partitions\nmetalctl partition update\t - updates the partition","category":"page"},{"location":"external/metalctl/docs/metalctl_filesystemlayout_apply/#metalctl-filesystemlayout-apply","page":"metalctl filesystemlayout apply","title":"metalctl filesystemlayout apply","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_filesystemlayout_apply/","page":"metalctl filesystemlayout apply","title":"metalctl filesystemlayout apply","text":"applies one or more filesystemlayouts from a given file","category":"page"},{"location":"external/metalctl/docs/metalctl_filesystemlayout_apply/","page":"metalctl filesystemlayout apply","title":"metalctl filesystemlayout apply","text":"metalctl filesystemlayout apply [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_filesystemlayout_apply/#Options","page":"metalctl filesystemlayout apply","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_filesystemlayout_apply/","page":"metalctl filesystemlayout apply","title":"metalctl filesystemlayout apply","text":" --bulk-output when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.\n -f, --file string filename of the create or update request in yaml format, or - for stdin.\n \n Example:\n $ metalctl filesystemlayout describe filesystemlayout-1 -o yaml > filesystemlayout.yaml\n $ vi filesystemlayout.yaml\n $ # either via stdin\n $ cat filesystemlayout.yaml | metalctl filesystemlayout apply -f -\n $ # or via file\n $ metalctl filesystemlayout apply -f filesystemlayout.yaml\n \n the file can also contain multiple documents and perform a bulk operation.\n \t\n -h, --help help for apply\n --skip-security-prompts skips security prompt for bulk operations\n --timestamps when used with --file (bulk operation): prints timestamps in-between the operations","category":"page"},{"location":"external/metalctl/docs/metalctl_filesystemlayout_apply/#Options-inherited-from-parent-commands","page":"metalctl filesystemlayout apply","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_filesystemlayout_apply/","page":"metalctl filesystemlayout apply","title":"metalctl filesystemlayout apply","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_filesystemlayout_apply/#SEE-ALSO","page":"metalctl filesystemlayout apply","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_filesystemlayout_apply/","page":"metalctl filesystemlayout apply","title":"metalctl filesystemlayout apply","text":"metalctl filesystemlayout\t - manage filesystemlayout entities","category":"page"},{"location":"external/metalctl/docs/metalctl_switch_connected-machines/#metalctl-switch-connected-machines","page":"metalctl switch connected-machines","title":"metalctl switch connected-machines","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_switch_connected-machines/","page":"metalctl switch connected-machines","title":"metalctl switch connected-machines","text":"shows switches with their connected machines","category":"page"},{"location":"external/metalctl/docs/metalctl_switch_connected-machines/","page":"metalctl switch connected-machines","title":"metalctl switch connected-machines","text":"metalctl switch connected-machines [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_switch_connected-machines/#Examples","page":"metalctl switch connected-machines","title":"Examples","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_switch_connected-machines/","page":"metalctl switch connected-machines","title":"metalctl switch connected-machines","text":"The command will show the machines connected to the switch ports.\n\nCan also be used with -o template in order to generate CSV-style output:\n\n$ metalctl switch connected-machines -o template --template '{{ $machines := .machines }}{{ range .switches }}{{ $switch := . }}{{ range .connections }}{{ $switch.id }},{{ $switch.rack_id }},{{ .nic.name }},{{ .machine_id }},{{ (index $machines .machine_id).ipmi.fru.product_serial }}{{ printf \"\\n\" }}{{ end }}{{ end }}'\nr01leaf01,swp1,f78cc340-e5e8-48ed-8fe7-2336c1e2ded2,\nr01leaf01,swp2,44e3a522-5f48-4f3c-9188-41025f9e401e,\n...\n","category":"page"},{"location":"external/metalctl/docs/metalctl_switch_connected-machines/#Options","page":"metalctl switch connected-machines","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_switch_connected-machines/","page":"metalctl switch connected-machines","title":"metalctl switch connected-machines","text":" -h, --help help for connected-machines\n --id string ID of the switch.\n --machine-id string The id of the connected machine, ignores size flag if set.\n --name string Name of the switch.\n --os-vendor string OS vendor of this switch.\n --os-version string OS version of this switch.\n --partition string Partition of this switch.\n --rack string Rack of this switch.\n --size string Size of the connected machines.","category":"page"},{"location":"external/metalctl/docs/metalctl_switch_connected-machines/#Options-inherited-from-parent-commands","page":"metalctl switch connected-machines","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_switch_connected-machines/","page":"metalctl switch connected-machines","title":"metalctl switch connected-machines","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_switch_connected-machines/#SEE-ALSO","page":"metalctl switch connected-machines","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_switch_connected-machines/","page":"metalctl switch connected-machines","title":"metalctl switch connected-machines","text":"metalctl switch\t - manage switch entities","category":"page"},{"location":"external/metalctl/docs/metalctl_filesystemlayout_create/#metalctl-filesystemlayout-create","page":"metalctl filesystemlayout create","title":"metalctl filesystemlayout create","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_filesystemlayout_create/","page":"metalctl filesystemlayout create","title":"metalctl filesystemlayout create","text":"creates the filesystemlayout","category":"page"},{"location":"external/metalctl/docs/metalctl_filesystemlayout_create/","page":"metalctl filesystemlayout create","title":"metalctl filesystemlayout create","text":"metalctl filesystemlayout create [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_filesystemlayout_create/#Options","page":"metalctl filesystemlayout create","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_filesystemlayout_create/","page":"metalctl filesystemlayout create","title":"metalctl filesystemlayout create","text":" --bulk-output when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.\n -f, --file string filename of the create or update request in yaml format, or - for stdin.\n \n Example:\n $ metalctl filesystemlayout describe filesystemlayout-1 -o yaml > filesystemlayout.yaml\n $ vi filesystemlayout.yaml\n $ # either via stdin\n $ cat filesystemlayout.yaml | metalctl filesystemlayout create -f -\n $ # or via file\n $ metalctl filesystemlayout create -f filesystemlayout.yaml\n \n the file can also contain multiple documents and perform a bulk operation.\n \t\n -h, --help help for create\n --skip-security-prompts skips security prompt for bulk operations\n --timestamps when used with --file (bulk operation): prints timestamps in-between the operations","category":"page"},{"location":"external/metalctl/docs/metalctl_filesystemlayout_create/#Options-inherited-from-parent-commands","page":"metalctl filesystemlayout create","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_filesystemlayout_create/","page":"metalctl filesystemlayout create","title":"metalctl filesystemlayout create","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_filesystemlayout_create/#SEE-ALSO","page":"metalctl filesystemlayout create","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_filesystemlayout_create/","page":"metalctl filesystemlayout create","title":"metalctl filesystemlayout create","text":"metalctl filesystemlayout\t - manage filesystemlayout entities","category":"page"},{"location":"external/metalctl/docs/metalctl_project_delete/#metalctl-project-delete","page":"metalctl project delete","title":"metalctl project delete","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_project_delete/","page":"metalctl project delete","title":"metalctl project delete","text":"deletes the project","category":"page"},{"location":"external/metalctl/docs/metalctl_project_delete/","page":"metalctl project delete","title":"metalctl project delete","text":"metalctl project delete [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_project_delete/#Options","page":"metalctl project delete","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_project_delete/","page":"metalctl project delete","title":"metalctl project delete","text":" --bulk-output when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.\n -f, --file string filename of the create or update request in yaml format, or - for stdin.\n \n Example:\n $ metalctl project describe project-1 -o yaml > project.yaml\n $ vi project.yaml\n $ # either via stdin\n $ cat project.yaml | metalctl project delete -f -\n $ # or via file\n $ metalctl project delete -f project.yaml\n \n the file can also contain multiple documents and perform a bulk operation.\n \t\n -h, --help help for delete\n --skip-security-prompts skips security prompt for bulk operations\n --timestamps when used with --file (bulk operation): prints timestamps in-between the operations","category":"page"},{"location":"external/metalctl/docs/metalctl_project_delete/#Options-inherited-from-parent-commands","page":"metalctl project delete","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_project_delete/","page":"metalctl project delete","title":"metalctl project delete","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_project_delete/#SEE-ALSO","page":"metalctl project delete","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_project_delete/","page":"metalctl project delete","title":"metalctl project delete","text":"metalctl project\t - manage project entities","category":"page"},{"location":"external/metalctl/docs/metalctl_image_apply/#metalctl-image-apply","page":"metalctl image apply","title":"metalctl image apply","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_image_apply/","page":"metalctl image apply","title":"metalctl image apply","text":"applies one or more images from a given file","category":"page"},{"location":"external/metalctl/docs/metalctl_image_apply/","page":"metalctl image apply","title":"metalctl image apply","text":"metalctl image apply [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_image_apply/#Options","page":"metalctl image apply","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_image_apply/","page":"metalctl image apply","title":"metalctl image apply","text":" --bulk-output when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.\n -f, --file string filename of the create or update request in yaml format, or - for stdin.\n \n Example:\n $ metalctl image describe image-1 -o yaml > image.yaml\n $ vi image.yaml\n $ # either via stdin\n $ cat image.yaml | metalctl image apply -f -\n $ # or via file\n $ metalctl image apply -f image.yaml\n \n the file can also contain multiple documents and perform a bulk operation.\n \t\n -h, --help help for apply\n --skip-security-prompts skips security prompt for bulk operations\n --timestamps when used with --file (bulk operation): prints timestamps in-between the operations","category":"page"},{"location":"external/metalctl/docs/metalctl_image_apply/#Options-inherited-from-parent-commands","page":"metalctl image apply","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_image_apply/","page":"metalctl image apply","title":"metalctl image apply","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_image_apply/#SEE-ALSO","page":"metalctl image apply","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_image_apply/","page":"metalctl image apply","title":"metalctl image apply","text":"metalctl image\t - manage image entities","category":"page"},{"location":"external/metalctl/docs/metalctl_network_list/#metalctl-network-list","page":"metalctl network list","title":"metalctl network list","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_network_list/","page":"metalctl network list","title":"metalctl network list","text":"list all networks","category":"page"},{"location":"external/metalctl/docs/metalctl_network_list/","page":"metalctl network list","title":"metalctl network list","text":"metalctl network list [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_network_list/#Options","page":"metalctl network list","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_network_list/","page":"metalctl network list","title":"metalctl network list","text":" --destination-prefixes strings destination prefixes to filter, use it like: --destination-prefixes prefix1,prefix2.\n -h, --help help for list\n --id string ID to filter [optional]\n --name string name to filter [optional]\n --nat nat to filter [optional]\n --parent string parent network to filter [optional]\n --partition string partition to filter [optional]\n --prefixes strings prefixes to filter, use it like: --prefixes prefix1,prefix2.\n --privatesuper privatesuper to filter [optional]\n --project string project to filter [optional]\n --sort-by strings sort by (comma separated) column(s), sort direction can be changed by appending :asc or :desc behind the column identifier. possible values: description|id|name|partition|project\n --underlay underlay to filter [optional]\n --vrf int vrf to filter [optional]","category":"page"},{"location":"external/metalctl/docs/metalctl_network_list/#Options-inherited-from-parent-commands","page":"metalctl network list","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_network_list/","page":"metalctl network list","title":"metalctl network list","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_network_list/#SEE-ALSO","page":"metalctl network list","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_network_list/","page":"metalctl network list","title":"metalctl network list","text":"metalctl network\t - manage network entities","category":"page"},{"location":"development/proposals/MEP5/README/#Shared-Networks","page":"Shared Networks","title":"Shared Networks","text":"","category":"section"},{"location":"development/proposals/MEP5/README/#Why-are-shared-networks-needed","page":"Shared Networks","title":"Why are shared networks needed","text":"","category":"section"},{"location":"development/proposals/MEP5/README/","page":"Shared Networks","title":"Shared Networks","text":"For special purpose machines that serve shared services with performance critical workloads to all machines of a partition (like persistent storage) it would be good to have kind of a \"shared network\" that is easily accessible. They do not necessarily need another firewall. This would avoid having two firewalls in the datapath between a machine in a private network and the machines of a shared service.","category":"page"},{"location":"development/proposals/MEP5/README/#Constraints-that-need-to-hold","page":"Shared Networks","title":"Constraints that need to hold","text":"","category":"section"},{"location":"development/proposals/MEP5/README/","page":"Shared Networks","title":"Shared Networks","text":"a shared network is usable from all machines that have a firewall in front, that uses it\na shared network is only usable within a single partition (currently we are constrained in bandwidth and have no routing of 10.0.0.0/8 addresses btw. partitions and failure domain should be the partition but this constraint might get lifted in the future)\nnetworks may be marked as shared after network allocation (but there should be no way back from shared to unshared)\nneither machines nor firewalls may have multiple private, unshared networks configured\nmachines must have a single primary network configured\nthis might be a shared network\nOR a plain, unshared private network\nfirewalls may participate in multiple shared networks\nmachines can be allocated with a primary network using auto IP allocation or with noauto and a specific IP","category":"page"},{"location":"development/proposals/MEP5/README/#Should-shared-networks-be-private","page":"Shared Networks","title":"Should shared networks be private","text":"","category":"section"},{"location":"development/proposals/MEP5/README/","page":"Shared Networks","title":"Shared Networks","text":"Alternative 1: If we implemented shared networks by extending functions around plain, private networks we would not have to manage another CIDR (mini point) and it would be possible to create a k8s cluster with a private network, mark the network as shared and produce shared services from this k8s cluster.","category":"page"},{"location":"development/proposals/MEP5/README/","page":"Shared Networks","title":"Shared Networks","text":"Alternative 2: If shared networks are implemented as first class networks we could customize the VRF and also accomplish an other goal of our roadmap: being able to create machines directly in an external network.","category":"page"},{"location":"development/proposals/MEP5/README/","page":"Shared Networks","title":"Shared Networks","text":"Together with @majst01 and @Gerrit91 we decided to continue to implement Alternative 1.","category":"page"},{"location":"development/proposals/MEP5/README/#Firewalls-accessing-a-shared-network","page":"Shared Networks","title":"Firewalls accessing a shared network","text":"","category":"section"},{"location":"development/proposals/MEP5/README/","page":"Shared Networks","title":"Shared Networks","text":"Firewalls that access shared networks need to:","category":"page"},{"location":"development/proposals/MEP5/README/","page":"Shared Networks","title":"Shared Networks","text":"hide the private network behind an ip address of the shared network if the shared network was configured with nat=true.\nimport the prefixes of the shared VRF to the private VRF and import the prefixes of the private VRF to the shared VRF so that the communication between the two is working in both directions. As long as no nat=true was set on the shared VRF, the original machine ips are visible in both communication directions.","category":"page"},{"location":"development/proposals/MEP5/README/#Setup-with-shared-networks-and-single-consumer","page":"Shared Networks","title":"Setup with shared networks and single consumer","text":"","category":"section"},{"location":"development/proposals/MEP5/README/","page":"Shared Networks","title":"Shared Networks","text":"(Image: Simple Setup)","category":"page"},{"location":"development/proposals/MEP5/README/#Setup-with-single-shared-network-and-multiple-consumers","page":"Shared Networks","title":"Setup with single shared network and multiple consumers","text":"","category":"section"},{"location":"development/proposals/MEP5/README/","page":"Shared Networks","title":"Shared Networks","text":"(Image: Advanced Setup)","category":"page"},{"location":"development/proposals/MEP5/README/#Getting-internet-access","page":"Shared Networks","title":"Getting internet access","text":"","category":"section"},{"location":"development/proposals/MEP5/README/","page":"Shared Networks","title":"Shared Networks","text":"Machines contained in a shared network can access the internet with different scenarios:","category":"page"},{"location":"development/proposals/MEP5/README/","page":"Shared Networks","title":"Shared Networks","text":"if they have an own firewall: this is internet accessibility, as common (check whether all traffic gets routed through it!)\nif they don't have an own firewall, an external HTTP proxy is needed that has an endpoint exposed as Service Type NodePort","category":"page"},{"location":"external/metalctl/docs/metalctl_tenant_delete/#metalctl-tenant-delete","page":"metalctl tenant delete","title":"metalctl tenant delete","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_tenant_delete/","page":"metalctl tenant delete","title":"metalctl tenant delete","text":"deletes the tenant","category":"page"},{"location":"external/metalctl/docs/metalctl_tenant_delete/","page":"metalctl tenant delete","title":"metalctl tenant delete","text":"metalctl tenant delete [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_tenant_delete/#Options","page":"metalctl tenant delete","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_tenant_delete/","page":"metalctl tenant delete","title":"metalctl tenant delete","text":" --bulk-output when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.\n -f, --file string filename of the create or update request in yaml format, or - for stdin.\n \n Example:\n $ metalctl tenant describe tenant-1 -o yaml > tenant.yaml\n $ vi tenant.yaml\n $ # either via stdin\n $ cat tenant.yaml | metalctl tenant delete -f -\n $ # or via file\n $ metalctl tenant delete -f tenant.yaml\n \n the file can also contain multiple documents and perform a bulk operation.\n \t\n -h, --help help for delete\n --skip-security-prompts skips security prompt for bulk operations\n --timestamps when used with --file (bulk operation): prints timestamps in-between the operations","category":"page"},{"location":"external/metalctl/docs/metalctl_tenant_delete/#Options-inherited-from-parent-commands","page":"metalctl tenant delete","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_tenant_delete/","page":"metalctl tenant delete","title":"metalctl tenant delete","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_tenant_delete/#SEE-ALSO","page":"metalctl tenant delete","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_tenant_delete/","page":"metalctl tenant delete","title":"metalctl tenant delete","text":"metalctl tenant\t - manage tenant entities","category":"page"},{"location":"external/firewall-controller/CONTRIBUTING/#Contributing","page":"Contributing","title":"Contributing","text":"","category":"section"},{"location":"external/firewall-controller/CONTRIBUTING/","page":"Contributing","title":"Contributing","text":"Please check out the contributing section in our docs.","category":"page"},{"location":"external/metalctl/docs/metalctl_network_ip_create/#metalctl-network-ip-create","page":"metalctl network ip create","title":"metalctl network ip create","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_network_ip_create/","page":"metalctl network ip create","title":"metalctl network ip create","text":"creates the ip","category":"page"},{"location":"external/metalctl/docs/metalctl_network_ip_create/","page":"metalctl network ip create","title":"metalctl network ip create","text":"metalctl network ip create [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_network_ip_create/#Options","page":"metalctl network ip create","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_network_ip_create/","page":"metalctl network ip create","title":"metalctl network ip create","text":" --bulk-output when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.\n -d, --description string description of the IP to allocate. [optional]\n -f, --file string filename of the create or update request in yaml format, or - for stdin.\n \n Example:\n $ metalctl ip describe ip-1 -o yaml > ip.yaml\n $ vi ip.yaml\n $ # either via stdin\n $ cat ip.yaml | metalctl ip create -f -\n $ # or via file\n $ metalctl ip create -f ip.yaml\n \n the file can also contain multiple documents and perform a bulk operation.\n \t\n -h, --help help for create\n --ipaddress string a specific ip address to allocate. [optional]\n -n, --name string name of the IP to allocate. [optional]\n --network string network from where the IP should be allocated.\n --project string project for which the IP should be allocated.\n --skip-security-prompts skips security prompt for bulk operations\n --tags strings tags to attach to the IP.\n --timestamps when used with --file (bulk operation): prints timestamps in-between the operations\n --type string type of the IP to allocate: ephemeral|static [optional] (default \"ephemeral\")","category":"page"},{"location":"external/metalctl/docs/metalctl_network_ip_create/#Options-inherited-from-parent-commands","page":"metalctl network ip create","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_network_ip_create/","page":"metalctl network ip create","title":"metalctl network ip create","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_network_ip_create/#SEE-ALSO","page":"metalctl network ip create","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_network_ip_create/","page":"metalctl network ip create","title":"metalctl network ip create","text":"metalctl network ip\t - manage ip entities","category":"page"},{"location":"external/metalctl/docs/metalctl_size_reservation_edit/#metalctl-size-reservation-edit","page":"metalctl size reservation edit","title":"metalctl size reservation edit","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_reservation_edit/","page":"metalctl size reservation edit","title":"metalctl size reservation edit","text":"edit the reservation through an editor and update","category":"page"},{"location":"external/metalctl/docs/metalctl_size_reservation_edit/","page":"metalctl size reservation edit","title":"metalctl size reservation edit","text":"metalctl size reservation edit [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_size_reservation_edit/#Options","page":"metalctl size reservation edit","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_reservation_edit/","page":"metalctl size reservation edit","title":"metalctl size reservation edit","text":" -h, --help help for edit","category":"page"},{"location":"external/metalctl/docs/metalctl_size_reservation_edit/#Options-inherited-from-parent-commands","page":"metalctl size reservation edit","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_reservation_edit/","page":"metalctl size reservation edit","title":"metalctl size reservation edit","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_size_reservation_edit/#SEE-ALSO","page":"metalctl size reservation edit","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_reservation_edit/","page":"metalctl size reservation edit","title":"metalctl size reservation edit","text":"metalctl size reservation\t - manage reservation entities","category":"page"},{"location":"external/metalctl/docs/metalctl_health/#metalctl-health","page":"metalctl health","title":"metalctl health","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_health/","page":"metalctl health","title":"metalctl health","text":"shows the server health","category":"page"},{"location":"external/metalctl/docs/metalctl_health/","page":"metalctl health","title":"metalctl health","text":"metalctl health [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_health/#Options","page":"metalctl health","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_health/","page":"metalctl health","title":"metalctl health","text":" -h, --help help for health","category":"page"},{"location":"external/metalctl/docs/metalctl_health/#Options-inherited-from-parent-commands","page":"metalctl health","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_health/","page":"metalctl health","title":"metalctl health","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_health/#SEE-ALSO","page":"metalctl health","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_health/","page":"metalctl health","title":"metalctl health","text":"metalctl\t - a cli to manage entities in the metal-stack api","category":"page"},{"location":"external/metalctl/docs/metalctl_firmware_upload/#metalctl-firmware-upload","page":"metalctl firmware upload","title":"metalctl firmware upload","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_firmware_upload/","page":"metalctl firmware upload","title":"metalctl firmware upload","text":"upload a firmware","category":"page"},{"location":"external/metalctl/docs/metalctl_firmware_upload/#Options","page":"metalctl firmware upload","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_firmware_upload/","page":"metalctl firmware upload","title":"metalctl firmware upload","text":" -h, --help help for upload","category":"page"},{"location":"external/metalctl/docs/metalctl_firmware_upload/#Options-inherited-from-parent-commands","page":"metalctl firmware upload","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_firmware_upload/","page":"metalctl firmware upload","title":"metalctl firmware upload","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_firmware_upload/#SEE-ALSO","page":"metalctl firmware upload","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_firmware_upload/","page":"metalctl firmware upload","title":"metalctl firmware upload","text":"metalctl firmware\t - manage firmwares\nmetalctl firmware upload bios\t - upload a BIOS firmware\nmetalctl firmware upload bmc\t - upload a BMC firmware","category":"page"},{"location":"external/metalctl/docs/metalctl_switch_detail/#metalctl-switch-detail","page":"metalctl switch detail","title":"metalctl switch detail","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_switch_detail/","page":"metalctl switch detail","title":"metalctl switch detail","text":"switch details","category":"page"},{"location":"external/metalctl/docs/metalctl_switch_detail/","page":"metalctl switch detail","title":"metalctl switch detail","text":"metalctl switch detail [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_switch_detail/#Options","page":"metalctl switch detail","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_switch_detail/","page":"metalctl switch detail","title":"metalctl switch detail","text":" -h, --help help for detail\n --id string ID of the switch.\n --name string Name of the switch.\n --os-vendor string OS vendor of this switch.\n --os-version string OS version of this switch.\n --partition string Partition of this switch.\n --rack string Rack of this switch.","category":"page"},{"location":"external/metalctl/docs/metalctl_switch_detail/#Options-inherited-from-parent-commands","page":"metalctl switch detail","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_switch_detail/","page":"metalctl switch detail","title":"metalctl switch detail","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_switch_detail/#SEE-ALSO","page":"metalctl switch detail","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_switch_detail/","page":"metalctl switch detail","title":"metalctl switch detail","text":"metalctl switch\t - manage switch entities","category":"page"},{"location":"external/metalctl/docs/metalctl_switch_edit/#metalctl-switch-edit","page":"metalctl switch edit","title":"metalctl switch edit","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_switch_edit/","page":"metalctl switch edit","title":"metalctl switch edit","text":"edit the switch through an editor and update","category":"page"},{"location":"external/metalctl/docs/metalctl_switch_edit/","page":"metalctl switch edit","title":"metalctl switch edit","text":"metalctl switch edit [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_switch_edit/#Options","page":"metalctl switch edit","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_switch_edit/","page":"metalctl switch edit","title":"metalctl switch edit","text":" -h, --help help for edit","category":"page"},{"location":"external/metalctl/docs/metalctl_switch_edit/#Options-inherited-from-parent-commands","page":"metalctl switch edit","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_switch_edit/","page":"metalctl switch edit","title":"metalctl switch edit","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_switch_edit/#SEE-ALSO","page":"metalctl switch edit","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_switch_edit/","page":"metalctl switch edit","title":"metalctl switch edit","text":"metalctl switch\t - manage switch entities","category":"page"},{"location":"external/metalctl/CONTRIBUTING/#Contributing","page":"Contributing","title":"Contributing","text":"","category":"section"},{"location":"external/metalctl/CONTRIBUTING/","page":"Contributing","title":"Contributing","text":"Please check out the contributing section in our docs.","category":"page"},{"location":"external/metalctl/docs/metalctl_update/#metalctl-update","page":"metalctl update","title":"metalctl update","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_update/","page":"metalctl update","title":"metalctl update","text":"update the program","category":"page"},{"location":"external/metalctl/docs/metalctl_update/#Options","page":"metalctl update","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_update/","page":"metalctl update","title":"metalctl update","text":" -h, --help help for update","category":"page"},{"location":"external/metalctl/docs/metalctl_update/#Options-inherited-from-parent-commands","page":"metalctl update","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_update/","page":"metalctl update","title":"metalctl update","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_update/#SEE-ALSO","page":"metalctl update","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_update/","page":"metalctl update","title":"metalctl update","text":"metalctl\t - a cli to manage entities in the metal-stack api\nmetalctl update check\t - check for update of the program\nmetalctl update do\t - do the update of the program","category":"page"},{"location":"external/metalctl/docs/metalctl_switch_replace/#metalctl-switch-replace","page":"metalctl switch replace","title":"metalctl switch replace","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_switch_replace/","page":"metalctl switch replace","title":"metalctl switch replace","text":"put a leaf switch into replace mode in preparation for physical replacement. For a description of the steps involved see the long help.","category":"page"},{"location":"external/metalctl/docs/metalctl_switch_replace/#Synopsis","page":"metalctl switch replace","title":"Synopsis","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_switch_replace/","page":"metalctl switch replace","title":"metalctl switch replace","text":"Put a leaf switch into replace mode in preparation for physical replacement","category":"page"},{"location":"external/metalctl/docs/metalctl_switch_replace/","page":"metalctl switch replace","title":"metalctl switch replace","text":"Operational steps to replace a switch:","category":"page"},{"location":"external/metalctl/docs/metalctl_switch_replace/","page":"metalctl switch replace","title":"metalctl switch replace","text":"Put the switch that needs to be replaced in replace mode with this command\nReplace the switch MAC address in the metal-stack deployment configuration\nMake sure that interfaces on the new switch do not get connected to the PXE-bridge immediately by setting the interfaces list of the respective leaf switch to [] in the metal-stack deployment configuration\nDeploy the management servers so that the dhcp servers will serve the right address and DHCP options to the new switch\nReplace the switch physically. Be careful to ensure that the cabling mirrors the remaining leaf exactly because the new switch information will be cloned from the remaining switch! Also make sure to have console access to the switch so you can start and monitor the install process\nIf the switch is not in onie install mode but already has an operating system installed, put it into install mode with \"sudo onie-select -i -f -v\" and reboot it. Now the switch should be provisioned with a management IP from a management server, install itself with the right software image and receive license and ssh keys through ZTP. You can check whether that process has completed successfully with the command \"sudo ztp -s\". The ZTP state should be disabled and the result should be success.\nDeploy the switch plane and metal-core through metal-stack deployment CI job\nThe switch will now register with its metal-api, and the metal-core service will receive the cloned interface and routing information. You can verify successful switch replacement by checking the interface and BGP configuration, and checking the switch status with \"metalctl switch ls -o wide\"; it should now be operational again","category":"page"},{"location":"external/metalctl/docs/metalctl_switch_replace/","page":"metalctl switch replace","title":"metalctl switch replace","text":"metalctl switch replace [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_switch_replace/#Options","page":"metalctl switch replace","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_switch_replace/","page":"metalctl switch replace","title":"metalctl switch replace","text":" -h, --help help for replace","category":"page"},{"location":"external/metalctl/docs/metalctl_switch_replace/#Options-inherited-from-parent-commands","page":"metalctl switch replace","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_switch_replace/","page":"metalctl switch replace","title":"metalctl switch replace","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_switch_replace/#SEE-ALSO","page":"metalctl switch replace","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_switch_replace/","page":"metalctl switch replace","title":"metalctl switch replace","text":"metalctl switch\t - manage switch entities","category":"page"},{"location":"external/metalctl/docs/metalctl_tenant_create/#metalctl-tenant-create","page":"metalctl tenant create","title":"metalctl tenant create","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_tenant_create/","page":"metalctl tenant create","title":"metalctl tenant create","text":"creates the tenant","category":"page"},{"location":"external/metalctl/docs/metalctl_tenant_create/","page":"metalctl tenant create","title":"metalctl tenant create","text":"metalctl tenant create [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_tenant_create/#Options","page":"metalctl tenant create","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_tenant_create/","page":"metalctl tenant create","title":"metalctl tenant create","text":" --annotations strings add initial annotations, must be in the form of key=value, can be given multiple times to add multiple annotations, e.g. --annotation key=value --annotation foo=bar\n --bulk-output when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.\n --cluster-quota int32 cluster quota\n --description string description of the tenant.\n -f, --file string filename of the create or update request in yaml format, or - for stdin.\n \n Example:\n $ metalctl tenant describe tenant-1 -o yaml > tenant.yaml\n $ vi tenant.yaml\n $ # either via stdin\n $ cat tenant.yaml | metalctl tenant create -f -\n $ # or via file\n $ metalctl tenant create -f tenant.yaml\n \n the file can also contain multiple documents and perform a bulk operation.\n \t\n -h, --help help for create\n --id string id of the tenant, max 10 characters.\n --ip-quota int32 ip quota\n --labels strings add initial label, can be given multiple times to add multiple labels, e.g. --label=foo --label=bar\n --machine-quota int32 machine quota\n --name string name of the tenant, max 10 characters.\n --skip-security-prompts skips security prompt for bulk operations\n --timestamps when used with --file (bulk operation): prints timestamps in-between the operations","category":"page"},{"location":"external/metalctl/docs/metalctl_tenant_create/#Options-inherited-from-parent-commands","page":"metalctl tenant create","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_tenant_create/","page":"metalctl tenant create","title":"metalctl tenant create","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_tenant_create/#SEE-ALSO","page":"metalctl tenant create","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_tenant_create/","page":"metalctl tenant create","title":"metalctl tenant create","text":"metalctl tenant\t - manage tenant entities","category":"page"},{"location":"development/contributing/#Contributing","page":"Contributing","title":"Contributing","text":"","category":"section"},{"location":"development/contributing/","page":"Contributing","title":"Contributing","text":"This document describes the way we want to contribute code to the projects of metal-stack, which are hosted on github.com/metal-stack.","category":"page"},{"location":"development/contributing/","page":"Contributing","title":"Contributing","text":"The document is meant to be understood as a general guideline for contributions, but not as burden to be placed on a developer. Use your best judgment when contributing code. Try to be as clean and precise as possible when writing code and try to make your code as maintainable and understandable as possible for other people.","category":"page"},{"location":"development/contributing/","page":"Contributing","title":"Contributing","text":"Even if it should go without saying, we live an open culture of discussion, in which everybody is welcome to participate. We treat every contribution with respect and objectiveness with the general aim to write software of quality.","category":"page"},{"location":"development/contributing/","page":"Contributing","title":"Contributing","text":"If you want, feel free to propose changes to this document in a pull request.","category":"page"},{"location":"development/contributing/","page":"Contributing","title":"Contributing","text":"Pages = [\"contributing.md\"]\nDepth = 5","category":"page"},{"location":"development/contributing/#How-Can-I-Contribute?","page":"Contributing","title":"How Can I Contribute?","text":"","category":"section"},{"location":"development/contributing/","page":"Contributing","title":"Contributing","text":"Open a Github issue in the project you would like to contribute. Within the issue, your idea can be discussed. It is also possible to directly create a pull request when the set of changes is relatively small.","category":"page"},{"location":"development/contributing/#Pull-Requests","page":"Contributing","title":"Pull Requests","text":"","category":"section"},{"location":"development/contributing/","page":"Contributing","title":"Contributing","text":"The process described here has several goals:","category":"page"},{"location":"development/contributing/","page":"Contributing","title":"Contributing","text":"Maintain quality\nEnable a sustainable system to review contributions\nEnable documented and reproducible addition of contributions","category":"page"},{"location":"development/contributing/","page":"Contributing","title":"Contributing","text":"Create a meaningful issue describing the WHY? of your contribution\nCreate a repository fork within the context of that issue.\nCreate a Draft Pull Request to the master branch of the target repository.\nDevelop, document and test your contribution (try not to solve more than one issue in a single pull request)\nAsk for merging your contribution by removing the draft marker\nIf code owners are defined, try to assign the request to a code owner","category":"page"},{"location":"development/contributing/#General-Objectives","page":"Contributing","title":"General Objectives","text":"","category":"section"},{"location":"development/contributing/","page":"Contributing","title":"Contributing","text":"This section contains language-agnostic topics that all metal-stack projects are trying to follow.","category":"page"},{"location":"development/contributing/#Code-Ownership","page":"Contributing","title":"Code Ownership","text":"","category":"section"},{"location":"development/contributing/","page":"Contributing","title":"Contributing","text":"The code base is owned by the entire team and every member is allowed to contribute changes to any of the projects. This is considered as collective code ownership[1].","category":"page"},{"location":"development/contributing/","page":"Contributing","title":"Contributing","text":"As a matter of fact, there are persons in a project, which already have experience with the sources. These are defined directly in the repository's CODEOWNERS file. If you want to merge changes into the master branch, it is advisable to include code owners into the proecess of discussion and merging.","category":"page"},{"location":"development/contributing/#Microservices","page":"Contributing","title":"Microservices","text":"","category":"section"},{"location":"development/contributing/","page":"Contributing","title":"Contributing","text":"One major ambition of metal-stack is to follow the idea of microservices. This way, we want to achieve that we can","category":"page"},{"location":"development/contributing/","page":"Contributing","title":"Contributing","text":"adapt to changes faster than with monolithic architectures,\nbe free of restrictions due to certain choices of technology,\nleverage powerful traits of cloud infrastructures (e.g. high-scalability, high-availability, ...).","category":"page"},{"location":"development/contributing/#Programming-Languages","page":"Contributing","title":"Programming Languages","text":"","category":"section"},{"location":"development/contributing/","page":"Contributing","title":"Contributing","text":"We are generally open to write code in any language that fits best to the function of the software. However, we encourage golang to be the main language of metal-stack as we think that it makes development faster when not establishing too many different languages in our architecture. Reason for this is that we are striving for consistent behavior of the microservices, similar to what has been described for the Twelve-Factor App (see 12 Factor). We help enforcing unified behavior by allowing a small layer of shared code for every programming language. We will refer to this shared code as \"libraries\" for the rest of this document.","category":"page"},{"location":"development/contributing/#Artifacts","page":"Contributing","title":"Artifacts","text":"","category":"section"},{"location":"development/contributing/","page":"Contributing","title":"Contributing","text":"Artifacts are always produced by a CI process (Github Actions).","category":"page"},{"location":"development/contributing/","page":"Contributing","title":"Contributing","text":"Docker images are published on the Github Container Registry of the metal-stack organization.","category":"page"},{"location":"development/contributing/","page":"Contributing","title":"Contributing","text":"Binary artifacts or OS images can be uploaded to images.metal-stack.io if necessary.","category":"page"},{"location":"development/contributing/","page":"Contributing","title":"Contributing","text":"When building Docker images, please consider our build tool docker-make or the specific docker-make action respectively.","category":"page"},{"location":"development/contributing/#APIs","page":"Contributing","title":"APIs","text":"","category":"section"},{"location":"development/contributing/","page":"Contributing","title":"Contributing","text":"We are currently making use of Swagger when we exposing traditional REST APIs for end-users. This helps us with being technology-agnostic as we can generate clients in almost any language using go-swagger. Swagger additionally simplifies the documentation of our APIs.","category":"page"},{"location":"development/contributing/","page":"Contributing","title":"Contributing","text":"Most APIs though are not required to be user-facing but are of technical nature. These are preferred to be implemented using grpc.","category":"page"},{"location":"development/contributing/#Versioning","page":"Contributing","title":"Versioning","text":"","category":"section"},{"location":"development/contributing/","page":"Contributing","title":"Contributing","text":"Artifacts are versioned by tagging the respective repository with a tag starting with the letter v. After the letter, there stands a valid semantic version.","category":"page"},{"location":"development/contributing/#Documentation","page":"Contributing","title":"Documentation","text":"","category":"section"},{"location":"development/contributing/","page":"Contributing","title":"Contributing","text":"In order to make it easier for others to understand a project, we document general information and usage instructions in a README.md in any project.","category":"page"},{"location":"development/contributing/","page":"Contributing","title":"Contributing","text":"In addition to that, we document a microservice in the docs repository. The documentation should contain the reasoning why this service exists and why it was being implemented the way it was being implemented. The aim of this procedure is to reduce the time for contributors to comprehend architectural decisions that were made during the process of writing the software and to clarify the general purpose of this service in the entire context of the software.","category":"page"},{"location":"development/contributing/#Guidelines","page":"Contributing","title":"Guidelines","text":"","category":"section"},{"location":"development/contributing/","page":"Contributing","title":"Contributing","text":"This chapter describes general guidelines on how to develop and contribute code for a certain programming language.","category":"page"},{"location":"development/contributing/#Golang","page":"Contributing","title":"Golang","text":"","category":"section"},{"location":"development/contributing/","page":"Contributing","title":"Contributing","text":"Development follows the official guide to:","category":"page"},{"location":"development/contributing/","page":"Contributing","title":"Contributing","text":"Write clear, idiomatic Go code[2]\nLearn from mistakes that must not be repeated[3]\nApply appropriate names to your artifacts:\nhttps://go.dev/talks/2014/names.slide\nhttps://go.dev/blog/package-names\nhttps://go.dev/doc/effective_go#names\nEnable others to understand the reasoning of non-trivial code sequences by applying a meaningful documentation.","category":"page"},{"location":"development/contributing/#Development-Decisions","page":"Contributing","title":"Development Decisions","text":"","category":"section"},{"location":"development/contributing/","page":"Contributing","title":"Contributing","text":"Dependency Management by using Go modules\nBuild and Test Automation by using GNU Make.\nEnd-user APIs should consider using go-swagger and Go-Restful Technical APIs should consider using grpc","category":"page"},{"location":"development/contributing/#Libraries","page":"Contributing","title":"Libraries","text":"","category":"section"},{"location":"development/contributing/","page":"Contributing","title":"Contributing","text":"metal-stack maintains several libraries that you should utilize in your project in order unify common behavior. Some of these projects are:","category":"page"},{"location":"development/contributing/","page":"Contributing","title":"Contributing","text":"metal-go\nmetal-lib","category":"page"},{"location":"development/contributing/#Error-Handling-with-Generated-Swagger-Clients","page":"Contributing","title":"Error Handling with Generated Swagger Clients","text":"","category":"section"},{"location":"development/contributing/","page":"Contributing","title":"Contributing","text":"From the server-side you should ensure that you are returning the common error json struct in case of an error as defined in the metal-lib/httperrors. Ensure you are using go-restful >= v2.9.1 and go-restful-openapi >= v0.13.1 (allows default responses with error codes other than 200).","category":"page"},{"location":"development/contributing/#Documentation-2","page":"Contributing","title":"Documentation","text":"","category":"section"},{"location":"development/contributing/","page":"Contributing","title":"Contributing","text":"We want to share knowledge and keep things simple. If things cannot kept simple we want enable everybody to understand them by:","category":"page"},{"location":"development/contributing/","page":"Contributing","title":"Contributing","text":"Document in short sentences[4].\nDo not explain the HOW (this is already documented by your code and documenting the obvious is considered a defect).\nExplain the WHY. Add a \"to\" in your documentation line to force yourself to explain the reasonning (e.g. \" to \").","category":"page"},{"location":"development/contributing/#Python","page":"Contributing","title":"Python","text":"","category":"section"},{"location":"development/contributing/","page":"Contributing","title":"Contributing","text":"Development follows the official guide to:","category":"page"},{"location":"development/contributing/","page":"Contributing","title":"Contributing","text":"Style Guide for Python Code (PEP 8)[5]\nThe use of an IDE like PyCharm helps to write compliant code easily\nConsider setuptools for packaging\nIf you want to add a Python microservice to the mix, consider pyinstaller on Alpine to achieve small image sizes","category":"page"},{"location":"development/contributing/","page":"Contributing","title":"Contributing","text":"[1]: https://martinfowler.com/bliki/CodeOwnership.html","category":"page"},{"location":"development/contributing/","page":"Contributing","title":"Contributing","text":"[2]: https://go.dev/doc/effective_go","category":"page"},{"location":"development/contributing/","page":"Contributing","title":"Contributing","text":"[3]: https://github.com/golang/go/wiki/CodeReviewComments","category":"page"},{"location":"development/contributing/","page":"Contributing","title":"Contributing","text":"[4]: https://github.com/golang/go/wiki/CodeReviewComments#comment-sentences","category":"page"},{"location":"development/contributing/","page":"Contributing","title":"Contributing","text":"[5]: https://www.python.org/dev/peps/pep-0008/","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_lock/#metalctl-machine-lock","page":"metalctl machine lock","title":"metalctl machine lock","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_lock/","page":"metalctl machine lock","title":"metalctl machine lock","text":"lock a machine","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_lock/#Synopsis","page":"metalctl machine lock","title":"Synopsis","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_lock/","page":"metalctl machine lock","title":"metalctl machine lock","text":"when a machine is locked, it can not be destroyed, to destroy a machine you must first remove the lock from that machine with –remove","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_lock/","page":"metalctl machine lock","title":"metalctl machine lock","text":"metalctl machine lock [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_lock/#Options","page":"metalctl machine lock","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_lock/","page":"metalctl machine lock","title":"metalctl machine lock","text":" -d, --description string description of the reason for the lock.\n -h, --help help for lock\n -r, --remove remove the lock.","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_lock/#Options-inherited-from-parent-commands","page":"metalctl machine lock","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_lock/","page":"metalctl machine lock","title":"metalctl machine lock","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_lock/#SEE-ALSO","page":"metalctl machine lock","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_lock/","page":"metalctl machine lock","title":"metalctl machine lock","text":"metalctl machine\t - manage machine entities","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_issues_list/#metalctl-machine-issues-list","page":"metalctl machine issues list","title":"metalctl machine issues list","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_issues_list/","page":"metalctl machine issues list","title":"metalctl machine issues list","text":"list all machine issues that the metal-api can evaluate","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_issues_list/","page":"metalctl machine issues list","title":"metalctl machine issues list","text":"metalctl machine issues list [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_issues_list/#Options","page":"metalctl machine issues list","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_issues_list/","page":"metalctl machine issues list","title":"metalctl machine issues list","text":" -h, --help help for list\n --sort-by strings sort by (comma separated) column(s), sort direction can be changed by appending :asc or :desc behind the column identifier. possible values: id|severity","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_issues_list/#Options-inherited-from-parent-commands","page":"metalctl machine issues list","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_issues_list/","page":"metalctl machine issues list","title":"metalctl machine issues list","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_issues_list/#SEE-ALSO","page":"metalctl machine issues list","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_issues_list/","page":"metalctl machine issues list","title":"metalctl machine issues list","text":"metalctl machine issues\t - display machines which are in a potential bad state","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_delete/#metalctl-machine-delete","page":"metalctl machine delete","title":"metalctl machine delete","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_delete/","page":"metalctl machine delete","title":"metalctl machine delete","text":"deletes the machine","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_delete/#Synopsis","page":"metalctl machine delete","title":"Synopsis","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_delete/","page":"metalctl machine delete","title":"metalctl machine delete","text":"delete a machine and destroy all data stored on the local disks. Once destroyed it is back for usage by other projects. A destroyed machine can not restored anymore","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_delete/","page":"metalctl machine delete","title":"metalctl machine delete","text":"metalctl machine delete [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_delete/#Options","page":"metalctl machine delete","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_delete/","page":"metalctl machine delete","title":"metalctl machine delete","text":" --bulk-output when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.\n -f, --file string filename of the create or update request in yaml format, or - for stdin.\n \n Example:\n $ metalctl machine describe machine-1 -o yaml > machine.yaml\n $ vi machine.yaml\n $ # either via stdin\n $ cat machine.yaml | metalctl machine delete -f -\n $ # or via file\n $ metalctl machine delete -f machine.yaml\n \n the file can also contain multiple documents and perform a bulk operation.\n \t\n -h, --help help for delete\n --remove-from-database remove given machine from the database, is only required for maintenance reasons [optional] (admin only).\n --skip-security-prompts skips security prompt for bulk operations\n --timestamps when used with --file (bulk operation): prints timestamps in-between the operations","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_delete/#Options-inherited-from-parent-commands","page":"metalctl machine delete","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_delete/","page":"metalctl machine delete","title":"metalctl machine delete","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_delete/#SEE-ALSO","page":"metalctl machine delete","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_delete/","page":"metalctl machine delete","title":"metalctl machine delete","text":"metalctl machine\t - manage machine entities","category":"page"},{"location":"development/proposals/MEP1/README/#Distributed-Metal-Control-Plane","page":"Distributed Metal Control Plane","title":"Distributed Metal Control Plane","text":"","category":"section"},{"location":"development/proposals/MEP1/README/#Problem-Statement","page":"Distributed Metal Control Plane","title":"Problem Statement","text":"","category":"section"},{"location":"development/proposals/MEP1/README/","page":"Distributed Metal Control Plane","title":"Distributed Metal Control Plane","text":"We face the situation that we argue for running bare metal on premise because this way the customers can control where and how their software and data are processed and stored. On the other hand, we have currently decided that our metal-api control plane components run on a kubernetes cluster (in our case on a cluster provided by one of the available hyperscalers).","category":"page"},{"location":"development/proposals/MEP1/README/","page":"Distributed Metal Control Plane","title":"Distributed Metal Control Plane","text":"Running the control plane on Kubernetes has the following benefits:","category":"page"},{"location":"development/proposals/MEP1/README/","page":"Distributed Metal Control Plane","title":"Distributed Metal Control Plane","text":"Ease of deployment\nGet most, if not all, of the required infrastructure services like (probably incomplete):\nIPs\nDNS\nL7-Loadbalancing\nStorage\nS3 Backup\nHigh Availability","category":"page"},{"location":"development/proposals/MEP1/README/","page":"Distributed Metal Control Plane","title":"Distributed Metal Control Plane","text":"Using a kubernetes as a service offering from one of the hyperscalers, enables us to focus on using kubernetes instead of maintaining it as well.","category":"page"},{"location":"development/proposals/MEP1/README/#Goal","page":"Distributed Metal Control Plane","title":"Goal","text":"","category":"section"},{"location":"development/proposals/MEP1/README/","page":"Distributed Metal Control Plane","title":"Distributed Metal Control Plane","text":"It would be much saner if metal-stack has no, or only minimal dependencies to external services. Imagine a metal-stack deployment in a plant, it would be optimal if we only have to deliver a single rack with servers and networking gear installed and wired, plug that rack to the power supply and a internet uplink and its ready to go.","category":"page"},{"location":"development/proposals/MEP1/README/","page":"Distributed Metal Control Plane","title":"Distributed Metal Control Plane","text":"Have a second plant which you want to be part of all your plants? Just tell both that they are part of something bigger and metal-api knows of two partitions.","category":"page"},{"location":"development/proposals/MEP1/README/#Possible-Solutions","page":"Distributed Metal Control Plane","title":"Possible Solutions","text":"","category":"section"},{"location":"development/proposals/MEP1/README/","page":"Distributed Metal Control Plane","title":"Distributed Metal Control Plane","text":"We can think of two different solutions to this vision:","category":"page"},{"location":"development/proposals/MEP1/README/","page":"Distributed Metal Control Plane","title":"Distributed Metal Control Plane","text":"Keep the central control plane approach and require some sort of kubernetes deployment accessible from the internet. This has the downside that the user must, provide a managed kubernetes deployment in his own datacenter or uses a hyperscaler. Still not optimal.\nInstall the metal-api and all its dependencies in every partition, replicate or shard the databases to every connected partition, make them know each other. Connect the partitions over the internet with some sort of vpn to make the services visible to each other.","category":"page"},{"location":"development/proposals/MEP1/README/","page":"Distributed Metal Control Plane","title":"Distributed Metal Control Plane","text":"As we can see, the first approach does not really address the problem, therefore i will describe solution #2 in more details.","category":"page"},{"location":"development/proposals/MEP1/README/#Central/Current-setup","page":"Distributed Metal Control Plane","title":"Central/Current setup","text":"","category":"section"},{"location":"development/proposals/MEP1/README/#Stateful-services","page":"Distributed Metal Control Plane","title":"Stateful services","text":"","category":"section"},{"location":"development/proposals/MEP1/README/","page":"Distributed Metal Control Plane","title":"Distributed Metal Control Plane","text":"Every distributed system suffer from handling state in a scalable, fast and correct way. To start how to cope with the state, we first must identify which state can be seen as partition local only and which state must be synchronous for read, and synchronous for writes across partitions.","category":"page"},{"location":"development/proposals/MEP1/README/","page":"Distributed Metal Control Plane","title":"Distributed Metal Control Plane","text":"Affected states:","category":"page"},{"location":"development/proposals/MEP1/README/","page":"Distributed Metal Control Plane","title":"Distributed Metal Control Plane","text":"masterdata: e.g. tenant and project must be present in every partition, but these are entities which are read often but updates are rare. A write can therefore be visible with a decent delay in a distinct partition with no consequences.\nipam: the prefixes and ip´s allocated from machines. These entities are also read often and rare updates. But we must differentiate between dirty reads for different types. A machine network is partition local, ips acquired from such a network must by synchronous in the same partition. Ips acquired from global networks such as internet must by synchronous for all partitions, as otherwise a internet ip could be acquired twice.\nvrf ids: they must only be unique in one partition\nimage and size configurations: read often, written seldom, so no high requirements on the storage of these entities.\nimages: os images are already replicated from a central s3 storage to a per partition s3 service. metal-hammer kernel and initrd are small and pull always from the central s3, can be done similar to os images.\nmachine and machine allocation: must be only synchronous in the partition\nswitch: must be only synchronous in the partition\nnsq messages: do not need to cross partition boundaries. No need to keep the messages persistent, even the opposite is true, we don't want to have the messages persist for a longer period.","category":"page"},{"location":"development/proposals/MEP1/README/","page":"Distributed Metal Control Plane","title":"Distributed Metal Control Plane","text":"Now we can see that the most critical state to held and synchronize are the IPAM data, because these entities must be guaranteed to be synchronously updated, while being updated frequently.","category":"page"},{"location":"development/proposals/MEP1/README/","page":"Distributed Metal Control Plane","title":"Distributed Metal Control Plane","text":"Datastores:","category":"page"},{"location":"development/proposals/MEP1/README/","page":"Distributed Metal Control Plane","title":"Distributed Metal Control Plane","text":"We use three different types of datastores to persist the states of the metal application.","category":"page"},{"location":"development/proposals/MEP1/README/","page":"Distributed Metal Control Plane","title":"Distributed Metal Control Plane","text":"rethinkdb is the main datastore for almost all entities managed by metal-api\npostgresql is used for masterdata and ipam data.\nnsq uses disk and memory tho store the messages.","category":"page"},{"location":"development/proposals/MEP1/README/#Stateless-services","page":"Distributed Metal Control Plane","title":"Stateless services","text":"","category":"section"},{"location":"development/proposals/MEP1/README/","page":"Distributed Metal Control Plane","title":"Distributed Metal Control Plane","text":"These are the easy part, all of our services which are stateless can be scaled up and down without any impact on functionality. Even the stateful services like masterdata and metal-api rely fully on the underlying datastore and can therefore also be scaled up and down to meet scalability requirements.","category":"page"},{"location":"development/proposals/MEP1/README/","page":"Distributed Metal Control Plane","title":"Distributed Metal Control Plane","text":"Albeit, most of these services need to be placed behind a loadbalancer which does the L4/L7 balancing across the started/available replicas of the service for the clients talking to it. This is actually provided by kubernetes with either service type loadbalancer or type clusterip.","category":"page"},{"location":"development/proposals/MEP1/README/","page":"Distributed Metal Control Plane","title":"Distributed Metal Control Plane","text":"One exception is the metal-console service which must have the partition in it´s dns name now, because there is no direct network connectivity between the management networks of the partitions. See \"Network Setup)","category":"page"},{"location":"development/proposals/MEP1/README/#Distributed-setup","page":"Distributed Metal Control Plane","title":"Distributed setup","text":"","category":"section"},{"location":"development/proposals/MEP1/README/#State","page":"Distributed Metal Control Plane","title":"State","text":"","category":"section"},{"location":"development/proposals/MEP1/README/","page":"Distributed Metal Control Plane","title":"Distributed Metal Control Plane","text":"In order to replicate certain data which must be available across all partitions we can use on of the existing open source databases which enable such kind of setup. There are a few available out there, the following incomplete list will highlight the pro´s and cons of each.","category":"page"},{"location":"development/proposals/MEP1/README/","page":"Distributed Metal Control Plane","title":"Distributed Metal Control Plane","text":"RethinkDB\nWe already store most of our data in RethinkDB and it gives already the ability to synchronize the data in a distributed manner with different guarantees for consistency and latency. This is described here: Scaling, Sharding and replication. But because rethinkdb has a rough history and unsure future with the last release took more than a year, we in the team already thought that we eventually must move away from rethinkdb in the future.\nPostgresql\nPostgres does not have a multi datacenter with replication in both directions, it just can make the remote instance store the same data.\nCockroachDB\nIs a Postgresql compatible database enginge on the wire. CockroachDB gives you both, ACID and geo replication with writes allowed from all connected members. It is even possible to configure Follow the Workload and Geo Partitioning and Replication.","category":"page"},{"location":"development/proposals/MEP1/README/","page":"Distributed Metal Control Plane","title":"Distributed Metal Control Plane","text":"If we migrate all metal-api entities to be stored the same way we store masterdata, we could use cockroachdb to store all metal entities in one ore more databases spread across all partitions and still ensure consistency and high availability.","category":"page"},{"location":"development/proposals/MEP1/README/","page":"Distributed Metal Control Plane","title":"Distributed Metal Control Plane","text":"A simple setup how this would look like is shown here.","category":"page"},{"location":"development/proposals/MEP1/README/","page":"Distributed Metal Control Plane","title":"Distributed Metal Control Plane","text":"(Image: Simple CockroachDB setup)","category":"page"},{"location":"development/proposals/MEP1/README/","page":"Distributed Metal Control Plane","title":"Distributed Metal Control Plane","text":"go-ipam was modified in a example PR here: PR 17","category":"page"},{"location":"development/proposals/MEP1/README/#API-Access","page":"Distributed Metal Control Plane","title":"API Access","text":"","category":"section"},{"location":"development/proposals/MEP1/README/","page":"Distributed Metal Control Plane","title":"Distributed Metal Control Plane","text":"In order to make the metal-api accessible for api users like cloud-api or metalctl as easy at it is today, some effort has to be taken. One possible approach would be to use a external loadbalancer which spread the requests evenly to all metal-api endpoints in all partitions. Because all data are accessible from all partitions, a api request going to partition A with a request to create a machine in partition B, will still work. If on the other hand partition B is not in a connected state because the interconnection between both partitions is broken, then of course the request will fail.","category":"page"},{"location":"development/proposals/MEP1/README/","page":"Distributed Metal Control Plane","title":"Distributed Metal Control Plane","text":"IMPORTANT The NSQ Message to inform metal-core must end in the correct partition","category":"page"},{"location":"development/proposals/MEP1/README/","page":"Distributed Metal Control Plane","title":"Distributed Metal Control Plane","text":"To provide such a external loadbalancer we have several opportunities:","category":"page"},{"location":"development/proposals/MEP1/README/","page":"Distributed Metal Control Plane","title":"Distributed Metal Control Plane","text":"Cloudflare or comparable CDN service.\nBGP Anycast from every partition","category":"page"},{"location":"development/proposals/MEP1/README/","page":"Distributed Metal Control Plane","title":"Distributed Metal Control Plane","text":"Another setup would place a small gateway behind the metal-api address, which forwards to the metal-api in the partition where the request must be executed. This gateway, metal-api-router must inspect the payload, extract the desired partition, and forward the request without any modifications to the metal-api endpoint in this partition. This can be done for all requests, or if we want to optimize, only for write accesses.","category":"page"},{"location":"development/proposals/MEP1/README/#Network-setup","page":"Distributed Metal Control Plane","title":"Network setup","text":"","category":"section"},{"location":"development/proposals/MEP1/README/","page":"Distributed Metal Control Plane","title":"Distributed Metal Control Plane","text":"In order to have the impact to the overall security concept as minimal as possible i would not modify the current network setup. The only modifications which has to be made are:","category":"page"},{"location":"development/proposals/MEP1/README/","page":"Distributed Metal Control Plane","title":"Distributed Metal Control Plane","text":"Allow https ingress traffic to all metal-api instances.\nAllow ssh ingress traffic to all metal-console instances.\nAllow CockroachDB Replication between all partitions.\nNo NSQ traffic from outside required anymore, except we cant solve the topic above.","category":"page"},{"location":"development/proposals/MEP1/README/","page":"Distributed Metal Control Plane","title":"Distributed Metal Control Plane","text":"A simple setup how this would look like is shown here, this does not work though because of the forementioned NSQ issue.","category":"page"},{"location":"development/proposals/MEP1/README/","page":"Distributed Metal Control Plane","title":"Distributed Metal Control Plane","text":"(Image: API and Console Access)","category":"page"},{"location":"development/proposals/MEP1/README/","page":"Distributed Metal Control Plane","title":"Distributed Metal Control Plane","text":"Therefore we need the metal-api-router:","category":"page"},{"location":"development/proposals/MEP1/README/","page":"Distributed Metal Control Plane","title":"Distributed Metal Control Plane","text":"(Image: Working API and Console Access)","category":"page"},{"location":"development/proposals/MEP1/README/#Deployment","page":"Distributed Metal Control Plane","title":"Deployment","text":"","category":"section"},{"location":"development/proposals/MEP1/README/","page":"Distributed Metal Control Plane","title":"Distributed Metal Control Plane","text":"The deployment of our components will substantially differ in a partition compared to a the deployment we have actually. Deploying it in kubernetes in the partition would be very difficult to achieve because we have no sane way to deploy kubernetes on physical machines without a underlying API. I would therefore suggest to deploy our components in the same way we do that for the services running on the management server. Use systemd to start docker containers.","category":"page"},{"location":"development/proposals/MEP1/README/","page":"Distributed Metal Control Plane","title":"Distributed Metal Control Plane","text":"(Image: Deployment)","category":"page"},{"location":"development/proposals/MEP12/partitioning/","page":"Multi-Partition-Layout","title":"Multi-Partition-Layout","text":"","category":"page"},{"location":"development/proposals/MEP12/partitioning/","page":"Multi-Partition-Layout","title":"Multi-Partition-Layout","text":"marp: true theme: metal-stack paginate: true footer: Gerrit Schwerthelm – x-cellent technologies GmbH — metal-stack Training backgroundImage: url(\"https://metal-stack.io/images/shape/banner.png\") –- ","category":"page"},{"location":"development/proposals/MEP12/partitioning/","page":"Multi-Partition-Layout","title":"Multi-Partition-Layout","text":"(Image: h:200px)","category":"page"},{"location":"development/proposals/MEP12/partitioning/","page":"Multi-Partition-Layout","title":"Multi-Partition-Layout","text":"","category":"page"},{"location":"development/proposals/MEP12/partitioning/","page":"Multi-Partition-Layout","title":"Multi-Partition-Layout","text":"","category":"page"},{"location":"development/proposals/MEP12/partitioning/#Multi-Partition-Layout","page":"Multi-Partition-Layout","title":"Multi-Partition-Layout","text":"","category":"section"},{"location":"development/proposals/MEP12/partitioning/","page":"Multi-Partition-Layout","title":"Multi-Partition-Layout","text":"","category":"page"},{"location":"development/proposals/MEP12/partitioning/","page":"Multi-Partition-Layout","title":"Multi-Partition-Layout","text":" (Image: bg contain)","category":"page"},{"location":"development/proposals/MEP12/partitioning/","page":"Multi-Partition-Layout","title":"Multi-Partition-Layout","text":"","category":"page"},{"location":"development/proposals/MEP12/partitioning/","page":"Multi-Partition-Layout","title":"Multi-Partition-Layout","text":" (Image: bg contain)","category":"page"},{"location":"development/proposals/MEP12/partitioning/","page":"Multi-Partition-Layout","title":"Multi-Partition-Layout","text":"","category":"page"},{"location":"development/proposals/MEP12/partitioning/","page":"Multi-Partition-Layout","title":"Multi-Partition-Layout","text":"","category":"page"},{"location":"development/proposals/MEP12/partitioning/#Multi-Partition-Layout-Properties","page":"Multi-Partition-Layout","title":"Multi-Partition-Layout Properties","text":"","category":"section"},{"location":"development/proposals/MEP12/partitioning/","page":"Multi-Partition-Layout","title":"Multi-Partition-Layout","text":"Fully independent locations with own storage and own node networks\nClusters can only be created independent in every location\nFailover mechanism for deployed applications requires duplicated deployments, which can serve independently\nFailover through BGP\nIf cluster nodes are spread across partitions (not implemented yet), nodes will not be able to reach each other\nWould require an overlay network for inter-node-communication","category":"page"},{"location":"development/proposals/MEP12/partitioning/","page":"Multi-Partition-Layout","title":"Multi-Partition-Layout","text":"","category":"page"},{"location":"development/proposals/MEP12/partitioning/","page":"Multi-Partition-Layout","title":"Multi-Partition-Layout","text":"","category":"page"},{"location":"development/proposals/MEP12/partitioning/#Single-Partition-Layout","page":"Multi-Partition-Layout","title":"Single-Partition-Layout","text":"","category":"section"},{"location":"development/proposals/MEP12/partitioning/","page":"Multi-Partition-Layout","title":"Multi-Partition-Layout","text":"","category":"page"},{"location":"development/proposals/MEP12/partitioning/","page":"Multi-Partition-Layout","title":"Multi-Partition-Layout","text":" (Image: bg contain)","category":"page"},{"location":"development/proposals/MEP12/partitioning/","page":"Multi-Partition-Layout","title":"Multi-Partition-Layout","text":"","category":"page"},{"location":"development/proposals/MEP12/partitioning/","page":"Multi-Partition-Layout","title":"Multi-Partition-Layout","text":"","category":"page"},{"location":"development/proposals/MEP12/partitioning/#Single-Partition-Layout-Properties","page":"Multi-Partition-Layout","title":"Single-Partition-Layout Properties","text":"","category":"section"},{"location":"development/proposals/MEP12/partitioning/","page":"Multi-Partition-Layout","title":"Multi-Partition-Layout","text":"Multiple groups of racks at multiple locations but connected to same CLOS topology\nAll racks can connect to the same storage network\nNodes in private networks can communicate\nWhen creating a cluster, nodes will be randomly spread across the racks\nPossible improvement of this situation, see MEP-12: Rack Spreading","category":"page"},{"location":"development/proposals/MEP12/partitioning/","page":"Multi-Partition-Layout","title":"Multi-Partition-Layout","text":"","category":"page"},{"location":"development/proposals/MEP12/partitioning/#MEP-12:-Rack-Spreading","page":"Multi-Partition-Layout","title":"MEP-12: Rack Spreading","text":"","category":"section"},{"location":"development/proposals/MEP12/partitioning/","page":"Multi-Partition-Layout","title":"Multi-Partition-Layout","text":"Instead of selecting a machine from a machine pool randomly\nGet all existing machines in the same project and count to which rack they belong\nPlace machine on the rack with the least amount of machines already allocated\nBest effort only","category":"page"},{"location":"overview/hardware/#Hardware-Support","page":"Hardware Support","title":"Hardware Support","text":"","category":"section"},{"location":"overview/hardware/","page":"Hardware Support","title":"Hardware Support","text":"In order to keep the automation and maintenance overhead small, we strongly advise against building highly heterogeneous environments with metal-stack. Having a lot of different vendors and server models in your partitions will heavily increase the time and effort for introducing metal-stack in your infrastructure. From experience we can tell that the interfaces for automating hardware provisioning are usually inconsistent between vendors and even between server models of the same vendor. Therefore, we encourage adopters to start off with only a small amount of machine types. If you want to be on the safe side, you should consider buying the hardware that we officially support.","category":"page"},{"location":"overview/hardware/","page":"Hardware Support","title":"Hardware Support","text":"We came up with a repository called go-hal, which includes the interface required for metal-stack to support a machine vendor. If you plan to implement support for new vendors, please check out this repository and contribute back your efforts in order to make the community benefit from extended vendor support as well.","category":"page"},{"location":"overview/hardware/#Servers","page":"Hardware Support","title":"Servers","text":"","category":"section"},{"location":"overview/hardware/","page":"Hardware Support","title":"Hardware Support","text":"The following server types are officially supported and verified by the metal-stack project:","category":"page"},{"location":"overview/hardware/","page":"Hardware Support","title":"Hardware Support","text":"Vendor Series Model Board Type Status\nSupermicro Big-Twin SYS-2029BT-HNR X11DPT-B stable\nSupermicro Big-Twin SYS-220BT-HNTR X12DPT-B6 stable\nSupermicro SuperServer SSG-5019D8-TR12P X11SDV-8C-TP8F stable\nSupermicro SuperServer 2029UZ-TN20R25M X11DPU stable\nSupermicro SuperServer SYS-621C-TN12R X13DDW-A stable\nSupermicro Microcloud 5039MD8-H8TNR X11SDD-8C-F stable\nLenovo ThinkSystem SD530 alpha","category":"page"},{"location":"overview/hardware/","page":"Hardware Support","title":"Hardware Support","text":"Other server series and models might work but were not reported to us.","category":"page"},{"location":"overview/hardware/#GPUs","page":"Hardware Support","title":"GPUs","text":"","category":"section"},{"location":"overview/hardware/","page":"Hardware Support","title":"Hardware Support","text":"The following GPU types are officially supported and verified by the metal-stack project:","category":"page"},{"location":"overview/hardware/","page":"Hardware Support","title":"Hardware Support","text":"Vendor Model Status\nNVIDIA RTX 6000 stable","category":"page"},{"location":"overview/hardware/","page":"Hardware Support","title":"Hardware Support","text":"Other GPU models might work but were not reported to us. For a detailed description howto use GPU support in a kubernetes cluster please check this documentation","category":"page"},{"location":"overview/hardware/#Switches","page":"Hardware Support","title":"Switches","text":"","category":"section"},{"location":"overview/hardware/","page":"Hardware Support","title":"Hardware Support","text":"The following switch types are officially supported and verified by the metal-stack project:","category":"page"},{"location":"overview/hardware/","page":"Hardware Support","title":"Hardware Support","text":"Vendor Series Model OS Status\nEdge-Core AS7700 Series AS7712-32X Cumulus 3.7.13 stable\nEdge-Core AS7700 Series AS7726-32X Cumulus 4.1.1 stable\nEdge-Core AS7700 Series AS7712-32X Edgecore SONiC stable\nEdge-Core AS7700 Series AS7726-32X Edgecore SONiC stable","category":"page"},{"location":"overview/hardware/","page":"Hardware Support","title":"Hardware Support","text":"Other switch series and models might work but were not reported to us.","category":"page"},{"location":"overview/hardware/","page":"Hardware Support","title":"Hardware Support","text":"warning: Warning\nOn our switches we run SONiC. The metal-core writes network configuration specifically implemented for this operating system. Please also consider running SONiC on your switches if you do not want to run into any issues with networking.Our previous support for Cumulus Linux will come to an end.Of course, contributions for supporting other switch vendors and operating systems are highly appreciated.","category":"page"},{"location":"overview/hardware/#Portable-metal-stack-Setup-DIY","page":"Hardware Support","title":"Portable metal-stack Setup DIY","text":"","category":"section"},{"location":"overview/hardware/","page":"Hardware Support","title":"Hardware Support","text":"A minimal physical hardware setup may contain at least the following components:","category":"page"},{"location":"overview/hardware/","page":"Hardware Support","title":"Hardware Support","text":"warning: Warning\nThis setup should work as the components are very similar to the currently supported ones but it's currently untested.","category":"page"},{"location":"overview/hardware/","page":"Hardware Support","title":"Hardware Support","text":"# Vendor Series Model Function\n2x Edge-Core AS5500 Series AS5512-54x (10G) Leaf / Exit switches\n1x Supermicro Microcloud SYS-5039MA16-H12RFT Usable machines\n1x Unifi Edgemax Edgerouter Pro Front router for internet and out-of-band access to servers and switches","category":"page"},{"location":"overview/hardware/","page":"Hardware Support","title":"Hardware Support","text":"Besides that, a 6HE rack with 1000mm depth and a portable LTE modem is needed.","category":"page"},{"location":"overview/hardware/","page":"Hardware Support","title":"Hardware Support","text":"This MVP will yield in 12 usable machines, one of them will be reserved as management server.","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_update-firmware_bmc/#metalctl-machine-update-firmware-bmc","page":"metalctl machine update-firmware bmc","title":"metalctl machine update-firmware bmc","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_update-firmware_bmc/","page":"metalctl machine update-firmware bmc","title":"metalctl machine update-firmware bmc","text":"update a machine BMC","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_update-firmware_bmc/#Synopsis","page":"metalctl machine update-firmware bmc","title":"Synopsis","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_update-firmware_bmc/","page":"metalctl machine update-firmware bmc","title":"metalctl machine update-firmware bmc","text":"the machine BMC will be updated to given revision. If revision flag is not specified an update plan will be printed instead.","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_update-firmware_bmc/","page":"metalctl machine update-firmware bmc","title":"metalctl machine update-firmware bmc","text":"metalctl machine update-firmware bmc [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_update-firmware_bmc/#Options","page":"metalctl machine update-firmware bmc","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_update-firmware_bmc/","page":"metalctl machine update-firmware bmc","title":"metalctl machine update-firmware bmc","text":" --description string the reason why the BMC should be updated\n -h, --help help for bmc\n --revision string the BMC revision","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_update-firmware_bmc/#Options-inherited-from-parent-commands","page":"metalctl machine update-firmware bmc","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_update-firmware_bmc/","page":"metalctl machine update-firmware bmc","title":"metalctl machine update-firmware bmc","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_update-firmware_bmc/#SEE-ALSO","page":"metalctl machine update-firmware bmc","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_update-firmware_bmc/","page":"metalctl machine update-firmware bmc","title":"metalctl machine update-firmware bmc","text":"metalctl machine update-firmware\t - update a machine firmware","category":"page"},{"location":"external/metalctl/docs/metalctl_size_imageconstraint_try/#metalctl-size-imageconstraint-try","page":"metalctl size imageconstraint try","title":"metalctl size imageconstraint try","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_imageconstraint_try/","page":"metalctl size imageconstraint try","title":"metalctl size imageconstraint try","text":"try if size and image can be allocated","category":"page"},{"location":"external/metalctl/docs/metalctl_size_imageconstraint_try/","page":"metalctl size imageconstraint try","title":"metalctl size imageconstraint try","text":"metalctl size imageconstraint try [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_size_imageconstraint_try/#Options","page":"metalctl size imageconstraint try","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_imageconstraint_try/","page":"metalctl size imageconstraint try","title":"metalctl size imageconstraint try","text":" -h, --help help for try\n --image string image to check if allocaltion is possible\n --size string size to check if allocaltion is possible","category":"page"},{"location":"external/metalctl/docs/metalctl_size_imageconstraint_try/#Options-inherited-from-parent-commands","page":"metalctl size imageconstraint try","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_imageconstraint_try/","page":"metalctl size imageconstraint try","title":"metalctl size imageconstraint try","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_size_imageconstraint_try/#SEE-ALSO","page":"metalctl size imageconstraint try","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_imageconstraint_try/","page":"metalctl size imageconstraint try","title":"metalctl size imageconstraint try","text":"metalctl size imageconstraint\t - manage imageconstraint entities","category":"page"},{"location":"external/metalctl/docs/metalctl_audit/#metalctl-audit","page":"metalctl audit","title":"metalctl audit","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_audit/","page":"metalctl audit","title":"metalctl audit","text":"manage audit trace entities","category":"page"},{"location":"external/metalctl/docs/metalctl_audit/#Synopsis","page":"metalctl audit","title":"Synopsis","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_audit/","page":"metalctl audit","title":"metalctl audit","text":"show audit traces of the api. feature must be enabled on server-side.","category":"page"},{"location":"external/metalctl/docs/metalctl_audit/#Options","page":"metalctl audit","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_audit/","page":"metalctl audit","title":"metalctl audit","text":" -h, --help help for audit","category":"page"},{"location":"external/metalctl/docs/metalctl_audit/#Options-inherited-from-parent-commands","page":"metalctl audit","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_audit/","page":"metalctl audit","title":"metalctl audit","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_audit/#SEE-ALSO","page":"metalctl audit","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_audit/","page":"metalctl audit","title":"metalctl audit","text":"metalctl\t - a cli to manage entities in the metal-stack api\nmetalctl audit describe\t - describes the audit trace\nmetalctl audit list\t - list all audit traces","category":"page"},{"location":"external/metalctl/docs/metalctl_audit_list/#metalctl-audit-list","page":"metalctl audit list","title":"metalctl audit list","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_audit_list/","page":"metalctl audit list","title":"metalctl audit list","text":"list all audit traces","category":"page"},{"location":"external/metalctl/docs/metalctl_audit_list/","page":"metalctl audit list","title":"metalctl audit list","text":"metalctl audit list [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_audit_list/#Options","page":"metalctl audit list","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_audit_list/","page":"metalctl audit list","title":"metalctl audit list","text":" --component string component of the audit trace.\n --detail string detail of the audit trace. An HTTP method, unary or stream\n --error string error of the audit trace.\n --forwarded-for string forwarded for of the audit trace.\n --from string start of range of the audit traces. e.g. 1h, 10m, 2006-01-02 15:04:05 (default \"1h\")\n -h, --help help for list\n --limit int limit the number of audit traces. (default 100)\n --path string api path of the audit trace.\n --phase string phase of the audit trace. One of [request, response, single, error, opened, closed]\n -q, --query string filters audit trace body payloads for the given text.\n --remote-addr string remote address of the audit trace.\n --request-id string request id of the audit trace.\n --sort-by strings sort by (comma separated) column(s), sort direction can be changed by appending :asc or :desc behind the column identifier. possible values: path|tenant|timestamp|user\n --status-code int32 HTTP status code of the audit trace.\n --tenant string tenant of the audit trace.\n --to string end of range of the audit traces. e.g. 1h, 10m, 2006-01-02 15:04:05\n --type string type of the audit trace. One of [http, grpc, event].\n --user string user of the audit trace.","category":"page"},{"location":"external/metalctl/docs/metalctl_audit_list/#Options-inherited-from-parent-commands","page":"metalctl audit list","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_audit_list/","page":"metalctl audit list","title":"metalctl audit list","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_audit_list/#SEE-ALSO","page":"metalctl audit list","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_audit_list/","page":"metalctl audit list","title":"metalctl audit list","text":"metalctl audit\t - manage audit trace entities","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_power_reset/#metalctl-machine-power-reset","page":"metalctl machine power reset","title":"metalctl machine power reset","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_power_reset/","page":"metalctl machine power reset","title":"metalctl machine power reset","text":"power reset a machine","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_power_reset/#Synopsis","page":"metalctl machine power reset","title":"Synopsis","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_power_reset/","page":"metalctl machine power reset","title":"metalctl machine power reset","text":"(hard) reset the machine power.","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_power_reset/","page":"metalctl machine power reset","title":"metalctl machine power reset","text":"metalctl machine power reset [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_power_reset/#Options","page":"metalctl machine power reset","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_power_reset/","page":"metalctl machine power reset","title":"metalctl machine power reset","text":" -h, --help help for reset","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_power_reset/#Options-inherited-from-parent-commands","page":"metalctl machine power reset","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_power_reset/","page":"metalctl machine power reset","title":"metalctl machine power reset","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_power_reset/#SEE-ALSO","page":"metalctl machine power reset","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_power_reset/","page":"metalctl machine power reset","title":"metalctl machine power reset","text":"metalctl machine power\t - manage machine power","category":"page"},{"location":"development/proposals/MEP3/README/#Machine-Re-Installation","page":"Machine Re-Installation","title":"Machine Re-Installation","text":"","category":"section"},{"location":"development/proposals/MEP3/README/","page":"Machine Re-Installation","title":"Machine Re-Installation","text":"In the current metal-api only machine installations are possible, performing a machine upgrade is only possible by creating a new machine and delete the old one. This has the drawback that in case a lot of data is stored on the local disks, a full restore of the original data must be performed.","category":"page"},{"location":"development/proposals/MEP3/README/","page":"Machine Re-Installation","title":"Machine Re-Installation","text":"To prevent this, we will introduce a new metal-api endpoint to reinstall the machine with a new image, without actually deleting the data stored on the additional hard disks.","category":"page"},{"location":"development/proposals/MEP3/README/","page":"Machine Re-Installation","title":"Machine Re-Installation","text":"Storage is a difficult task to get right and reliable. A short analysis of our different storage requirements lead to 3 different scenarios.","category":"page"},{"location":"development/proposals/MEP3/README/","page":"Machine Re-Installation","title":"Machine Re-Installation","text":"Storage for the etcd pvs in the seed cluster of every partition. This is the most important storage in our setup because these etcd pods serve as configuration backend for all customer kubernetes clusters. If they fail, the cluster is down. However gardener deploys a backup and restore sidecar into the etcd pod of every customer kubernetes control plane, and if this sidecar detects a corrupt or missing etcd database file(s) it starts automatic restore from the configured backup location. This will take some minutes. If for example a node dies, and gardener creates a new node instead, the csi-lvm created pv is not present on that node. Kubernetes will not schedule the missing etcd pod on this node because it has a local PV configured and is therefore tainted to run only on that node. To let kubernetes create that pod anyhow, someone has to either remove the taint, or delete the pod. If this is done, the pod starts and the restore of the etcd data can start as well. You can see this is a bit too complicated and will take the customer cluster down for a while (not measured yet but in the range of 5-10 minutes).\nStorage in customer clusters. This was not promised in 2020. We have a intermediate solution with the provisioning of csi-lvm by default into all customer clusters. Albeit this is only local storage and will get deleted if a node dies.\nS3 Storage. We have two possibilities to cope with storage:\nIn place update of the OS with a daemonset This will be fast and simple, but might fail because the packages being installed are broken right now, or a filesystem gets full, or any other failure you can think of during a os update. Another drawback is that metal-api does not reflect the updated os image.\nmetal-api get a machine reinstall endpoint With this approach we leverage from existing and already proven mechanisms. Reinstall must keep all data except the sata-dom. Gardener currently is not able to do an update with this approach because it can only do rolling updates. Therefore a additional osupdatestrategy has to be implemented for metal and other providers in gardener to be able to leverage the metal reinstall on the same machineID approach.","category":"page"},{"location":"development/proposals/MEP3/README/","page":"Machine Re-Installation","title":"Machine Re-Installation","text":"If reinstall is implemented, we should focus on the same technology for all scenarios and put ceph via rook.io into the kubernetes clusters as additional StorageClass. It has to be checked whether to use the raw disk or a PV as the underlay block device where ceph stores its data.","category":"page"},{"location":"development/proposals/MEP3/README/#API-and-behavior","page":"Machine Re-Installation","title":"API and behavior","text":"","category":"section"},{"location":"development/proposals/MEP3/README/","page":"Machine Re-Installation","title":"Machine Re-Installation","text":"The API will get an new endpoint \"reinstall\" this endpoint takes two arguments:","category":"page"},{"location":"development/proposals/MEP3/README/","page":"Machine Re-Installation","title":"Machine Re-Installation","text":"machineID\nimage","category":"page"},{"location":"development/proposals/MEP3/README/","page":"Machine Re-Installation","title":"Machine Re-Installation","text":"No other aspects of the machine can be modified during the re-installation. All data stored in the existing allocation will be preserved, only the image will be modified. Once this endpoint was called, the machine will get a reboot signal with the boot order set to PXE instead of HDD and the network interfaces on the leaf are set to PXE as well. Then the normal installation process starts:","category":"page"},{"location":"development/proposals/MEP3/README/","page":"Machine Re-Installation","title":"Machine Re-Installation","text":"unchanged: PXE boot with metal-hammer\nchanged: metal-hammer first checks with the machineID in the metal-api (through metal-core) if there is already a allocation present\nchanged: if a allocation is present and the allocation has set reinstall: true, wipe disk is only executed for the root disk, all other disks are untouched.\nunchanged: the specified image is downloaded and burned, /install.sh is executed\nunchanged: successful installation is reported back, network is set the the vrf, boot order is set to HDD.\nunchanged: distribution kernel is booted via kexec","category":"page"},{"location":"development/proposals/MEP3/README/","page":"Machine Re-Installation","title":"Machine Re-Installation","text":"We can see that the allocation requires one additional parameter: reinstall and metal-hammer must check for already existing allocation at an earlier stage.","category":"page"},{"location":"development/proposals/MEP3/README/","page":"Machine Re-Installation","title":"Machine Re-Installation","text":"Components which requires modifications (first guess):","category":"page"},{"location":"development/proposals/MEP3/README/","page":"Machine Re-Installation","title":"Machine Re-Installation","text":"metal-hammer:\ncheck for allocation present earlier\nevaluation of reinstall flag set\nwipe of disks depends on that flag\nBonus: move configuration of disk layout and primary disk detection algorithm (PDDA) from metal-hammer into metal-api. metal-api MUST reject reinstallation if the disk found by PDDA does not have the /etc/metal directory!\nmetal-core:\nprobably nothing\nmetal-api:\nnew endpoint /machine/reinstall\nadd Reinstall bool to data model of allocation\nmake sure to reset Reinstall after reinstallation to prevent endless reinstallation loop\nmetalctl:\nimplement reinstall\nmetal-go:\nimplement reinstall\ngardener (longterm):\nadd the OSUpgradeStrategy reinstall","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_create/#metalctl-machine-create","page":"metalctl machine create","title":"metalctl machine create","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_create/","page":"metalctl machine create","title":"metalctl machine create","text":"creates the machine","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_create/","page":"metalctl machine create","title":"metalctl machine create","text":"metalctl machine create [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_create/#Examples","page":"metalctl machine create","title":"Examples","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_create/","page":"metalctl machine create","title":"metalctl machine create","text":"machine create can be done in two different ways:\n\n- default with automatic allocation:\n\n\tmetalctl machine create \\\n\t\t--hostname worker01 \\\n\t\t--name worker \\\n\t\t--image ubuntu-18.04 \\ # query available with: metalctl image list\n\t\t--size t1-small-x86 \\ # query available with: metalctl size list\n\t\t--partition test \\ # query available with: metalctl partition list\n\t\t--project cluster01 \\\n\t\t--sshpublickey \"@~/.ssh/id_rsa.pub\"\n\n- for metal administration with reserved machines:\n\n\treserve a machine you want to allocate:\n\n\tmetalctl machine reserve 00000000-0000-0000-0000-0cc47ae54694 --description \"blocked for maintenance\"\n\n\tallocate this machine:\n\n\tmetalctl machine create \\\n\t\t--hostname worker01 \\\n\t\t--name worker \\\n\t\t--image ubuntu-18.04 \\ # query available with: metalctl image list\n\t\t--project cluster01 \\\n\t\t--sshpublickey \"@~/.ssh/id_rsa.pub\" \\\n\t\t--id 00000000-0000-0000-0000-0cc47ae54694\n\nafter you do not want to use this machine exclusive, remove the reservation:\n\nmetalctl machine reserve 00000000-0000-0000-0000-0cc47ae54694 --remove\n\nOnce created the machine installation can not be modified anymore.\n","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_create/#Options","page":"metalctl machine create","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_create/","page":"metalctl machine create","title":"metalctl machine create","text":" --bulk-output when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.\n -d, --description string Description of the machine to create. [optional]\n -f, --file string filename of the create or update request in yaml format, or - for stdin.\n \n Example:\n $ metalctl machine describe machine-1 -o yaml > machine.yaml\n $ vi machine.yaml\n $ # either via stdin\n $ cat machine.yaml | metalctl machine create -f -\n $ # or via file\n $ metalctl machine create -f machine.yaml\n \n the file can also contain multiple documents and perform a bulk operation.\n \t\n --filesystemlayout string Filesystemlayout to use during machine installation. [optional]\n -h, --help help for create\n -H, --hostname string Hostname of the machine. [required]\n -I, --id string ID of a specific machine to allocate, if given, size and partition are ignored. Need to be set to reserved (--reserve) state before.\n -i, --image string OS Image to install. [required]\n --ips strings Sets the machine's IP address. Usage: [--ips[=IPV4-ADDRESS[,IPV4-ADDRESS]...]]...\n IPV4-ADDRESS specifies the IPv4 address to add.\n It can only be used in conjunction with --networks.\n -n, --name string Name of the machine. [optional]\n --networks strings Adds a network. Usage: [--networks NETWORK[:MODE][,NETWORK[:MODE]]...]...\n NETWORK specifies the name or id of an existing network.\n MODE cane be omitted or one of:\n \tauto\tIP address is automatically acquired from the given network\n \tnoauto\tIP address for the given network must be provided via --ips\n -S, --partition string partition/datacenter where the machine is created. [required, except for reserved machines]\n -P, --project string Project where the machine should belong to. [required]\n -s, --size string Size of the machine. [required, except for reserved machines]\n --skip-security-prompts skips security prompt for bulk operations\n -p, --sshpublickey string SSH public key for access via ssh and console. [optional]\n Can be either the public key as string, or pointing to the public key file to use e.g.: \"@~/.ssh/id_rsa.pub\".\n If ~/.ssh/[id_ed25519.pub | id_rsa.pub | id_dsa.pub] is present it will be picked as default, matching the first one in this order.\n --tags strings tags to add to the machine, use it like: --tags \"tag1,tag2\" or --tags \"tag3\".\n --timestamps when used with --file (bulk operation): prints timestamps in-between the operations\n --userdata string cloud-init.io compatible userdata. [optional]\n Can be either the userdata as string, or pointing to the userdata file to use e.g.: \"@/tmp/userdata.cfg\".","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_create/#Options-inherited-from-parent-commands","page":"metalctl machine create","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_create/","page":"metalctl machine create","title":"metalctl machine create","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_create/#SEE-ALSO","page":"metalctl machine create","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_create/","page":"metalctl machine create","title":"metalctl machine create","text":"metalctl machine\t - manage machine entities","category":"page"},{"location":"installation/monitoring/#Monitoring-the-metal-stack","page":"Monitoring","title":"Monitoring the metal-stack","text":"","category":"section"},{"location":"installation/monitoring/","page":"Monitoring","title":"Monitoring","text":"We are currently working on providing the sources of our monitoring deployment for public usage. Please come back later.","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_reserve/#metalctl-machine-reserve","page":"metalctl machine reserve","title":"metalctl machine reserve","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_reserve/","page":"metalctl machine reserve","title":"metalctl machine reserve","text":"reserve a machine","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_reserve/#Synopsis","page":"metalctl machine reserve","title":"Synopsis","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_reserve/","page":"metalctl machine reserve","title":"metalctl machine reserve","text":"reserve a machine for exclusive usage, this machine will no longer be picked by other allocations. This is useful for maintenance of the machine or testing. After the reservation is not needed anymore, the reservation should be removed with –remove.","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_reserve/","page":"metalctl machine reserve","title":"metalctl machine reserve","text":"metalctl machine reserve [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_reserve/#Options","page":"metalctl machine reserve","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_reserve/","page":"metalctl machine reserve","title":"metalctl machine reserve","text":" -d, --description string description of the reason for the reservation.\n -h, --help help for reserve\n -r, --remove remove the reservation.","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_reserve/#Options-inherited-from-parent-commands","page":"metalctl machine reserve","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_reserve/","page":"metalctl machine reserve","title":"metalctl machine reserve","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_reserve/#SEE-ALSO","page":"metalctl machine reserve","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_reserve/","page":"metalctl machine reserve","title":"metalctl machine reserve","text":"metalctl machine\t - manage machine entities","category":"page"},{"location":"external/metalctl/docs/metalctl_completion_bash/#metalctl-completion-bash","page":"metalctl completion bash","title":"metalctl completion bash","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_completion_bash/","page":"metalctl completion bash","title":"metalctl completion bash","text":"Generate the autocompletion script for bash","category":"page"},{"location":"external/metalctl/docs/metalctl_completion_bash/#Synopsis","page":"metalctl completion bash","title":"Synopsis","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_completion_bash/","page":"metalctl completion bash","title":"metalctl completion bash","text":"Generate the autocompletion script for the bash shell.","category":"page"},{"location":"external/metalctl/docs/metalctl_completion_bash/","page":"metalctl completion bash","title":"metalctl completion bash","text":"This script depends on the 'bash-completion' package. If it is not installed already, you can install it via your OS's package manager.","category":"page"},{"location":"external/metalctl/docs/metalctl_completion_bash/","page":"metalctl completion bash","title":"metalctl completion bash","text":"To load completions in your current shell session:","category":"page"},{"location":"external/metalctl/docs/metalctl_completion_bash/","page":"metalctl completion bash","title":"metalctl completion bash","text":"source <(metalctl completion bash)","category":"page"},{"location":"external/metalctl/docs/metalctl_completion_bash/","page":"metalctl completion bash","title":"metalctl completion bash","text":"To load completions for every new session, execute once:","category":"page"},{"location":"external/metalctl/docs/metalctl_completion_bash/#Linux:","page":"metalctl completion bash","title":"Linux:","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_completion_bash/","page":"metalctl completion bash","title":"metalctl completion bash","text":"metalctl completion bash > /etc/bash_completion.d/metalctl","category":"page"},{"location":"external/metalctl/docs/metalctl_completion_bash/#macOS:","page":"metalctl completion bash","title":"macOS:","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_completion_bash/","page":"metalctl completion bash","title":"metalctl completion bash","text":"metalctl completion bash > $(brew --prefix)/etc/bash_completion.d/metalctl","category":"page"},{"location":"external/metalctl/docs/metalctl_completion_bash/","page":"metalctl completion bash","title":"metalctl completion bash","text":"You will need to start a new shell for this setup to take effect.","category":"page"},{"location":"external/metalctl/docs/metalctl_completion_bash/","page":"metalctl completion bash","title":"metalctl completion bash","text":"metalctl completion bash","category":"page"},{"location":"external/metalctl/docs/metalctl_completion_bash/#Options","page":"metalctl completion bash","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_completion_bash/","page":"metalctl completion bash","title":"metalctl completion bash","text":" -h, --help help for bash\n --no-descriptions disable completion descriptions","category":"page"},{"location":"external/metalctl/docs/metalctl_completion_bash/#Options-inherited-from-parent-commands","page":"metalctl completion bash","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_completion_bash/","page":"metalctl completion bash","title":"metalctl completion bash","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_completion_bash/#SEE-ALSO","page":"metalctl completion bash","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_completion_bash/","page":"metalctl completion bash","title":"metalctl completion bash","text":"metalctl completion\t - Generate the autocompletion script for the specified shell","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_power_on/#metalctl-machine-power-on","page":"metalctl machine power on","title":"metalctl machine power on","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_power_on/","page":"metalctl machine power on","title":"metalctl machine power on","text":"power on a machine","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_power_on/#Synopsis","page":"metalctl machine power on","title":"Synopsis","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_power_on/","page":"metalctl machine power on","title":"metalctl machine power on","text":"set the machine to power on state, if the machine already was on nothing happens.","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_power_on/","page":"metalctl machine power on","title":"metalctl machine power on","text":"metalctl machine power on [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_power_on/#Options","page":"metalctl machine power on","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_power_on/","page":"metalctl machine power on","title":"metalctl machine power on","text":" -h, --help help for on","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_power_on/#Options-inherited-from-parent-commands","page":"metalctl machine power on","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_power_on/","page":"metalctl machine power on","title":"metalctl machine power on","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_power_on/#SEE-ALSO","page":"metalctl machine power on","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_power_on/","page":"metalctl machine power on","title":"metalctl machine power on","text":"metalctl machine power\t - manage machine power","category":"page"},{"location":"external/metalctl/docs/metalctl_firmware/#metalctl-firmware","page":"metalctl firmware","title":"metalctl firmware","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_firmware/","page":"metalctl firmware","title":"metalctl firmware","text":"manage firmwares","category":"page"},{"location":"external/metalctl/docs/metalctl_firmware/#Synopsis","page":"metalctl firmware","title":"Synopsis","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_firmware/","page":"metalctl firmware","title":"metalctl firmware","text":"list, upload and remove firmwares.","category":"page"},{"location":"external/metalctl/docs/metalctl_firmware/#Options","page":"metalctl firmware","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_firmware/","page":"metalctl firmware","title":"metalctl firmware","text":" -h, --help help for firmware","category":"page"},{"location":"external/metalctl/docs/metalctl_firmware/#Options-inherited-from-parent-commands","page":"metalctl firmware","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_firmware/","page":"metalctl firmware","title":"metalctl firmware","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_firmware/#SEE-ALSO","page":"metalctl firmware","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_firmware/","page":"metalctl firmware","title":"metalctl firmware","text":"metalctl\t - a cli to manage entities in the metal-stack api\nmetalctl firmware delete\t - delete a firmware\nmetalctl firmware list\t - list firmwares\nmetalctl firmware upload\t - upload a firmware","category":"page"},{"location":"external/metalctl/docs/metalctl_filesystemlayout_edit/#metalctl-filesystemlayout-edit","page":"metalctl filesystemlayout edit","title":"metalctl filesystemlayout edit","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_filesystemlayout_edit/","page":"metalctl filesystemlayout edit","title":"metalctl filesystemlayout edit","text":"edit the filesystemlayout through an editor and update","category":"page"},{"location":"external/metalctl/docs/metalctl_filesystemlayout_edit/","page":"metalctl filesystemlayout edit","title":"metalctl filesystemlayout edit","text":"metalctl filesystemlayout edit [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_filesystemlayout_edit/#Options","page":"metalctl filesystemlayout edit","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_filesystemlayout_edit/","page":"metalctl filesystemlayout edit","title":"metalctl filesystemlayout edit","text":" -h, --help help for edit","category":"page"},{"location":"external/metalctl/docs/metalctl_filesystemlayout_edit/#Options-inherited-from-parent-commands","page":"metalctl filesystemlayout edit","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_filesystemlayout_edit/","page":"metalctl filesystemlayout edit","title":"metalctl filesystemlayout edit","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_filesystemlayout_edit/#SEE-ALSO","page":"metalctl filesystemlayout edit","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_filesystemlayout_edit/","page":"metalctl filesystemlayout edit","title":"metalctl filesystemlayout edit","text":"metalctl filesystemlayout\t - manage filesystemlayout entities","category":"page"},{"location":"external/metalctl/docs/metalctl_firmware_delete/#metalctl-firmware-delete","page":"metalctl firmware delete","title":"metalctl firmware delete","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_firmware_delete/","page":"metalctl firmware delete","title":"metalctl firmware delete","text":"delete a firmware","category":"page"},{"location":"external/metalctl/docs/metalctl_firmware_delete/#Synopsis","page":"metalctl firmware delete","title":"Synopsis","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_firmware_delete/","page":"metalctl firmware delete","title":"metalctl firmware delete","text":"deletes the specified firmware.","category":"page"},{"location":"external/metalctl/docs/metalctl_firmware_delete/","page":"metalctl firmware delete","title":"metalctl firmware delete","text":"metalctl firmware delete [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_firmware_delete/#Options","page":"metalctl firmware delete","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_firmware_delete/","page":"metalctl firmware delete","title":"metalctl firmware delete","text":" --board string the board type (required)\n -h, --help help for delete\n --kind string the firmware kind [bmc|bios] (required)\n --revision string the firmware revision (required)\n --vendor string the vendor (required)","category":"page"},{"location":"external/metalctl/docs/metalctl_firmware_delete/#Options-inherited-from-parent-commands","page":"metalctl firmware delete","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_firmware_delete/","page":"metalctl firmware delete","title":"metalctl firmware delete","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_firmware_delete/#SEE-ALSO","page":"metalctl firmware delete","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_firmware_delete/","page":"metalctl firmware delete","title":"metalctl firmware delete","text":"metalctl firmware\t - manage firmwares","category":"page"},{"location":"overview/gpu-support/#GPU-Support","page":"GPU Support","title":"GPU Support","text":"","category":"section"},{"location":"overview/gpu-support/","page":"GPU Support","title":"GPU Support","text":"Pages = [\"gpu-support.md\"]\nDepth = 5","category":"page"},{"location":"overview/gpu-support/","page":"GPU Support","title":"GPU Support","text":"For workloads which require the assistance of GPUs, support for GPUs in bare metal servers was added to metal-stack.io v0.18.0.","category":"page"},{"location":"overview/gpu-support/#GPU-Operator-installation","page":"GPU Support","title":"GPU Operator installation","text":"","category":"section"},{"location":"overview/gpu-support/","page":"GPU Support","title":"GPU Support","text":"With the nvidia image a worker has basic GPU support. This means that the required kernel driver, the containerd shim and the required containerd configuration are already installed and configured.","category":"page"},{"location":"overview/gpu-support/","page":"GPU Support","title":"GPU Support","text":"To enable Pods that require GPU support to be scheduled on a worker node with a GPU, a `gpu-operator' must be installed. This has to be done by the cluster owner after the cluster is up and running.","category":"page"},{"location":"overview/gpu-support/","page":"GPU Support","title":"GPU Support","text":"The simplest way to install this operator is as follows:","category":"page"},{"location":"overview/gpu-support/","page":"GPU Support","title":"GPU Support","text":"helm repo add nvidia https://helm.ngc.nvidia.com/nvidia\nhelm repo update\n\nkubectl create ns gpu-operator\nkubectl label --overwrite ns gpu-operator pod-security.kubernetes.io/enforce=privileged\n\nhelm install --wait \\\n --generate-name \\\n --namespace gpu-operator \\\n --create-namespace \\\n nvidia/gpu-operator \\\n --set driver.enabled=false \\\n --set toolkit.enabled=false","category":"page"},{"location":"overview/gpu-support/","page":"GPU Support","title":"GPU Support","text":"After that kubectl describe node must show the gpu in the capacity like so:","category":"page"},{"location":"overview/gpu-support/","page":"GPU Support","title":"GPU Support","text":"...\nCapacity:\n cpu: 64\n ephemeral-storage: 100205640Ki\n hugepages-1Gi: 0\n hugepages-2Mi: 0\n memory: 263802860Ki\n nvidia.com/gpu: 1\n pods: 510\n...","category":"page"},{"location":"overview/gpu-support/","page":"GPU Support","title":"GPU Support","text":"With this basic installation, the worker node is ready to process GPU workloads.","category":"page"},{"location":"overview/gpu-support/","page":"GPU Support","title":"GPU Support","text":"warning: Warning\nHowever, there is a caveat - only one 'Pod' can access the GPU. If this is all you need, no additional configuration is required. On the other hand, if you are planning to deploy multiple applications that require GPU support, and there are not that many GPUs available, you will need to configure the gpu-operator to allow the GPU to be shared between multiple Pods.","category":"page"},{"location":"overview/gpu-support/","page":"GPU Support","title":"GPU Support","text":"There are several approaches to sharing GPUs, please consult the official Nvidia documentation for further reference.","category":"page"},{"location":"overview/gpu-support/","page":"GPU Support","title":"GPU Support","text":"https://developer.nvidia.com/blog/improving-gpu-utilization-in-kubernetes https://docs.nvidia.com/datacenter/cloud-native/gpu-operator/latest/gpu-operator-mig.html https://docs.nvidia.com/datacenter/cloud-native/gpu-operator/latest/gpu-sharing.html","category":"page"},{"location":"overview/gpu-support/","page":"GPU Support","title":"GPU Support","text":"With this, happy AI processing.","category":"page"},{"location":"external/metalctl/docs/metalctl_completion_powershell/#metalctl-completion-powershell","page":"metalctl completion powershell","title":"metalctl completion powershell","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_completion_powershell/","page":"metalctl completion powershell","title":"metalctl completion powershell","text":"Generate the autocompletion script for powershell","category":"page"},{"location":"external/metalctl/docs/metalctl_completion_powershell/#Synopsis","page":"metalctl completion powershell","title":"Synopsis","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_completion_powershell/","page":"metalctl completion powershell","title":"metalctl completion powershell","text":"Generate the autocompletion script for powershell.","category":"page"},{"location":"external/metalctl/docs/metalctl_completion_powershell/","page":"metalctl completion powershell","title":"metalctl completion powershell","text":"To load completions in your current shell session:","category":"page"},{"location":"external/metalctl/docs/metalctl_completion_powershell/","page":"metalctl completion powershell","title":"metalctl completion powershell","text":"metalctl completion powershell | Out-String | Invoke-Expression","category":"page"},{"location":"external/metalctl/docs/metalctl_completion_powershell/","page":"metalctl completion powershell","title":"metalctl completion powershell","text":"To load completions for every new session, add the output of the above command to your powershell profile.","category":"page"},{"location":"external/metalctl/docs/metalctl_completion_powershell/","page":"metalctl completion powershell","title":"metalctl completion powershell","text":"metalctl completion powershell [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_completion_powershell/#Options","page":"metalctl completion powershell","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_completion_powershell/","page":"metalctl completion powershell","title":"metalctl completion powershell","text":" -h, --help help for powershell\n --no-descriptions disable completion descriptions","category":"page"},{"location":"external/metalctl/docs/metalctl_completion_powershell/#Options-inherited-from-parent-commands","page":"metalctl completion powershell","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_completion_powershell/","page":"metalctl completion powershell","title":"metalctl completion powershell","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_completion_powershell/#SEE-ALSO","page":"metalctl completion powershell","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_completion_powershell/","page":"metalctl completion powershell","title":"metalctl completion powershell","text":"metalctl completion\t - Generate the autocompletion script for the specified shell","category":"page"},{"location":"external/metalctl/docs/metalctl_size_list/#metalctl-size-list","page":"metalctl size list","title":"metalctl size list","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_list/","page":"metalctl size list","title":"metalctl size list","text":"list all sizes","category":"page"},{"location":"external/metalctl/docs/metalctl_size_list/","page":"metalctl size list","title":"metalctl size list","text":"metalctl size list [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_size_list/#Options","page":"metalctl size list","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_list/","page":"metalctl size list","title":"metalctl size list","text":" -h, --help help for list\n --sort-by strings sort by (comma separated) column(s), sort direction can be changed by appending :asc or :desc behind the column identifier. possible values: description|id|name","category":"page"},{"location":"external/metalctl/docs/metalctl_size_list/#Options-inherited-from-parent-commands","page":"metalctl size list","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_list/","page":"metalctl size list","title":"metalctl size list","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_size_list/#SEE-ALSO","page":"metalctl size list","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_list/","page":"metalctl size list","title":"metalctl size list","text":"metalctl size\t - manage size entities","category":"page"},{"location":"external/metalctl/docs/metalctl_size_imageconstraint/#metalctl-size-imageconstraint","page":"metalctl size imageconstraint","title":"metalctl size imageconstraint","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_imageconstraint/","page":"metalctl size imageconstraint","title":"metalctl size imageconstraint","text":"manage imageconstraint entities","category":"page"},{"location":"external/metalctl/docs/metalctl_size_imageconstraint/#Synopsis","page":"metalctl size imageconstraint","title":"Synopsis","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_imageconstraint/","page":"metalctl size imageconstraint","title":"metalctl size imageconstraint","text":"if a size has specific requirements regarding the images which must fulfill certain constraints, this can be configured here.","category":"page"},{"location":"external/metalctl/docs/metalctl_size_imageconstraint/#Options","page":"metalctl size imageconstraint","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_imageconstraint/","page":"metalctl size imageconstraint","title":"metalctl size imageconstraint","text":" -h, --help help for imageconstraint","category":"page"},{"location":"external/metalctl/docs/metalctl_size_imageconstraint/#Options-inherited-from-parent-commands","page":"metalctl size imageconstraint","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_imageconstraint/","page":"metalctl size imageconstraint","title":"metalctl size imageconstraint","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_size_imageconstraint/#SEE-ALSO","page":"metalctl size imageconstraint","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_imageconstraint/","page":"metalctl size imageconstraint","title":"metalctl size imageconstraint","text":"metalctl size\t - manage size entities\nmetalctl size imageconstraint apply\t - applies one or more imageconstraints from a given file\nmetalctl size imageconstraint create\t - creates the imageconstraint\nmetalctl size imageconstraint delete\t - deletes the imageconstraint\nmetalctl size imageconstraint describe\t - describes the imageconstraint\nmetalctl size imageconstraint edit\t - edit the imageconstraint through an editor and update\nmetalctl size imageconstraint list\t - list all imageconstraints\nmetalctl size imageconstraint try\t - try if size and image can be allocated\nmetalctl size imageconstraint update\t - updates the imageconstraint","category":"page"},{"location":"external/metalctl/docs/metalctl_size/#metalctl-size","page":"metalctl size","title":"metalctl size","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size/","page":"metalctl size","title":"metalctl size","text":"manage size entities","category":"page"},{"location":"external/metalctl/docs/metalctl_size/#Synopsis","page":"metalctl size","title":"Synopsis","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size/","page":"metalctl size","title":"metalctl size","text":"a size matches a machine in terms of cpu cores, ram and storage.","category":"page"},{"location":"external/metalctl/docs/metalctl_size/#Options","page":"metalctl size","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size/","page":"metalctl size","title":"metalctl size","text":" -h, --help help for size","category":"page"},{"location":"external/metalctl/docs/metalctl_size/#Options-inherited-from-parent-commands","page":"metalctl size","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size/","page":"metalctl size","title":"metalctl size","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_size/#SEE-ALSO","page":"metalctl size","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size/","page":"metalctl size","title":"metalctl size","text":"metalctl\t - a cli to manage entities in the metal-stack api\nmetalctl size apply\t - applies one or more sizes from a given file\nmetalctl size create\t - creates the size\nmetalctl size delete\t - deletes the size\nmetalctl size describe\t - describes the size\nmetalctl size edit\t - edit the size through an editor and update\nmetalctl size imageconstraint\t - manage imageconstraint entities\nmetalctl size list\t - list all sizes\nmetalctl size reservation\t - manage reservation entities\nmetalctl size suggest\t - suggest size from a given machine id\nmetalctl size update\t - updates the size","category":"page"},{"location":"overview/os/#Operating-Systems","page":"Operating Systems","title":"Operating Systems","text":"","category":"section"},{"location":"overview/os/","page":"Operating Systems","title":"Operating Systems","text":"Our operating system images are built on regular basis from the metal-images repository.","category":"page"},{"location":"overview/os/","page":"Operating Systems","title":"Operating Systems","text":"All images are hosted on GKE at images.metal-stack.io. Feel free to use this as a mirror for your metal-stack partitions if you want. The metal-stack developers continuously have an eye on the supported images. They are updated regularly and scanned for vulnerabilities.","category":"page"},{"location":"overview/os/#Supported-OS-Images","page":"Operating Systems","title":"Supported OS Images","text":"","category":"section"},{"location":"overview/os/","page":"Operating Systems","title":"Operating Systems","text":"The operating system images that we build are trimmed down to their bare essentials for serving as Kubernetes worker nodes. Small image sizes make machine provisioning blazingly fast.","category":"page"},{"location":"overview/os/","page":"Operating Systems","title":"Operating Systems","text":"The supported images for worker nodes currently are:","category":"page"},{"location":"overview/os/","page":"Operating Systems","title":"Operating Systems","text":"Platform Distribution Version\nLinux Debian 11\nLinux Ubuntu 22.04","category":"page"},{"location":"overview/os/","page":"Operating Systems","title":"Operating Systems","text":"The supported images for firewalls are:","category":"page"},{"location":"overview/os/","page":"Operating Systems","title":"Operating Systems","text":"Platform Distribution Version Based On\nLinux Ubuntu 3 22.04","category":"page"},{"location":"overview/os/#Building-Your-Own-Images","page":"Operating Systems","title":"Building Your Own Images","text":"","category":"section"},{"location":"overview/os/","page":"Operating Systems","title":"Operating Systems","text":"It is fully possible to build your own operating system images and provide them through the metal-stack.","category":"page"},{"location":"overview/os/","page":"Operating Systems","title":"Operating Systems","text":"There are some conventions though that you need to follow in order to make your image installable through the metal-hammer. You should understand the machine provisioning sequence before starting to write your own images.","category":"page"},{"location":"overview/os/","page":"Operating Systems","title":"Operating Systems","text":"Images need to be compressed to a tarball using the lz4 compression algorithm\nAn md5 checksum file with the same name as the image archive needs to be provided in the download path along with the actual os image\nA packages.txt containing the packages contained in the OS image should be provided in the download path (not strictly required)\nConsider semantic image versioning, which we use in our algorithms to select latest images (e.g. os-major.minor.patch ➡️ ubuntu-19.10.20191018)\nConsider installing packages used by the metal-stack infrastructure\nFRR to enable routing-to-the-host in our network topology\ngo-lldpd to enable checking if the machine is still alive after user allocation\nignition for enabling users to run user-specific initialization instructions before bootup. It's pretty small in size, which is why we use it. However, you are free to use other cloud instance initialization tools if you want to.\nYou have to provide an install.sh script, which applies user-specific configuration in the installed image\nThis script should consume parameters from the install.yaml file that the metal-hammer writes to /etc/metal/install.yaml\nPlease check this contract between image and the metal-hammer here\nFor the time being, your image must be able to support kexec into the new operating system kernel, the kexec command is issued by the metal-hammer after running the install.sh. We do this because kexec is much faster than rebooting a machine.\nWe recommend building images from Dockerfiles as it is done in metal-images repository.","category":"page"},{"location":"overview/os/","page":"Operating Systems","title":"Operating Systems","text":"info: Info\nBuilding own operating system images is an advanced topic. When you have just started with metal-stack, we recommend using the public operating system images first.","category":"page"},{"location":"external/metalctl/README/#metalctl","page":"metalctl","title":"metalctl","text":"","category":"section"},{"location":"external/metalctl/README/","page":"metalctl","title":"metalctl","text":"metalctl is the command line client to access the metal-api.","category":"page"},{"location":"external/metalctl/README/#Installation","page":"metalctl","title":"Installation","text":"","category":"section"},{"location":"external/metalctl/README/","page":"metalctl","title":"metalctl","text":"Download locations:","category":"page"},{"location":"external/metalctl/README/","page":"metalctl","title":"metalctl","text":"metalctl-linux-amd64\nmetalctl-darwin-amd64\nmetalctl-darwin-arm64\nmetalctl-windows-amd64","category":"page"},{"location":"external/metalctl/README/#Installation-on-Linux","page":"metalctl","title":"Installation on Linux","text":"","category":"section"},{"location":"external/metalctl/README/","page":"metalctl","title":"metalctl","text":"curl -LO https://github.com/metal-stack/metalctl/releases/latest/download/metalctl-linux-amd64\nchmod +x metalctl-linux-amd64\nsudo mv metalctl-linux-amd64 /usr/local/bin/metalctl","category":"page"},{"location":"external/metalctl/README/#Installation-on-MacOS","page":"metalctl","title":"Installation on MacOS","text":"","category":"section"},{"location":"external/metalctl/README/","page":"metalctl","title":"metalctl","text":"For x86 based Macs:","category":"page"},{"location":"external/metalctl/README/","page":"metalctl","title":"metalctl","text":"curl -LO https://github.com/metal-stack/metalctl/releases/latest/download/metalctl-darwin-amd64\nchmod +x metalctl-darwin-amd64\nsudo mv metalctl-darwin-amd64 /usr/local/bin/metalctl","category":"page"},{"location":"external/metalctl/README/","page":"metalctl","title":"metalctl","text":"For Apple Silicon (M1) based Macs:","category":"page"},{"location":"external/metalctl/README/","page":"metalctl","title":"metalctl","text":"curl -LO https://github.com/metal-stack/metalctl/releases/latest/download/metalctl-darwin-arm64\nchmod +x metalctl-darwin-arm64\nsudo mv metalctl-darwin-arm64 /usr/local/bin/metalctl","category":"page"},{"location":"external/metalctl/README/#Installation-on-Windows","page":"metalctl","title":"Installation on Windows","text":"","category":"section"},{"location":"external/metalctl/README/","page":"metalctl","title":"metalctl","text":"curl -LO https://github.com/metal-stack/metalctl/releases/latest/download/metalctl-windows-amd64\ncopy metalctl-windows-amd64 metalctl.exe","category":"page"},{"location":"external/metalctl/README/#metalctl-update","page":"metalctl","title":"metalctl update","text":"","category":"section"},{"location":"external/metalctl/README/","page":"metalctl","title":"metalctl","text":"In order to keep your local metalctl installation up to date, you can update the binary like this:","category":"page"},{"location":"external/metalctl/README/","page":"metalctl","title":"metalctl","text":"metalctl update check\nlatest version:v0.8.3 from:2020-08-13T11:55:14Z\nlocal version:v0.8.2 from:2020-08-12T09:27:39Z\nmetalctl is not up to date\n\nmetalctl update do\n# a download with progress bar starts and replaces the binary. If the binary has root permissions please execute\nsudo metalctl update do\n# instead","category":"page"},{"location":"external/metalctl/README/#Built-from-project","page":"metalctl","title":"Built from project","text":"","category":"section"},{"location":"external/metalctl/README/","page":"metalctl","title":"metalctl","text":"make\nsudo ln -sf $(pwd)/bin/metalctl /usr/local/bin/metalctl","category":"page"},{"location":"external/metalctl/README/#Configuration","page":"metalctl","title":"Configuration","text":"","category":"section"},{"location":"external/metalctl/README/","page":"metalctl","title":"metalctl","text":"Set up auto-completion for metalctl, e.g. add to your ~/.bashrc:","category":"page"},{"location":"external/metalctl/README/","page":"metalctl","title":"metalctl","text":"source <(metalctl completion bash)","category":"page"},{"location":"external/metalctl/README/","page":"metalctl","title":"metalctl","text":"Set up metalctl config, by first creating the config folder (mkdir -p ~/.metalctl), then set the values according to your installation in ~/.metalctl/config.yaml:","category":"page"},{"location":"external/metalctl/README/","page":"metalctl","title":"metalctl","text":"---\ncurrent: prod\ncontexts:\n prod:\n url: https://api.metal-stack.io/metal\n issuer_url: https://dex.metal-stack.io/dex\n client_id: metal_client\n client_secret: 456\n hmac: YOUR_HMAC","category":"page"},{"location":"external/metalctl/README/","page":"metalctl","title":"metalctl","text":"Optional you can specify issuer_type: generic if you use other issuers as Dex, e.g. Keycloak (this will request scopes openid,profile,email):","category":"page"},{"location":"external/metalctl/README/","page":"metalctl","title":"metalctl","text":"contexts:\n prod:\n url: https://api.metal-stack.io/metal\n issuer_url: https://keycloak.somedomain.io\n issuer_type: generic\n client_id: my-client-id\n client_secret: my-secret","category":"page"},{"location":"external/metalctl/README/","page":"metalctl","title":"metalctl","text":"If you must specify special scopes for your issuer, you can use custom_scopes:","category":"page"},{"location":"external/metalctl/README/","page":"metalctl","title":"metalctl","text":"contexts:\n prod:\n url: https://api.metal-stack.io/metal\n issuer_url: https://keycloak.somedomain.io\n custom_scopes: roles,openid,profile,email\n client_id: my-client-id\n client_secret: my-secret","category":"page"},{"location":"external/metalctl/README/#Available-commands","page":"metalctl","title":"Available commands","text":"","category":"section"},{"location":"external/metalctl/README/","page":"metalctl","title":"metalctl","text":"Full documentation is generated out of the cobra command implementation with:","category":"page"},{"location":"external/metalctl/README/","page":"metalctl","title":"metalctl","text":"metalctl markdown","category":"page"},{"location":"external/metalctl/README/","page":"metalctl","title":"metalctl","text":"generated markdown is here and here","category":"page"},{"location":"external/metalctl/README/#Development","page":"metalctl","title":"Development","text":"","category":"section"},{"location":"external/metalctl/README/","page":"metalctl","title":"metalctl","text":"For MacOS users, running the tests might throw an error because tests are utilizing go-mpatch in order to manipulate the time.Now function. The patch allows testing with fixed timestamps.","category":"page"},{"location":"external/metalctl/README/","page":"metalctl","title":"metalctl","text":"Instead, MacOS users can utilize the make test-in-docker target to execute the tests.","category":"page"},{"location":"external/metalctl/README/#Page-Tree","page":"metalctl","title":"Page Tree","text":"","category":"section"},{"location":"external/metalctl/README/","page":"metalctl","title":"metalctl","text":"Pages = vcat([[joinpath(root, file)[length(@__DIR__)+2:end] for file in files] for (root, dirs, files) in walkdir(@__DIR__)]...)","category":"page"},{"location":"external/metalctl/docs/metalctl_network_ip/#metalctl-network-ip","page":"metalctl network ip","title":"metalctl network ip","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_network_ip/","page":"metalctl network ip","title":"metalctl network ip","text":"manage ip entities","category":"page"},{"location":"external/metalctl/docs/metalctl_network_ip/#Synopsis","page":"metalctl network ip","title":"Synopsis","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_network_ip/","page":"metalctl network ip","title":"metalctl network ip","text":"an ip address can be attached to a machine or firewall such that network traffic can be routed to these servers.","category":"page"},{"location":"external/metalctl/docs/metalctl_network_ip/#Options","page":"metalctl network ip","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_network_ip/","page":"metalctl network ip","title":"metalctl network ip","text":" -h, --help help for ip","category":"page"},{"location":"external/metalctl/docs/metalctl_network_ip/#Options-inherited-from-parent-commands","page":"metalctl network ip","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_network_ip/","page":"metalctl network ip","title":"metalctl network ip","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_network_ip/#SEE-ALSO","page":"metalctl network ip","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_network_ip/","page":"metalctl network ip","title":"metalctl network ip","text":"metalctl network\t - manage network entities\nmetalctl network ip apply\t - applies one or more ips from a given file\nmetalctl network ip create\t - creates the ip\nmetalctl network ip delete\t - deletes the ip\nmetalctl network ip describe\t - describes the ip\nmetalctl network ip edit\t - edit the ip through an editor and update\nmetalctl network ip issues\t - display ips which are in a potential bad state\nmetalctl network ip list\t - list all ips\nmetalctl network ip update\t - updates the ip","category":"page"},{"location":"external/metalctl/docs/metalctl_firewall_create/#metalctl-firewall-create","page":"metalctl firewall create","title":"metalctl firewall create","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_firewall_create/","page":"metalctl firewall create","title":"metalctl firewall create","text":"creates the firewall","category":"page"},{"location":"external/metalctl/docs/metalctl_firewall_create/","page":"metalctl firewall create","title":"metalctl firewall create","text":"metalctl firewall create [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_firewall_create/#Options","page":"metalctl firewall create","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_firewall_create/","page":"metalctl firewall create","title":"metalctl firewall create","text":" --bulk-output when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.\n -d, --description string Description of the firewall to create. [optional]\n -f, --file string filename of the create or update request in yaml format, or - for stdin.\n \n Example:\n $ metalctl firewall describe firewall-1 -o yaml > firewall.yaml\n $ vi firewall.yaml\n $ # either via stdin\n $ cat firewall.yaml | metalctl firewall create -f -\n $ # or via file\n $ metalctl firewall create -f firewall.yaml\n \n the file can also contain multiple documents and perform a bulk operation.\n \t\n --filesystemlayout string Filesystemlayout to use during machine installation. [optional]\n --firewall-rules-file string firewall rules specified in a yaml file\n \n Example:\n \n $ metalctl firewall create ..mandatory args.. --firewall-rules-file rules.yaml\n \n rules.yaml\n ---\n egress:\n - comment: allow outgoing https\n ports:\n - 443\n protocol: TCP\n to:\n - 0.0.0.0/0\n - comment: allow outgoing dns via tcp\n ports:\n - 53\n protocol: TCP\n to:\n - 0.0.0.0/0\n - comment: allow outgoing dns and ntp via udp\n ports:\n - 53\n - 123\n protocol: UDP\n to:\n - 0.0.0.0/0\n ingress:\n - comment: allow incoming ssh only to one ip\n ports:\n - 22\n protocol: TCP\n from:\n - 0.0.0.0/0\n - 1.2.3.4/32\n to:\n - 212.34.83.19/32\n - comment: allow incoming https to all targets\n ports:\n - 80\n - 433\n protocol: TCP\n from:\n - 0.0.0.0/0\n \n \n -h, --help help for create\n -H, --hostname string Hostname of the firewall. [required]\n -I, --id string ID of a specific firewall to allocate, if given, size and partition are ignored. Need to be set to reserved (--reserve) state before.\n -i, --image string OS Image to install. [required]\n --ips strings Sets the firewall's IP address. Usage: [--ips[=IPV4-ADDRESS[,IPV4-ADDRESS]...]]...\n IPV4-ADDRESS specifies the IPv4 address to add.\n It can only be used in conjunction with --networks.\n -n, --name string Name of the firewall. [optional]\n --networks strings Adds network(s). Usage: --networks NETWORK[:MODE][,NETWORK[:MODE]]... [--networks NETWORK[:MODE][,\n NETWORK[:MODE]]...]...\n NETWORK specifies the id of an existing network.\n MODE can be omitted or one of:\n \tauto\tIP address is automatically acquired from the given network\n \tnoauto\tNo automatic IP address acquisition\n -S, --partition string partition/datacenter where the firewall is created. [required, except for reserved machines]\n -P, --project string Project where the firewall should belong to. [required]\n -s, --size string Size of the firewall. [required, except for reserved machines]\n --skip-security-prompts skips security prompt for bulk operations\n -p, --sshpublickey string SSH public key for access via ssh and console. [optional]\n Can be either the public key as string, or pointing to the public key file to use e.g.: \"@~/.ssh/id_rsa.pub\".\n If ~/.ssh/[id_ed25519.pub | id_rsa.pub | id_dsa.pub] is present it will be picked as default, matching the first one in this order.\n --tags strings tags to add to the firewall, use it like: --tags \"tag1,tag2\" or --tags \"tag3\".\n --timestamps when used with --file (bulk operation): prints timestamps in-between the operations\n --userdata string cloud-init.io compatible userdata. [optional]\n Can be either the userdata as string, or pointing to the userdata file to use e.g.: \"@/tmp/userdata.cfg\".","category":"page"},{"location":"external/metalctl/docs/metalctl_firewall_create/#Options-inherited-from-parent-commands","page":"metalctl firewall create","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_firewall_create/","page":"metalctl firewall create","title":"metalctl firewall create","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_firewall_create/#SEE-ALSO","page":"metalctl firewall create","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_firewall_create/","page":"metalctl firewall create","title":"metalctl firewall create","text":"metalctl firewall\t - manage firewall entities","category":"page"},{"location":"external/metalctl/docs/metalctl_filesystemlayout_match/#metalctl-filesystemlayout-match","page":"metalctl filesystemlayout match","title":"metalctl filesystemlayout match","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_filesystemlayout_match/","page":"metalctl filesystemlayout match","title":"metalctl filesystemlayout match","text":"check if a machine satisfies all disk requirements of a given filesystemlayout","category":"page"},{"location":"external/metalctl/docs/metalctl_filesystemlayout_match/","page":"metalctl filesystemlayout match","title":"metalctl filesystemlayout match","text":"metalctl filesystemlayout match [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_filesystemlayout_match/#Options","page":"metalctl filesystemlayout match","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_filesystemlayout_match/","page":"metalctl filesystemlayout match","title":"metalctl filesystemlayout match","text":" --filesystemlayout string filesystemlayout id to check against [required]\n -h, --help help for match\n --machine string machine id to check for match [required]","category":"page"},{"location":"external/metalctl/docs/metalctl_filesystemlayout_match/#Options-inherited-from-parent-commands","page":"metalctl filesystemlayout match","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_filesystemlayout_match/","page":"metalctl filesystemlayout match","title":"metalctl filesystemlayout match","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_filesystemlayout_match/#SEE-ALSO","page":"metalctl filesystemlayout match","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_filesystemlayout_match/","page":"metalctl filesystemlayout match","title":"metalctl filesystemlayout match","text":"metalctl filesystemlayout\t - manage filesystemlayout entities","category":"page"},{"location":"external/metalctl/docs/metalctl_filesystemlayout_delete/#metalctl-filesystemlayout-delete","page":"metalctl filesystemlayout delete","title":"metalctl filesystemlayout delete","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_filesystemlayout_delete/","page":"metalctl filesystemlayout delete","title":"metalctl filesystemlayout delete","text":"deletes the filesystemlayout","category":"page"},{"location":"external/metalctl/docs/metalctl_filesystemlayout_delete/","page":"metalctl filesystemlayout delete","title":"metalctl filesystemlayout delete","text":"metalctl filesystemlayout delete [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_filesystemlayout_delete/#Options","page":"metalctl filesystemlayout delete","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_filesystemlayout_delete/","page":"metalctl filesystemlayout delete","title":"metalctl filesystemlayout delete","text":" --bulk-output when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.\n -f, --file string filename of the create or update request in yaml format, or - for stdin.\n \n Example:\n $ metalctl filesystemlayout describe filesystemlayout-1 -o yaml > filesystemlayout.yaml\n $ vi filesystemlayout.yaml\n $ # either via stdin\n $ cat filesystemlayout.yaml | metalctl filesystemlayout delete -f -\n $ # or via file\n $ metalctl filesystemlayout delete -f filesystemlayout.yaml\n \n the file can also contain multiple documents and perform a bulk operation.\n \t\n -h, --help help for delete\n --skip-security-prompts skips security prompt for bulk operations\n --timestamps when used with --file (bulk operation): prints timestamps in-between the operations","category":"page"},{"location":"external/metalctl/docs/metalctl_filesystemlayout_delete/#Options-inherited-from-parent-commands","page":"metalctl filesystemlayout delete","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_filesystemlayout_delete/","page":"metalctl filesystemlayout delete","title":"metalctl filesystemlayout delete","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_filesystemlayout_delete/#SEE-ALSO","page":"metalctl filesystemlayout delete","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_filesystemlayout_delete/","page":"metalctl filesystemlayout delete","title":"metalctl filesystemlayout delete","text":"metalctl filesystemlayout\t - manage filesystemlayout entities","category":"page"},{"location":"external/metalctl/docs/metalctl_network_ip_update/#metalctl-network-ip-update","page":"metalctl network ip update","title":"metalctl network ip update","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_network_ip_update/","page":"metalctl network ip update","title":"metalctl network ip update","text":"updates the ip","category":"page"},{"location":"external/metalctl/docs/metalctl_network_ip_update/","page":"metalctl network ip update","title":"metalctl network ip update","text":"metalctl network ip update [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_network_ip_update/#Options","page":"metalctl network ip update","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_network_ip_update/","page":"metalctl network ip update","title":"metalctl network ip update","text":" --bulk-output when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.\n -f, --file string filename of the create or update request in yaml format, or - for stdin.\n \n Example:\n $ metalctl ip describe ip-1 -o yaml > ip.yaml\n $ vi ip.yaml\n $ # either via stdin\n $ cat ip.yaml | metalctl ip update -f -\n $ # or via file\n $ metalctl ip update -f ip.yaml\n \n the file can also contain multiple documents and perform a bulk operation.\n \t\n -h, --help help for update\n --skip-security-prompts skips security prompt for bulk operations\n --timestamps when used with --file (bulk operation): prints timestamps in-between the operations","category":"page"},{"location":"external/metalctl/docs/metalctl_network_ip_update/#Options-inherited-from-parent-commands","page":"metalctl network ip update","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_network_ip_update/","page":"metalctl network ip update","title":"metalctl network ip update","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_network_ip_update/#SEE-ALSO","page":"metalctl network ip update","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_network_ip_update/","page":"metalctl network ip update","title":"metalctl network ip update","text":"metalctl network ip\t - manage ip entities","category":"page"},{"location":"external/metalctl/docs/metalctl_size_describe/#metalctl-size-describe","page":"metalctl size describe","title":"metalctl size describe","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_describe/","page":"metalctl size describe","title":"metalctl size describe","text":"describes the size","category":"page"},{"location":"external/metalctl/docs/metalctl_size_describe/","page":"metalctl size describe","title":"metalctl size describe","text":"metalctl size describe [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_size_describe/#Options","page":"metalctl size describe","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_describe/","page":"metalctl size describe","title":"metalctl size describe","text":" -h, --help help for describe","category":"page"},{"location":"external/metalctl/docs/metalctl_size_describe/#Options-inherited-from-parent-commands","page":"metalctl size describe","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_describe/","page":"metalctl size describe","title":"metalctl size describe","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_size_describe/#SEE-ALSO","page":"metalctl size describe","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_describe/","page":"metalctl size describe","title":"metalctl size describe","text":"metalctl size\t - manage size entities","category":"page"},{"location":"external/metalctl/docs/metalctl_tenant_apply/#metalctl-tenant-apply","page":"metalctl tenant apply","title":"metalctl tenant apply","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_tenant_apply/","page":"metalctl tenant apply","title":"metalctl tenant apply","text":"applies one or more tenants from a given file","category":"page"},{"location":"external/metalctl/docs/metalctl_tenant_apply/","page":"metalctl tenant apply","title":"metalctl tenant apply","text":"metalctl tenant apply [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_tenant_apply/#Options","page":"metalctl tenant apply","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_tenant_apply/","page":"metalctl tenant apply","title":"metalctl tenant apply","text":" --bulk-output when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.\n -f, --file string filename of the create or update request in yaml format, or - for stdin.\n \n Example:\n $ metalctl tenant describe tenant-1 -o yaml > tenant.yaml\n $ vi tenant.yaml\n $ # either via stdin\n $ cat tenant.yaml | metalctl tenant apply -f -\n $ # or via file\n $ metalctl tenant apply -f tenant.yaml\n \n the file can also contain multiple documents and perform a bulk operation.\n \t\n -h, --help help for apply\n --skip-security-prompts skips security prompt for bulk operations\n --timestamps when used with --file (bulk operation): prints timestamps in-between the operations","category":"page"},{"location":"external/metalctl/docs/metalctl_tenant_apply/#Options-inherited-from-parent-commands","page":"metalctl tenant apply","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_tenant_apply/","page":"metalctl tenant apply","title":"metalctl tenant apply","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_tenant_apply/#SEE-ALSO","page":"metalctl tenant apply","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_tenant_apply/","page":"metalctl tenant apply","title":"metalctl tenant apply","text":"metalctl tenant\t - manage tenant entities","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_power_off/#metalctl-machine-power-off","page":"metalctl machine power off","title":"metalctl machine power off","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_power_off/","page":"metalctl machine power off","title":"metalctl machine power off","text":"power off a machine","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_power_off/#Synopsis","page":"metalctl machine power off","title":"Synopsis","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_power_off/","page":"metalctl machine power off","title":"metalctl machine power off","text":"set the machine to power off state, if the machine already was off nothing happens. It will usually take some time to power off the machine, depending on the machine type. Power on will therefore not work if the machine is in the powering off phase.","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_power_off/","page":"metalctl machine power off","title":"metalctl machine power off","text":"metalctl machine power off [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_power_off/#Options","page":"metalctl machine power off","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_power_off/","page":"metalctl machine power off","title":"metalctl machine power off","text":" -h, --help help for off","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_power_off/#Options-inherited-from-parent-commands","page":"metalctl machine power off","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_power_off/","page":"metalctl machine power off","title":"metalctl machine power off","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_power_off/#SEE-ALSO","page":"metalctl machine power off","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_power_off/","page":"metalctl machine power off","title":"metalctl machine power off","text":"metalctl machine power\t - manage machine power","category":"page"},{"location":"external/metalctl/docs/metalctl_project_describe/#metalctl-project-describe","page":"metalctl project describe","title":"metalctl project describe","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_project_describe/","page":"metalctl project describe","title":"metalctl project describe","text":"describes the project","category":"page"},{"location":"external/metalctl/docs/metalctl_project_describe/","page":"metalctl project describe","title":"metalctl project describe","text":"metalctl project describe [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_project_describe/#Options","page":"metalctl project describe","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_project_describe/","page":"metalctl project describe","title":"metalctl project describe","text":" -h, --help help for describe","category":"page"},{"location":"external/metalctl/docs/metalctl_project_describe/#Options-inherited-from-parent-commands","page":"metalctl project describe","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_project_describe/","page":"metalctl project describe","title":"metalctl project describe","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_project_describe/#SEE-ALSO","page":"metalctl project describe","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_project_describe/","page":"metalctl project describe","title":"metalctl project describe","text":"metalctl project\t - manage project entities","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_logs/#metalctl-machine-logs","page":"metalctl machine logs","title":"metalctl machine logs","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_logs/","page":"metalctl machine logs","title":"metalctl machine logs","text":"display machine provisioning logs","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_logs/","page":"metalctl machine logs","title":"metalctl machine logs","text":"metalctl machine logs [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_logs/#Options","page":"metalctl machine logs","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_logs/","page":"metalctl machine logs","title":"metalctl machine logs","text":" -h, --help help for logs\n --last-event-error-threshold duration the duration up to how long in the past a machine last event error will be counted as an issue [optional] (default 168h0m0s)","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_logs/#Options-inherited-from-parent-commands","page":"metalctl machine logs","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_logs/","page":"metalctl machine logs","title":"metalctl machine logs","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_logs/#SEE-ALSO","page":"metalctl machine logs","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_logs/","page":"metalctl machine logs","title":"metalctl machine logs","text":"metalctl machine\t - manage machine entities","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_power_cycle/#metalctl-machine-power-cycle","page":"metalctl machine power cycle","title":"metalctl machine power cycle","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_power_cycle/","page":"metalctl machine power cycle","title":"metalctl machine power cycle","text":"power cycle a machine (graceful shutdown)","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_power_cycle/#Synopsis","page":"metalctl machine power cycle","title":"Synopsis","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_power_cycle/","page":"metalctl machine power cycle","title":"metalctl machine power cycle","text":"(soft) cycle the machine power.","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_power_cycle/","page":"metalctl machine power cycle","title":"metalctl machine power cycle","text":"metalctl machine power cycle [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_power_cycle/#Options","page":"metalctl machine power cycle","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_power_cycle/","page":"metalctl machine power cycle","title":"metalctl machine power cycle","text":" -h, --help help for cycle","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_power_cycle/#Options-inherited-from-parent-commands","page":"metalctl machine power cycle","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_power_cycle/","page":"metalctl machine power cycle","title":"metalctl machine power cycle","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_power_cycle/#SEE-ALSO","page":"metalctl machine power cycle","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_power_cycle/","page":"metalctl machine power cycle","title":"metalctl machine power cycle","text":"metalctl machine power\t - manage machine power","category":"page"},{"location":"external/metalctl/docs/metalctl_image/#metalctl-image","page":"metalctl image","title":"metalctl image","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_image/","page":"metalctl image","title":"metalctl image","text":"manage image entities","category":"page"},{"location":"external/metalctl/docs/metalctl_image/#Synopsis","page":"metalctl image","title":"Synopsis","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_image/","page":"metalctl image","title":"metalctl image","text":"os images available to be installed on machines.","category":"page"},{"location":"external/metalctl/docs/metalctl_image/#Options","page":"metalctl image","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_image/","page":"metalctl image","title":"metalctl image","text":" -h, --help help for image","category":"page"},{"location":"external/metalctl/docs/metalctl_image/#Options-inherited-from-parent-commands","page":"metalctl image","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_image/","page":"metalctl image","title":"metalctl image","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_image/#SEE-ALSO","page":"metalctl image","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_image/","page":"metalctl image","title":"metalctl image","text":"metalctl\t - a cli to manage entities in the metal-stack api\nmetalctl image apply\t - applies one or more images from a given file\nmetalctl image create\t - creates the image\nmetalctl image delete\t - deletes the image\nmetalctl image describe\t - describes the image\nmetalctl image edit\t - edit the image through an editor and update\nmetalctl image list\t - list all images\nmetalctl image update\t - updates the image","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_console/#metalctl-machine-console","page":"metalctl machine console","title":"metalctl machine console","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_console/","page":"metalctl machine console","title":"metalctl machine console","text":"console access to a machine","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_console/#Synopsis","page":"metalctl machine console","title":"Synopsis","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_console/","page":"metalctl machine console","title":"metalctl machine console","text":"console access to a machine, machine must be created with a ssh public key, authentication is done with your private key. In case the machine did not register properly a direct ipmi console access is available via the –ipmi flag. This is only for administrative access.","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_console/","page":"metalctl machine console","title":"metalctl machine console","text":"metalctl machine console [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_console/#Options","page":"metalctl machine console","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_console/","page":"metalctl machine console","title":"metalctl machine console","text":" --admin authenticate as admin (admin only).\n -h, --help help for console\n --ipmi use ipmitool with direct network access (admin only).\n --ipmipassword string overwrite ipmi password (admin only).\n --ipmiuser string overwrite ipmi user (admin only).\n -i, --sshidentity string SSH key file, if not given the default ssh key will be used if present [optional].","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_console/#Options-inherited-from-parent-commands","page":"metalctl machine console","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_console/","page":"metalctl machine console","title":"metalctl machine console","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_console/#SEE-ALSO","page":"metalctl machine console","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_console/","page":"metalctl machine console","title":"metalctl machine console","text":"metalctl machine\t - manage machine entities","category":"page"},{"location":"external/metalctl/docs/metalctl_project/#metalctl-project","page":"metalctl project","title":"metalctl project","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_project/","page":"metalctl project","title":"metalctl project","text":"manage project entities","category":"page"},{"location":"external/metalctl/docs/metalctl_project/#Synopsis","page":"metalctl project","title":"Synopsis","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_project/","page":"metalctl project","title":"metalctl project","text":"a project belongs to a tenant and groups together entities in metal-stack.","category":"page"},{"location":"external/metalctl/docs/metalctl_project/#Options","page":"metalctl project","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_project/","page":"metalctl project","title":"metalctl project","text":" -h, --help help for project","category":"page"},{"location":"external/metalctl/docs/metalctl_project/#Options-inherited-from-parent-commands","page":"metalctl project","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_project/","page":"metalctl project","title":"metalctl project","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_project/#SEE-ALSO","page":"metalctl project","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_project/","page":"metalctl project","title":"metalctl project","text":"metalctl\t - a cli to manage entities in the metal-stack api\nmetalctl project apply\t - applies one or more projects from a given file\nmetalctl project create\t - creates the project\nmetalctl project delete\t - deletes the project\nmetalctl project describe\t - describes the project\nmetalctl project edit\t - edit the project through an editor and update\nmetalctl project list\t - list all projects\nmetalctl project update\t - updates the project","category":"page"},{"location":"external/metalctl/docs/metalctl_image_list/#metalctl-image-list","page":"metalctl image list","title":"metalctl image list","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_image_list/","page":"metalctl image list","title":"metalctl image list","text":"list all images","category":"page"},{"location":"external/metalctl/docs/metalctl_image_list/","page":"metalctl image list","title":"metalctl image list","text":"metalctl image list [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_image_list/#Options","page":"metalctl image list","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_image_list/","page":"metalctl image list","title":"metalctl image list","text":" --classification string Classification of this image.\n --features string Features of this image.\n -h, --help help for list\n --id string ID of the image.\n --name string Name of the image.\n --os string OS derivate of this image.\n --show-usage show from how many allocated machines every image is used\n --sort-by strings sort by (comma separated) column(s), sort direction can be changed by appending :asc or :desc behind the column identifier. possible values: classification|description|expiration|id|name\n --version string Version of this image.","category":"page"},{"location":"external/metalctl/docs/metalctl_image_list/#Options-inherited-from-parent-commands","page":"metalctl image list","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_image_list/","page":"metalctl image list","title":"metalctl image list","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_image_list/#SEE-ALSO","page":"metalctl image list","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_image_list/","page":"metalctl image list","title":"metalctl image list","text":"metalctl image\t - manage image entities","category":"page"},{"location":"external/metalctl/docs/metalctl_partition_update/#metalctl-partition-update","page":"metalctl partition update","title":"metalctl partition update","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_partition_update/","page":"metalctl partition update","title":"metalctl partition update","text":"updates the partition","category":"page"},{"location":"external/metalctl/docs/metalctl_partition_update/","page":"metalctl partition update","title":"metalctl partition update","text":"metalctl partition update [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_partition_update/#Options","page":"metalctl partition update","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_partition_update/","page":"metalctl partition update","title":"metalctl partition update","text":" --bulk-output when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.\n -f, --file string filename of the create or update request in yaml format, or - for stdin.\n \n Example:\n $ metalctl partition describe partition-1 -o yaml > partition.yaml\n $ vi partition.yaml\n $ # either via stdin\n $ cat partition.yaml | metalctl partition update -f -\n $ # or via file\n $ metalctl partition update -f partition.yaml\n \n the file can also contain multiple documents and perform a bulk operation.\n \t\n -h, --help help for update\n --skip-security-prompts skips security prompt for bulk operations\n --timestamps when used with --file (bulk operation): prints timestamps in-between the operations","category":"page"},{"location":"external/metalctl/docs/metalctl_partition_update/#Options-inherited-from-parent-commands","page":"metalctl partition update","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_partition_update/","page":"metalctl partition update","title":"metalctl partition update","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_partition_update/#SEE-ALSO","page":"metalctl partition update","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_partition_update/","page":"metalctl partition update","title":"metalctl partition update","text":"metalctl partition\t - manage partition entities","category":"page"},{"location":"external/metalctl/docs/metalctl_project_edit/#metalctl-project-edit","page":"metalctl project edit","title":"metalctl project edit","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_project_edit/","page":"metalctl project edit","title":"metalctl project edit","text":"edit the project through an editor and update","category":"page"},{"location":"external/metalctl/docs/metalctl_project_edit/","page":"metalctl project edit","title":"metalctl project edit","text":"metalctl project edit [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_project_edit/#Options","page":"metalctl project edit","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_project_edit/","page":"metalctl project edit","title":"metalctl project edit","text":" -h, --help help for edit","category":"page"},{"location":"external/metalctl/docs/metalctl_project_edit/#Options-inherited-from-parent-commands","page":"metalctl project edit","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_project_edit/","page":"metalctl project edit","title":"metalctl project edit","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_project_edit/#SEE-ALSO","page":"metalctl project edit","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_project_edit/","page":"metalctl project edit","title":"metalctl project edit","text":"metalctl project\t - manage project entities","category":"page"},{"location":"installation/troubleshoot/#Troubleshoot","page":"Troubleshoot","title":"Troubleshoot","text":"","category":"section"},{"location":"installation/troubleshoot/","page":"Troubleshoot","title":"Troubleshoot","text":"This document summarizes help when something goes wrong and provides advice on debugging the metal-stack in certain situations.","category":"page"},{"location":"installation/troubleshoot/","page":"Troubleshoot","title":"Troubleshoot","text":"Of course, it is also advisable to check out the issues on the Github projects for help.","category":"page"},{"location":"installation/troubleshoot/","page":"Troubleshoot","title":"Troubleshoot","text":"If you still can't find a solution to your problem, please reach out to us and our community. We have a public Slack Channel to discuss problems, but you can also reach us via mail. Check out metal-stack.io for contact information.","category":"page"},{"location":"installation/troubleshoot/","page":"Troubleshoot","title":"Troubleshoot","text":"Pages = [\"troubleshoot.md\"]\nDepth = 5","category":"page"},{"location":"installation/troubleshoot/#Deployment","page":"Troubleshoot","title":"Deployment","text":"","category":"section"},{"location":"installation/troubleshoot/#Ansible-fails-when-the-metal-control-plane-helm-chart-gets-applied","page":"Troubleshoot","title":"Ansible fails when the metal control plane helm chart gets applied","text":"","category":"section"},{"location":"installation/troubleshoot/","page":"Troubleshoot","title":"Troubleshoot","text":"There can be many reasons for this. Since you are deploying the metal control plane into a Kubernetes cluster, the first step should be to install kubectl and check the pods in your cluster. Depending on the metal-stack version and Kubernetes cluster, your control-plane should look something like this after the deployment (this is in a Kind cluster):","category":"page"},{"location":"installation/troubleshoot/","page":"Troubleshoot","title":"Troubleshoot","text":"kubectl get pod -A\nNAMESPACE NAME READY STATUS RESTARTS AGE\ningress-nginx nginx-ingress-controller-56966f7dc7-khfp9 1/1 Running 0 2m34s\nkube-system coredns-66bff467f8-grn7q 1/1 Running 0 2m34s\nkube-system coredns-66bff467f8-n7n77 1/1 Running 0 2m34s\nkube-system etcd-kind-control-plane 1/1 Running 0 2m42s\nkube-system kindnet-4dv7m 1/1 Running 0 2m34s\nkube-system kube-apiserver-kind-control-plane 1/1 Running 0 2m42s\nkube-system kube-controller-manager-kind-control-plane 1/1 Running 0 2m42s\nkube-system kube-proxy-jz7kp 1/1 Running 0 2m34s\nkube-system kube-scheduler-kind-control-plane 1/1 Running 0 2m42s\nlocal-path-storage local-path-provisioner-bd4bb6b75-cwfb7 1/1 Running 0 2m34s\nmetal-control-plane ipam-db-0 2/2 Running 0 2m31s\nmetal-control-plane masterdata-api-6dd4b54db5-rwk45 1/1 Running 0 33s\nmetal-control-plane masterdata-db-0 2/2 Running 0 2m29s\nmetal-control-plane metal-api-998cb46c4-jj2tt 1/1 Running 0 33s\nmetal-control-plane metal-api-initdb-r9sc6 0/1 Completed 0 2m24s\nmetal-control-plane metal-api-liveliness-1590479940-brhc7 0/1 Completed 0 6s\nmetal-control-plane metal-console-7955cbb7d7-p6hxp 1/1 Running 0 33s\nmetal-control-plane metal-db-0 2/2 Running 0 2m34s\nmetal-control-plane nsq-lookupd-5b4ccbfb64-n6prg 1/1 Running 0 2m34s\nmetal-control-plane nsqd-6cd87f69c4-vtn9k 2/2 Running 0 2m33s","category":"page"},{"location":"installation/troubleshoot/","page":"Troubleshoot","title":"Troubleshoot","text":"If there are any failing pods, investigate those and look into container logs. This information should point you to the place where the deployment goes wrong.","category":"page"},{"location":"installation/troubleshoot/","page":"Troubleshoot","title":"Troubleshoot","text":"info: Info\nSometimes, you see a helm errors like \"no deployed releases\" or something like this. When a helm chart fails after the first deployment it could be that you have a chart installation still pending. Also, the control plane helm chart uses pre- and post-hooks, which creates jobs that helm expects to be completed before attempting another deployment. Delete the helm chart (use Helm 3) with helm delete -n metal-control-plane metal-control-plane and delete the jobs in the metal-control-plane namespace before retrying the deployment.","category":"page"},{"location":"installation/troubleshoot/#In-the-mini-lab-the-control-plane-deployment-fails-because-my-system-can't-resolve-api.172.17.0.1.nip.io","page":"Troubleshoot","title":"In the mini-lab the control-plane deployment fails because my system can't resolve api.172.17.0.1.nip.io","text":"","category":"section"},{"location":"installation/troubleshoot/","page":"Troubleshoot","title":"Troubleshoot","text":"The control-plane deployment returns an error like this:","category":"page"},{"location":"installation/troubleshoot/","page":"Troubleshoot","title":"Troubleshoot","text":"deploy-control-plane | fatal: [localhost]: FAILED! => changed=false\ndeploy-control-plane | attempts: 60\ndeploy-control-plane | content: ''\ndeploy-control-plane | elapsed: 0\ndeploy-control-plane | msg: 'Status code was -1 and not [200]: Request failed: '\ndeploy-control-plane | redirected: false\ndeploy-control-plane | status: -1\ndeploy-control-plane | url: http://api.172.17.0.1.nip.io:8080/metal/v1/health\ndeploy-control-plane |\ndeploy-control-plane | PLAY RECAP *********************************************************************\ndeploy-control-plane | localhost : ok=29 changed=4 unreachable=0 failed=1 skipped=7 rescued=0 ignored=0\ndeploy-control-plane |\ndeploy-control-plane exited with code 2","category":"page"},{"location":"installation/troubleshoot/","page":"Troubleshoot","title":"Troubleshoot","text":"Some home routers have a security feature that prevents DNS Servers to resolve anything in the router's local IP range (DNS-Rebind-Protection).","category":"page"},{"location":"installation/troubleshoot/","page":"Troubleshoot","title":"Troubleshoot","text":"You need to add an exception for nip.io in your router configuration or add 127.0.0.1 api.172.17.0.1.nip.io to your /etc/hosts.","category":"page"},{"location":"installation/troubleshoot/#FritzBox","page":"Troubleshoot","title":"FritzBox","text":"","category":"section"},{"location":"installation/troubleshoot/","page":"Troubleshoot","title":"Troubleshoot","text":"Home Network -> Network -> Network Settings -> Additional Settings -> DNS Rebind Protection -> Host name exceptions -> nip.io","category":"page"},{"location":"installation/troubleshoot/#Operations","page":"Troubleshoot","title":"Operations","text":"","category":"section"},{"location":"installation/troubleshoot/#Fixing-Machine-Issues","page":"Troubleshoot","title":"Fixing Machine Issues","text":"","category":"section"},{"location":"installation/troubleshoot/","page":"Troubleshoot","title":"Troubleshoot","text":"The metalctl machine issues command gives you an overview over machines in your metal-stack environment that are in an unusual state.","category":"page"},{"location":"installation/troubleshoot/","page":"Troubleshoot","title":"Troubleshoot","text":"tip: Tip\nMachines that are known not to function properly, should be locked through metalctl machine lock and annotated with a description of the problem. This way, you can mark machine for replacement without being in danger of having a user allocating the faulty machine.","category":"page"},{"location":"installation/troubleshoot/","page":"Troubleshoot","title":"Troubleshoot","text":"In the following sections, you can look up the machine issues that are returned by metalctl and find out how to deal with them properly.","category":"page"},{"location":"installation/troubleshoot/#no-event-container","page":"Troubleshoot","title":"no-event-container","text":"","category":"section"},{"location":"installation/troubleshoot/","page":"Troubleshoot","title":"Troubleshoot","text":"Every machine in the metal-stack database usually has a corresponding event container where provisioning events are stored. This database entity gets created lazily as soon as a machine is registered by the metal-hammer or a provisioning event for the machine arrives at the metal-api.","category":"page"},{"location":"installation/troubleshoot/","page":"Troubleshoot","title":"Troubleshoot","text":"When there is no event container, this means that the machine has never registered nor received a provisioning event. As an operator you should evaluate why this machine is not booting into the metal-hammer.","category":"page"},{"location":"installation/troubleshoot/","page":"Troubleshoot","title":"Troubleshoot","text":"This issue is special in a way that it prevents other issues from being evaluated for this machine because the issue calculation usually requires information from the machine event container.","category":"page"},{"location":"installation/troubleshoot/#no-partition","page":"Troubleshoot","title":"no-partition","text":"","category":"section"},{"location":"installation/troubleshoot/","page":"Troubleshoot","title":"Troubleshoot","text":"When a machine has no partition, the metal-hammer has not yet registered the machine at the metal-api. Instead, the machine was created through metal-stack's event machinery, which does not have a lot of information about a machine (e.g. a PXE boot event was reported from the pixiecore), or just by the metal-bmc which discovered the machine through DHCP.","category":"page"},{"location":"installation/troubleshoot/","page":"Troubleshoot","title":"Troubleshoot","text":"This can usually happen on the very first boot of a machine and the machine's hardware is not supported by metal-stack, leading to the metal-bmc being unable to report BMC details to the metal-api (a metal-bmc report sets the partition id of a machine) and the metal-hammer not finishing the machine registration phase.","category":"page"},{"location":"installation/troubleshoot/","page":"Troubleshoot","title":"Troubleshoot","text":"To resolve this issue, you need to identify the machine in your metal-stack partition that emits PXE boot events and find the reason why it is not properly booting into the metal-hammer. The console logs of this machine should enable you to find out the root cause.","category":"page"},{"location":"installation/troubleshoot/#liveliness-dead","page":"Troubleshoot","title":"liveliness-dead","text":"","category":"section"},{"location":"installation/troubleshoot/","page":"Troubleshoot","title":"Troubleshoot","text":"For machines without an allocation, the metal-hammer consistently reports whether a machine is still being responsive or not. When the liveliness is Dead, there were no events received from this machine for longer than ~5 minutes.","category":"page"},{"location":"installation/troubleshoot/","page":"Troubleshoot","title":"Troubleshoot","text":"Reasons for this can be:","category":"page"},{"location":"installation/troubleshoot/","page":"Troubleshoot","title":"Troubleshoot","text":"The network connection between the partition and metal-stack control plane is interrupted\nThe machine was removed from your data center\nThe machine has changed its UUID metal-hammer#52\nThe machine is turned off\nThe machine hangs / freezes\nThe machine booted to BIOS or UEFI shell and does not try to PXE boot again\nThe issue only appears temporarily\nThe machine takes longer than 5 minutes for the reboot\nThe machine is performing a firmware upgrade, which usually takes longer than 5 minutes to succeed","category":"page"},{"location":"installation/troubleshoot/","page":"Troubleshoot","title":"Troubleshoot","text":"info: Info\nIn order to minimize maintenance overhead, a machine which is dead for longer than an hour will be rebooted through the metal-api.In case you want to prevent this action from happening for a machine, you can lock the machine through metalctl machine lock.","category":"page"},{"location":"installation/troubleshoot/","page":"Troubleshoot","title":"Troubleshoot","text":"If the machine is dead for a long time and you are sure that it will never come back, you can clean up the machine through metalctl machine rm --remove-from-database.","category":"page"},{"location":"installation/troubleshoot/#liveliness-unknown","page":"Troubleshoot","title":"liveliness-unknown","text":"","category":"section"},{"location":"installation/troubleshoot/","page":"Troubleshoot","title":"Troubleshoot","text":"For machines that are allocated by a user, the ownership has gone over to this user and as an operator you cannot access the machine anymore. This makes it harder to detect whether a machine is in a healthy state or not. Typically, all official metal-stack OS images deploy an LLDP daemon, that consistently emits alive messages. These messages are caught by the metal-core and turned into a Phoned Home event. Internally, the metal-api uses these events as an indicator to decide whether the machine is still responsive or not.","category":"page"},{"location":"installation/troubleshoot/","page":"Troubleshoot","title":"Troubleshoot","text":"When the LLDP daemon stopped sending packages, the reasons are identical to those of dead machines. However, it's not possible anymore to decide whether the user is responsible for reaching this state or not.","category":"page"},{"location":"installation/troubleshoot/","page":"Troubleshoot","title":"Troubleshoot","text":"In most of the cases, there is not much that can be done from the operator's perspective. You will need to wait for the user to report an issue with the machine. When you do support, you can use this issue type to quickly identify this machine.","category":"page"},{"location":"installation/troubleshoot/#liveliness-not-available","page":"Troubleshoot","title":"liveliness-not-available","text":"","category":"section"},{"location":"installation/troubleshoot/","page":"Troubleshoot","title":"Troubleshoot","text":"This is more of a theoretical issue. When the machine liveliness is not available check that the Kubernetes CronJob in the metal-stack control plane for evaluating the machine liveliness is running regularly and not containing error logs. Make the machine boot into the metal-hammer and this issue should not appear.","category":"page"},{"location":"installation/troubleshoot/#failed-machine-reclaim","page":"Troubleshoot","title":"failed-machine-reclaim","text":"","category":"section"},{"location":"installation/troubleshoot/","page":"Troubleshoot","title":"Troubleshoot","text":"If a machine remains in the Phoned Home state without having an allocation, this indicates that the metal-bmc was not able to put the machine back into PXE boot mode after metalctl machine rm. The machine is still running the operating system and it does not return back into the allocatable machine pool. Effectively, you lost a machine in your environment and no-one pays for it. Therefore, you should resolve this issue as soon as possible.","category":"page"},{"location":"installation/troubleshoot/","page":"Troubleshoot","title":"Troubleshoot","text":"In bad scenarios, when the machine was a firewall, the machine can still reach the internet through the PXE boot network and also attract traffic, which it cannot route anymore inside the tenant VRF. This can cause traffic loss inside a tenant network.","category":"page"},{"location":"installation/troubleshoot/","page":"Troubleshoot","title":"Troubleshoot","text":"In most of the cases, it should be sufficient to run another metalctl machine rm on this machine in order to retry booting into PXE mode. If this still does not succeed, you can boot the machine into the BIOS and manually and change the boot order to PXE boot. This should force booting the metal-hammer again and add the machine back into your pool of allocatable machines.","category":"page"},{"location":"installation/troubleshoot/","page":"Troubleshoot","title":"Troubleshoot","text":"For further reference, see metal-api#145.","category":"page"},{"location":"installation/troubleshoot/#crashloop","page":"Troubleshoot","title":"crashloop","text":"","category":"section"},{"location":"installation/troubleshoot/","page":"Troubleshoot","title":"Troubleshoot","text":"Under bad circumstances, a machine diverges from its typical machine lifecycle. When this happens, the internal state-machine of the metal-api detects that the machine reboots unexpectedly during the provisioning phase. It is likely that the machine has entered a crash loop where it PXE boots again and again without the machine ever becoming usable.","category":"page"},{"location":"installation/troubleshoot/","page":"Troubleshoot","title":"Troubleshoot","text":"Reasons for this can be:","category":"page"},{"location":"installation/troubleshoot/","page":"Troubleshoot","title":"Troubleshoot","text":"The machine's hardware is not supported and the metal-hammer crashes during the machine discovery\nThe machine registration fails through the metal-hammer because an orphaned / dead machine is still present in the metal-api's data base. The machine is connected to the same switch ports that were used by the orphaned machine. In this case, you should clean up the orphaned machine through metalctl machine rm --remove-from-database.","category":"page"},{"location":"installation/troubleshoot/","page":"Troubleshoot","title":"Troubleshoot","text":"Please also consider console logs of the machine for investigating the issue.","category":"page"},{"location":"installation/troubleshoot/","page":"Troubleshoot","title":"Troubleshoot","text":"The incomplete cycle count is reset as soon as the machine reaches Phoned Home state or there is a Planned Reboot of the machine (planned reboot is also done by the metal-hammer once a day in order to reboot with the latest version).","category":"page"},{"location":"installation/troubleshoot/#last-event-error","page":"Troubleshoot","title":"last-event-error","text":"","category":"section"},{"location":"installation/troubleshoot/","page":"Troubleshoot","title":"Troubleshoot","text":"The machine had an error during the provisioning lifecycle recently or events are arriving out of order at the metal-api. This can be an interesting hint for the operator that something during machine provisioning went wrong. You can look at the error through metalctl machine describe or metalctl machine logs.","category":"page"},{"location":"installation/troubleshoot/","page":"Troubleshoot","title":"Troubleshoot","text":"This error will disappear after a certain time period from machine issues. You can still look up the error as described above.","category":"page"},{"location":"installation/troubleshoot/#asn-not-unique","page":"Troubleshoot","title":"asn-not-unique","text":"","category":"section"},{"location":"installation/troubleshoot/","page":"Troubleshoot","title":"Troubleshoot","text":"This issue was introduced by a bug in earlier versions of metal-stack and was fixed in PR105","category":"page"},{"location":"installation/troubleshoot/","page":"Troubleshoot","title":"Troubleshoot","text":"To resolve the issue, you need to recreate the firewalls that use the same ASN.","category":"page"},{"location":"installation/troubleshoot/#bmc-without-mac","page":"Troubleshoot","title":"bmc-without-mac","text":"","category":"section"},{"location":"installation/troubleshoot/","page":"Troubleshoot","title":"Troubleshoot","text":"The metal-bmc is responsible to report connection data for the machine's BMC.","category":"page"},{"location":"installation/troubleshoot/","page":"Troubleshoot","title":"Troubleshoot","text":"If it's uncapable of discovering this information, your hardware might not be supported. Please investigate the logs of the metal-bmc to find out what's going wrong with this machine.","category":"page"},{"location":"installation/troubleshoot/#bmc-without-ip","page":"Troubleshoot","title":"bmc-without-ip","text":"","category":"section"},{"location":"installation/troubleshoot/","page":"Troubleshoot","title":"Troubleshoot","text":"The metal-bmc is responsible to report connection data for the machine's BMC.","category":"page"},{"location":"installation/troubleshoot/","page":"Troubleshoot","title":"Troubleshoot","text":"If it's uncapable of discovering this information, your hardware might not be supported. Please investigate the logs of the metal-bmc to find out what's going wrong with this machine.","category":"page"},{"location":"installation/troubleshoot/#bmc-no-distinct-ip","page":"Troubleshoot","title":"bmc-no-distinct-ip","text":"","category":"section"},{"location":"installation/troubleshoot/","page":"Troubleshoot","title":"Troubleshoot","text":"The metal-bmc is responsible to report connection data for the machine's BMC.","category":"page"},{"location":"installation/troubleshoot/","page":"Troubleshoot","title":"Troubleshoot","text":"When there is no distinct IP address for the BMC, it can be that an orphaned machine used this IP in the past. In this case, you need to clean up the orphaned machine through metalctl machine rm --remove-from-database.","category":"page"},{"location":"installation/troubleshoot/#bmc-info-outdated","page":"Troubleshoot","title":"bmc-info-outdated","text":"","category":"section"},{"location":"installation/troubleshoot/","page":"Troubleshoot","title":"Troubleshoot","text":"The metal-bmc is responsible to report bmc details for the machine's BMC.","category":"page"},{"location":"installation/troubleshoot/","page":"Troubleshoot","title":"Troubleshoot","text":"When the metal-bmc was not able to fetch the bmc info for longer than 20 minutes, something is wrong with the BMC configuration of the machine. This can be caused by one of the following reasons:","category":"page"},{"location":"installation/troubleshoot/","page":"Troubleshoot","title":"Troubleshoot","text":"Wrong password for the root user is configured in the BMC\nip address of the BMC is either wrong or not present\nthe device on the given ip address is not a machine, maybe a switch or a management component which is not managed by the metal-api","category":"page"},{"location":"installation/troubleshoot/","page":"Troubleshoot","title":"Troubleshoot","text":"In either case, please check the logs for the given machine UUID on the metal-bmc for further details. Also check that the metal-bmc is configured to only consider BMC IPs in the range they are configured from the DHCP server in the partition. This prevents grabbing unrelated BMCs.","category":"page"},{"location":"installation/troubleshoot/#A-machine-has-registered-with-a-different-UUID-after-reboot","page":"Troubleshoot","title":"A machine has registered with a different UUID after reboot","text":"","category":"section"},{"location":"installation/troubleshoot/","page":"Troubleshoot","title":"Troubleshoot","text":"metal-stack heavily relies on steady machine UUIDs as the UUID is the primary key of the machine entity in the metal-api.","category":"page"},{"location":"installation/troubleshoot/","page":"Troubleshoot","title":"Troubleshoot","text":"For further reference also see metal-stack/metal-hammer#52.","category":"page"},{"location":"installation/troubleshoot/#Reasons","page":"Troubleshoot","title":"Reasons","text":"","category":"section"},{"location":"installation/troubleshoot/","page":"Troubleshoot","title":"Troubleshoot","text":"There are some scenarios (can be vendor-specific), which can cause a machine UUID to change over time, e.g.:","category":"page"},{"location":"installation/troubleshoot/","page":"Troubleshoot","title":"Troubleshoot","text":"When the UUID partly contains of a network card's mac address, it can happen when:\nExchanging network cards\nDisabling network cards through BIOS\nChanging the UUID through vendor-specific CLI tool","category":"page"},{"location":"installation/troubleshoot/#Solution","page":"Troubleshoot","title":"Solution","text":"","category":"section"},{"location":"installation/troubleshoot/","page":"Troubleshoot","title":"Troubleshoot","text":"After five minutes, the orphaned machine UUID will be marked dead (💀) because machine events will be sent only to the most recent UUID\nIdentify the dead machine through metalctl machine ls\nRemove the dead machine forcefully with metalctl machine rm --remove-from-database --yes-i-really-mean-it ","category":"page"},{"location":"installation/troubleshoot/#Fixing-Switch-Issues","page":"Troubleshoot","title":"Fixing Switch Issues","text":"","category":"section"},{"location":"installation/troubleshoot/#switch-sync-failing","page":"Troubleshoot","title":"switch-sync-failing","text":"","category":"section"},{"location":"installation/troubleshoot/","page":"Troubleshoot","title":"Troubleshoot","text":"For your network infrastructure it is key to adapt to new configuration. In case this sync process fails for more than 10 minutes, it is likely to require manual investigation.","category":"page"},{"location":"installation/troubleshoot/","page":"Troubleshoot","title":"Troubleshoot","text":"Depending on your switch operating system, the error sources might differ a lot. Try to connect to your switch using the console or ssh and investigate the logs. Check if the hard drive is full.","category":"page"},{"location":"external/metalctl/docs/metalctl_network_ip_delete/#metalctl-network-ip-delete","page":"metalctl network ip delete","title":"metalctl network ip delete","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_network_ip_delete/","page":"metalctl network ip delete","title":"metalctl network ip delete","text":"deletes the ip","category":"page"},{"location":"external/metalctl/docs/metalctl_network_ip_delete/","page":"metalctl network ip delete","title":"metalctl network ip delete","text":"metalctl network ip delete [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_network_ip_delete/#Options","page":"metalctl network ip delete","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_network_ip_delete/","page":"metalctl network ip delete","title":"metalctl network ip delete","text":" --bulk-output when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.\n -f, --file string filename of the create or update request in yaml format, or - for stdin.\n \n Example:\n $ metalctl ip describe ip-1 -o yaml > ip.yaml\n $ vi ip.yaml\n $ # either via stdin\n $ cat ip.yaml | metalctl ip delete -f -\n $ # or via file\n $ metalctl ip delete -f ip.yaml\n \n the file can also contain multiple documents and perform a bulk operation.\n \t\n -h, --help help for delete\n --skip-security-prompts skips security prompt for bulk operations\n --timestamps when used with --file (bulk operation): prints timestamps in-between the operations","category":"page"},{"location":"external/metalctl/docs/metalctl_network_ip_delete/#Options-inherited-from-parent-commands","page":"metalctl network ip delete","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_network_ip_delete/","page":"metalctl network ip delete","title":"metalctl network ip delete","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_network_ip_delete/#SEE-ALSO","page":"metalctl network ip delete","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_network_ip_delete/","page":"metalctl network ip delete","title":"metalctl network ip delete","text":"metalctl network ip\t - manage ip entities","category":"page"},{"location":"external/metalctl/docs/metalctl_network_ip_describe/#metalctl-network-ip-describe","page":"metalctl network ip describe","title":"metalctl network ip describe","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_network_ip_describe/","page":"metalctl network ip describe","title":"metalctl network ip describe","text":"describes the ip","category":"page"},{"location":"external/metalctl/docs/metalctl_network_ip_describe/","page":"metalctl network ip describe","title":"metalctl network ip describe","text":"metalctl network ip describe [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_network_ip_describe/#Options","page":"metalctl network ip describe","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_network_ip_describe/","page":"metalctl network ip describe","title":"metalctl network ip describe","text":" -h, --help help for describe","category":"page"},{"location":"external/metalctl/docs/metalctl_network_ip_describe/#Options-inherited-from-parent-commands","page":"metalctl network ip describe","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_network_ip_describe/","page":"metalctl network ip describe","title":"metalctl network ip describe","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_network_ip_describe/#SEE-ALSO","page":"metalctl network ip describe","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_network_ip_describe/","page":"metalctl network ip describe","title":"metalctl network ip describe","text":"metalctl network ip\t - manage ip entities","category":"page"},{"location":"development/proposals/#Metal-Stack-Enhancement-Proposals-(MEPs)","page":"Enhancement Proposals","title":"Metal Stack Enhancement Proposals (MEPs)","text":"","category":"section"},{"location":"development/proposals/","page":"Enhancement Proposals","title":"Enhancement Proposals","text":"This section contains proposals which address substantial modifications to metal-stack.","category":"page"},{"location":"development/proposals/","page":"Enhancement Proposals","title":"Enhancement Proposals","text":"Every proposal has a short name which starts with MEP followed by an incremental, unique number. Proposals should be raised as pull requests in the docs repository and can be discussed in Github issues.","category":"page"},{"location":"development/proposals/","page":"Enhancement Proposals","title":"Enhancement Proposals","text":"The list of proposal and their current state is listed in the table below.","category":"page"},{"location":"development/proposals/","page":"Enhancement Proposals","title":"Enhancement Proposals","text":"Possible states are:","category":"page"},{"location":"development/proposals/","page":"Enhancement Proposals","title":"Enhancement Proposals","text":"In Discussion\nAccepted\nDeclined\nIn Progress\nCompleted\nAborted","category":"page"},{"location":"development/proposals/","page":"Enhancement Proposals","title":"Enhancement Proposals","text":"Once a proposal was accepted, an issue should be raised and the implementation should be done in a separate PR.","category":"page"},{"location":"development/proposals/","page":"Enhancement Proposals","title":"Enhancement Proposals","text":"Name Description State\nMEP-1 Distributed Control Plane Deployment In Discussion\nMEP-2 Two Factor Authentication Aborted\nMEP-3 Machine Re-Installation to preserve local data Completed\nMEP-4 Multi-tenancy for the metal-api In Discussion\nMEP-5 Shared Networks Completed\nMEP-6 DMZ Networks Completed\nMEP-8 Configurable Filesystemlayout Completed\nMEP-9 No Open Ports To the Data Center Completed\nMEP-10 SONiC Support Completed\nMEP-11 Auditing of metal-stack resources Completed\nMEP-12 Rack Spreading Completed\nMEP-14 Independence from external sources In Discussion","category":"page"},{"location":"external/metalctl/docs/metalctl_image_delete/#metalctl-image-delete","page":"metalctl image delete","title":"metalctl image delete","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_image_delete/","page":"metalctl image delete","title":"metalctl image delete","text":"deletes the image","category":"page"},{"location":"external/metalctl/docs/metalctl_image_delete/","page":"metalctl image delete","title":"metalctl image delete","text":"metalctl image delete [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_image_delete/#Options","page":"metalctl image delete","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_image_delete/","page":"metalctl image delete","title":"metalctl image delete","text":" --bulk-output when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.\n -f, --file string filename of the create or update request in yaml format, or - for stdin.\n \n Example:\n $ metalctl image describe image-1 -o yaml > image.yaml\n $ vi image.yaml\n $ # either via stdin\n $ cat image.yaml | metalctl image delete -f -\n $ # or via file\n $ metalctl image delete -f image.yaml\n \n the file can also contain multiple documents and perform a bulk operation.\n \t\n -h, --help help for delete\n --skip-security-prompts skips security prompt for bulk operations\n --timestamps when used with --file (bulk operation): prints timestamps in-between the operations","category":"page"},{"location":"external/metalctl/docs/metalctl_image_delete/#Options-inherited-from-parent-commands","page":"metalctl image delete","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_image_delete/","page":"metalctl image delete","title":"metalctl image delete","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_image_delete/#SEE-ALSO","page":"metalctl image delete","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_image_delete/","page":"metalctl image delete","title":"metalctl image delete","text":"metalctl image\t - manage image entities","category":"page"},{"location":"external/metalctl/docs/metalctl_markdown/#metalctl-markdown","page":"metalctl markdown","title":"metalctl markdown","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_markdown/","page":"metalctl markdown","title":"metalctl markdown","text":"create markdown documentation","category":"page"},{"location":"external/metalctl/docs/metalctl_markdown/","page":"metalctl markdown","title":"metalctl markdown","text":"metalctl markdown [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_markdown/#Options","page":"metalctl markdown","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_markdown/","page":"metalctl markdown","title":"metalctl markdown","text":" -h, --help help for markdown","category":"page"},{"location":"external/metalctl/docs/metalctl_markdown/#Options-inherited-from-parent-commands","page":"metalctl markdown","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_markdown/","page":"metalctl markdown","title":"metalctl markdown","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_markdown/#SEE-ALSO","page":"metalctl markdown","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_markdown/","page":"metalctl markdown","title":"metalctl markdown","text":"metalctl\t - a cli to manage entities in the metal-stack api","category":"page"},{"location":"external/metalctl/docs/metalctl_size_create/#metalctl-size-create","page":"metalctl size create","title":"metalctl size create","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_create/","page":"metalctl size create","title":"metalctl size create","text":"creates the size","category":"page"},{"location":"external/metalctl/docs/metalctl_size_create/","page":"metalctl size create","title":"metalctl size create","text":"metalctl size create [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_size_create/#Options","page":"metalctl size create","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_create/","page":"metalctl size create","title":"metalctl size create","text":" --bulk-output when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.\n -d, --description string Description of the size. [required]\n -f, --file string filename of the create or update request in yaml format, or - for stdin.\n \n Example:\n $ metalctl size describe size-1 -o yaml > size.yaml\n $ vi size.yaml\n $ # either via stdin\n $ cat size.yaml | metalctl size create -f -\n $ # or via file\n $ metalctl size create -f size.yaml\n \n the file can also contain multiple documents and perform a bulk operation.\n \t\n -h, --help help for create\n --id string ID of the size. [required]\n --max int min value of given size constraint type. [required]\n --min int min value of given size constraint type. [required]\n -n, --name string Name of the size. [optional]\n --skip-security-prompts skips security prompt for bulk operations\n --timestamps when used with --file (bulk operation): prints timestamps in-between the operations\n --type string type of constraints. [required]","category":"page"},{"location":"external/metalctl/docs/metalctl_size_create/#Options-inherited-from-parent-commands","page":"metalctl size create","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_create/","page":"metalctl size create","title":"metalctl size create","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_size_create/#SEE-ALSO","page":"metalctl size create","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_create/","page":"metalctl size create","title":"metalctl size create","text":"metalctl size\t - manage size entities","category":"page"},{"location":"external/metalctl/docs/metalctl_firewall_describe/#metalctl-firewall-describe","page":"metalctl firewall describe","title":"metalctl firewall describe","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_firewall_describe/","page":"metalctl firewall describe","title":"metalctl firewall describe","text":"describes the firewall","category":"page"},{"location":"external/metalctl/docs/metalctl_firewall_describe/","page":"metalctl firewall describe","title":"metalctl firewall describe","text":"metalctl firewall describe [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_firewall_describe/#Options","page":"metalctl firewall describe","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_firewall_describe/","page":"metalctl firewall describe","title":"metalctl firewall describe","text":" -h, --help help for describe","category":"page"},{"location":"external/metalctl/docs/metalctl_firewall_describe/#Options-inherited-from-parent-commands","page":"metalctl firewall describe","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_firewall_describe/","page":"metalctl firewall describe","title":"metalctl firewall describe","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_firewall_describe/#SEE-ALSO","page":"metalctl firewall describe","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_firewall_describe/","page":"metalctl firewall describe","title":"metalctl firewall describe","text":"metalctl firewall\t - manage firewall entities","category":"page"},{"location":"development/roadmap/#Roadmap","page":"Roadmap","title":"Roadmap","text":"","category":"section"},{"location":"development/roadmap/","page":"Roadmap","title":"Roadmap","text":"A roadmap with short-, mid- and long-term planning will be available soon. For now, there is only a backlog.","category":"page"},{"location":"development/roadmap/#Short-term","page":"Roadmap","title":"Short-term","text":"","category":"section"},{"location":"development/roadmap/","page":"Roadmap","title":"Roadmap","text":"Available soon.","category":"page"},{"location":"development/roadmap/#Mid-term","page":"Roadmap","title":"Mid-term","text":"","category":"section"},{"location":"development/roadmap/","page":"Roadmap","title":"Roadmap","text":"Available soon.","category":"page"},{"location":"development/roadmap/#Long-term","page":"Roadmap","title":"Long-term","text":"","category":"section"},{"location":"development/roadmap/","page":"Roadmap","title":"Roadmap","text":"Available soon.","category":"page"},{"location":"development/roadmap/#Backlog","page":"Roadmap","title":"Backlog","text":"","category":"section"},{"location":"development/roadmap/","page":"Roadmap","title":"Roadmap","text":"The backlog contains ideas of what could become part of the roadmap in the future. The list is ordered alphabetically. Therefore, the order does not express the importance or weight of a backlog item.","category":"page"},{"location":"development/roadmap/","page":"Roadmap","title":"Roadmap","text":"We incorporate community feedback into the roadmap. If you think that important points are missing in the backlog, please share your ideas with us. We have a Slack channel. Please check out metal-stack.io for contact information.","category":"page"},{"location":"development/roadmap/","page":"Roadmap","title":"Roadmap","text":"danger: Danger\nBy no means this list is a promise of what is being worked on in the near future. It is just a summary of ideas that was agreed on to be \"nice to have\". It is up to the investors, maintainers and the community to choose topics from this list and to implement them or to remove them from the list.","category":"page"},{"location":"development/roadmap/","page":"Roadmap","title":"Roadmap","text":"Add metal-stack to Gardener conformance test grid\nAutoscaler for metal control plane components\nCI dashboard and public integration testing\nCilium as the default CNI for metal-stack on Gardener K8s clusters\nImproved release and deploy processes (GitOps, Spinnaker, Flux)\nMachine internet without firewalls\nmetal-stack dashboard (UI)\nOffer our metal-stack extensions as enterprise products (accounting, cluster-api, S3) (neither of them will ever be required for running metal-stack, they just add extra value for certain enterprises)\nPartition managed by Kubernetes (with Kubelets joining the control plane cluster)\nPublic offering / demo playground\nResource scoping in the metal-api (MEP-4)\nService / API tokens (for scoped technical user access)","category":"page"},{"location":"external/firewall-controller/DEVELOP/#Develop-Setup","page":"Develop Setup","title":"Develop Setup","text":"","category":"section"},{"location":"external/firewall-controller/DEVELOP/","page":"Develop Setup","title":"Develop Setup","text":"download kubebuilder\ndownload kustomize from kustomize\ninit project and run kubebuilder\nkubebuilder init --domain metal-stack.io\nkubebuilder create api --group firewall --version v1 --kind Network\nrun test\nexport KUBEBUILDER_ASSETS=/usr/local/kubebuilder/bin # path-to-kubebuilder/bin\nmake test","category":"page"},{"location":"external/firewall-controller/DEVELOP/#Testing-locally","page":"Develop Setup","title":"Testing locally","text":"","category":"section"},{"location":"external/firewall-controller/DEVELOP/","page":"Develop Setup","title":"Develop Setup","text":"# make binary\nmake\n\n# start the controller\nbin/firewall-controller --hosts-file ./hosts --enable-signature-check=false --enable-IDS=false\n\n# install kind (k8s in docker)\n\n# create a local kind cluster\nkind create cluster\n\n# deploy manifests\nk apply -f deploy\n\n# watch results\nk describe -n firewall firewall\ncat nftables.v4\ncat hosts","category":"page"},{"location":"development/proposals/MEP11/README/#Auditing-of-metal-stack-resources","page":"Auditing of metal-stack resources","title":"Auditing of metal-stack resources","text":"","category":"section"},{"location":"development/proposals/MEP11/README/","page":"Auditing of metal-stack resources","title":"Auditing of metal-stack resources","text":"Currently no logs of the ownership of resources like machines, networks, ips and volumes are generated or kept. Though due to legal requirements data centers are required to keep track of this ownership over time to prevent liability issues when opening the platform for external users.","category":"page"},{"location":"development/proposals/MEP11/README/","page":"Auditing of metal-stack resources","title":"Auditing of metal-stack resources","text":"In this proposal we want to introduce a flexible and low-maintenance approach for auditing on top of Meilisearch.","category":"page"},{"location":"development/proposals/MEP11/README/#Overview","page":"Auditing of metal-stack resources","title":"Overview","text":"","category":"section"},{"location":"development/proposals/MEP11/README/","page":"Auditing of metal-stack resources","title":"Auditing of metal-stack resources","text":"In general our auditing logs will be collected by a request interceptor or middleware. Every request and response will be processed and eventually logged to Meilisearch. Meilisearch will be configured to regularly create chunks of the auditing logs. These finished chunks will be backed up to a S3 compatible storage with a read-only option enabled.","category":"page"},{"location":"development/proposals/MEP11/README/","page":"Auditing of metal-stack resources","title":"Auditing of metal-stack resources","text":"Of course sensitive data like session keys or passwords will be redacted before logging. We want to track relevant requests and responses. If auditing the request fails, the request itself will be aborted and will not be processed further. The requests and responses that will be audited will be annotated with a correlation id.","category":"page"},{"location":"development/proposals/MEP11/README/","page":"Auditing of metal-stack resources","title":"Auditing of metal-stack resources","text":"Transferring the meilisearch auditing data chunks to the S3 compatible storage will be done by a sidecar cronjob that is executed periodically. To avoid data manipulation the S3 compatible storage will be configured to be read-only.","category":"page"},{"location":"development/proposals/MEP11/README/#Whitelisting","page":"Auditing of metal-stack resources","title":"Whitelisting","text":"","category":"section"},{"location":"development/proposals/MEP11/README/","page":"Auditing of metal-stack resources","title":"Auditing of metal-stack resources","text":"To reduce the amount of unnecessary logs we want to introduce a whitelist of resources and operations on those that should be logged. Other requests will be passed directly to the next middleware or web service without any further processing.","category":"page"},{"location":"development/proposals/MEP11/README/","page":"Auditing of metal-stack resources","title":"Auditing of metal-stack resources","text":"As we are only interested in mutating endpoints, we ignore all GET requests. The whitelist includes all POST, PUT, PATCH and DELETE endpoints of the HTTP middleware except for the following (non-manipulating) route suffixes:","category":"page"},{"location":"development/proposals/MEP11/README/","page":"Auditing of metal-stack resources","title":"Auditing of metal-stack resources","text":"/find\n/notify\n/try and /match\n/capacity\n/from-hardware","category":"page"},{"location":"development/proposals/MEP11/README/","page":"Auditing of metal-stack resources","title":"Auditing of metal-stack resources","text":"Regarding GRPC audit trails, they are not so interesting because only internal clients are using this API. However, we can log the trails of the Boot service, which can be interesting to revise the machine lifecycle.","category":"page"},{"location":"development/proposals/MEP11/README/#Chunking-in-Meilisearch","page":"Auditing of metal-stack resources","title":"Chunking in Meilisearch","text":"","category":"section"},{"location":"development/proposals/MEP11/README/","page":"Auditing of metal-stack resources","title":"Auditing of metal-stack resources","text":"We want our data to be chunked in Meilisearch. To accomplish this, we rotate the index identifier on a scheduled basis. The index identifiers will be derived from the current date and time.","category":"page"},{"location":"development/proposals/MEP11/README/","page":"Auditing of metal-stack resources","title":"Auditing of metal-stack resources","text":"To keep things simple, we only support hourly, daily and monthly rotation. The eventually prefixed index names will only include relevant parts of date and time like 2021-01, 2021-01-01 or 2021-01-01_13.","category":"page"},{"location":"development/proposals/MEP11/README/","page":"Auditing of metal-stack resources","title":"Auditing of metal-stack resources","text":"The metal-api will only write to the current index and switches to the new index on rotation. The metal-api will never read or update data in any indices.","category":"page"},{"location":"development/proposals/MEP11/README/#Moving-chunks-to-S3-compatible-storage","page":"Auditing of metal-stack resources","title":"Moving chunks to S3 compatible storage","text":"","category":"section"},{"location":"development/proposals/MEP11/README/","page":"Auditing of metal-stack resources","title":"Auditing of metal-stack resources","text":"As Meilisearch will be filled with data over time, we want to move completed chunks to a S3 compatible storage. This will be done by a sidecar cronjob that is executed periodically. Note that the periods of the index rotation and the cronjob execution don't have to match.","category":"page"},{"location":"development/proposals/MEP11/README/","page":"Auditing of metal-stack resources","title":"Auditing of metal-stack resources","text":"When the backup process gets started, it initiates a Meilisearch dump of the whole database across all indices. Once the returned task is finished, the dump must be copied from a Meilisearch volume to the S3 compatible storage. After a successful copy, the dump can be deleted.","category":"page"},{"location":"development/proposals/MEP11/README/","page":"Auditing of metal-stack resources","title":"Auditing of metal-stack resources","text":"Now we want to remove all indices from Meilisearch, except the most recent one. For this, we get all indices, sort them and delete each index except the most recent one to avoid data loss.","category":"page"},{"location":"development/proposals/MEP11/README/","page":"Auditing of metal-stack resources","title":"Auditing of metal-stack resources","text":"For the actual implementation, we can build upon backup-restore-sidecar. But due to the index rotation and the fact, that older indices need to be deleted, this probably does not fit into the mentioned sidecar.","category":"page"},{"location":"development/proposals/MEP11/README/#S3-compatible-storage","page":"Auditing of metal-stack resources","title":"S3 compatible storage","text":"","category":"section"},{"location":"development/proposals/MEP11/README/","page":"Auditing of metal-stack resources","title":"Auditing of metal-stack resources","text":"The dumps of chunks should automatically deleted after a certain amount of time, once we are either no longer allowed or required to keep them. The default retention time will be 6 months. Ideally already uploaded chunks should be read-only to prevent data manipulation.","category":"page"},{"location":"development/proposals/MEP11/README/","page":"Auditing of metal-stack resources","title":"Auditing of metal-stack resources","text":"A candidate for the S3 compatible storage is Google Cloud Storage, which allows to configure automatic expiration of objects through a lifecycle rule.","category":"page"},{"location":"development/proposals/MEP11/README/#Affected-components","page":"Auditing of metal-stack resources","title":"Affected components","text":"","category":"section"},{"location":"development/proposals/MEP11/README/","page":"Auditing of metal-stack resources","title":"Auditing of metal-stack resources","text":"metal-api grpc server needs an auditing interceptor\nmetal-api web server needs an auditing filter chain / middleware\nmetal-api needs new command line arguments to configure the auditing\nmini-lab needs a Meilisearch instance\nmini-lab may need a local S3 compatible storage\nwe need a sidecar to implement the backup to S3 compatible storage\nConsider auditing of volume allocations and freeings outside of metal-stack","category":"page"},{"location":"development/proposals/MEP11/README/#Alternatives-considered","page":"Auditing of metal-stack resources","title":"Alternatives considered","text":"","category":"section"},{"location":"development/proposals/MEP11/README/","page":"Auditing of metal-stack resources","title":"Auditing of metal-stack resources","text":"Instead of using Meilisearch we investigated using an immutable database like immudb. But immudb does not support chunking of data and due to its immutable nature, we will never be able to free up space of expired data. Even if we are legally allowed or required to delete data, we will not be able to do so with immudb.","category":"page"},{"location":"development/proposals/MEP11/README/","page":"Auditing of metal-stack resources","title":"Auditing of metal-stack resources","text":"In another variant of the Meilisearch approach the metal-api would also be responsible for copying chunks to the S3 compatible storage and deleting old indices. But separating the concerns allows completely different implementations for every deployment stage.","category":"page"},{"location":"external/metalctl/docs/metalctl_firewall/#metalctl-firewall","page":"metalctl firewall","title":"metalctl firewall","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_firewall/","page":"metalctl firewall","title":"metalctl firewall","text":"manage firewall entities","category":"page"},{"location":"external/metalctl/docs/metalctl_firewall/#Synopsis","page":"metalctl firewall","title":"Synopsis","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_firewall/","page":"metalctl firewall","title":"metalctl firewall","text":"firewalls are used to establish network connectivity between metal-stack networks. firewalls are similar to machines but are managed by the provider. almost every command of the machine command subset works on firewalls, too.","category":"page"},{"location":"external/metalctl/docs/metalctl_firewall/#Options","page":"metalctl firewall","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_firewall/","page":"metalctl firewall","title":"metalctl firewall","text":" -h, --help help for firewall","category":"page"},{"location":"external/metalctl/docs/metalctl_firewall/#Options-inherited-from-parent-commands","page":"metalctl firewall","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_firewall/","page":"metalctl firewall","title":"metalctl firewall","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_firewall/#SEE-ALSO","page":"metalctl firewall","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_firewall/","page":"metalctl firewall","title":"metalctl firewall","text":"metalctl\t - a cli to manage entities in the metal-stack api\nmetalctl firewall create\t - creates the firewall\nmetalctl firewall describe\t - describes the firewall\nmetalctl firewall list\t - list all firewalls\nmetalctl firewall ssh\t - SSH to a firewall","category":"page"},{"location":"external/metalctl/docs/metalctl_update_do/#metalctl-update-do","page":"metalctl update do","title":"metalctl update do","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_update_do/","page":"metalctl update do","title":"metalctl update do","text":"do the update of the program","category":"page"},{"location":"external/metalctl/docs/metalctl_update_do/","page":"metalctl update do","title":"metalctl update do","text":"metalctl update do [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_update_do/#Options","page":"metalctl update do","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_update_do/","page":"metalctl update do","title":"metalctl update do","text":" -h, --help help for do\n -v, --version string the version to update to, by default updates to the supported version, use \"latest\" to update to latest version","category":"page"},{"location":"external/metalctl/docs/metalctl_update_do/#Options-inherited-from-parent-commands","page":"metalctl update do","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_update_do/","page":"metalctl update do","title":"metalctl update do","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_update_do/#SEE-ALSO","page":"metalctl update do","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_update_do/","page":"metalctl update do","title":"metalctl update do","text":"metalctl update\t - update the program","category":"page"},{"location":"development/client_libraries/#Client-Libraries","page":"Client Libraries","title":"Client Libraries","text":"","category":"section"},{"location":"development/client_libraries/","page":"Client Libraries","title":"Client Libraries","text":"Our public-facing APIs are built on swagger, which allows you generating API clients in all sorts of programming languages.","category":"page"},{"location":"development/client_libraries/","page":"Client Libraries","title":"Client Libraries","text":"For the metal-api we officially support the following client libraries:","category":"page"},{"location":"development/client_libraries/","page":"Client Libraries","title":"Client Libraries","text":"metal-go\nmetal-python","category":"page"},{"location":"development/proposals/MEP9/README/#No-Open-Ports-To-the-Data-Center","page":"No Open Ports To the Data Center","title":"No Open Ports To the Data Center","text":"","category":"section"},{"location":"development/proposals/MEP9/README/","page":"No Open Ports To the Data Center","title":"No Open Ports To the Data Center","text":"Our metal-stack partitions typically have open ports for metal-stack native services, these are:","category":"page"},{"location":"development/proposals/MEP9/README/","page":"No Open Ports To the Data Center","title":"No Open Ports To the Data Center","text":"SSH port on the firewalls\nbmc-reverse-proxy for serial console access through the metal-console","category":"page"},{"location":"development/proposals/MEP9/README/","page":"No Open Ports To the Data Center","title":"No Open Ports To the Data Center","text":"These open ports are potential security risks. For example, while SSH access is possible only with private key it's still vulnerable to DoS attack.","category":"page"},{"location":"development/proposals/MEP9/README/","page":"No Open Ports To the Data Center","title":"No Open Ports To the Data Center","text":"Therefore, we want to get rid off these open ports to reduce the attack surface to the data center.","category":"page"},{"location":"development/proposals/MEP9/README/#Requirements","page":"No Open Ports To the Data Center","title":"Requirements","text":"","category":"section"},{"location":"development/proposals/MEP9/README/","page":"No Open Ports To the Data Center","title":"No Open Ports To the Data Center","text":"Access to firewall SSH only via VPN\nEasy to update VPN components","category":"page"},{"location":"development/proposals/MEP9/README/","page":"No Open Ports To the Data Center","title":"No Open Ports To the Data Center","text":"As a next step, we can also consider joining the management servers to the VPN mesh, which would replace typical WireGuard setups for operators to enter resources inside the partition.","category":"page"},{"location":"development/proposals/MEP9/README/#High-Level-Design","page":"No Open Ports To the Data Center","title":"High Level Design","text":"","category":"section"},{"location":"development/proposals/MEP9/README/","page":"No Open Ports To the Data Center","title":"No Open Ports To the Data Center","text":"","category":"page"},{"location":"development/proposals/MEP9/README/","page":"No Open Ports To the Data Center","title":"No Open Ports To the Data Center","text":"Simplified drawing showing old vs. new architecture.","category":"page"},{"location":"development/proposals/MEP9/README/#Concerns","page":"No Open Ports To the Data Center","title":"Concerns","text":"","category":"section"},{"location":"development/proposals/MEP9/README/","page":"No Open Ports To the Data Center","title":"No Open Ports To the Data Center","text":"There's few concerns when using WireGuard for implementing VPN:","category":"page"},{"location":"development/proposals/MEP9/README/","page":"No Open Ports To the Data Center","title":"No Open Ports To the Data Center","text":"WireGuard doesn't implement dynamic cipher substitution. Which is important in case one of the crypto methods, used by WireGuard will be broken. The only possible solution for that will be to update WireGuard to a fixed version.\nCoordination server(Headscale) is a single point of failure. In case it fails, it potentially can disconnect existing members of the network, as WireGuard can't manage dynamic IPs by itself.\nHeadscale is already falls behind Tailscale coordination server implementation. Which can complicate the upgrade to newer version of Tailscale client in case of emergency.","category":"page"},{"location":"development/proposals/MEP9/README/#Solutions-to-concerns","page":"No Open Ports To the Data Center","title":"Solutions to concerns","text":"","category":"section"},{"location":"development/proposals/MEP9/README/","page":"No Open Ports To the Data Center","title":"No Open Ports To the Data Center","text":"Tailscale node software is using userspace implementation of WireGuard – wireguard-go. One of the options is to inject Tailscale client into metalctl. And make it available as metalctl vpn or similar command. It should be possible to do as tailscale node is already available as open sourced Go pkg. That would allow us to control, what version of Tailscale users are using and in case of any critical changes to enforce them to update metalctl to use VPN functionality.\nWould it be a considerable risk? We could look into wg-dynamic project to cover this problem.\nAt the moment, repository looks well maintained and the metal-stack team already contributes to it.","category":"page"},{"location":"development/proposals/MEP9/README/#Implementation-Details","page":"No Open Ports To the Data Center","title":"Implementation Details","text":"","category":"section"},{"location":"development/proposals/MEP9/README/#metal-roles","page":"No Open Ports To the Data Center","title":"metal-roles","text":"","category":"section"},{"location":"development/proposals/MEP9/README/","page":"No Open Ports To the Data Center","title":"No Open Ports To the Data Center","text":"metal-roles will be responsible for deployment of headscale server(via new headscale role). It also should provide sufficient config to metal-api so it establishes connection with headscale gRPC server.","category":"page"},{"location":"development/proposals/MEP9/README/#New-metalctl-commands","page":"No Open Ports To the Data Center","title":"New metalctl commands","text":"","category":"section"},{"location":"development/proposals/MEP9/README/","page":"No Open Ports To the Data Center","title":"No Open Ports To the Data Center","text":"metalctl will be responsible for client-side implementation of this MEP. Specifically, it's by using metalctl user expected to connect to firewalls.","category":"page"},{"location":"development/proposals/MEP9/README/","page":"No Open Ports To the Data Center","title":"No Open Ports To the Data Center","text":"metalctl vpn – section for VPN related commands:\nmetalctl vpn get key [vpn name] --namespace [namespace name] – returns auth key to be used with tailscale client for establishing connection.","category":"page"},{"location":"development/proposals/MEP9/README/","page":"No Open Ports To the Data Center","title":"No Open Ports To the Data Center","text":"Extend metalctl firewall:","category":"page"},{"location":"development/proposals/MEP9/README/","page":"No Open Ports To the Data Center","title":"No Open Ports To the Data Center","text":"metalctl firewall ssh [ID] – connect to firewall via SSH.","category":"page"},{"location":"development/proposals/MEP9/README/","page":"No Open Ports To the Data Center","title":"No Open Ports To the Data Center","text":"Extend metalctl machine:","category":"page"},{"location":"development/proposals/MEP9/README/","page":"No Open Ports To the Data Center","title":"No Open Ports To the Data Center","text":"metalctl machine ssh [ID] – connect to machine via SSH.","category":"page"},{"location":"development/proposals/MEP9/README/","page":"No Open Ports To the Data Center","title":"No Open Ports To the Data Center","text":"metalctl will be able to connect to firewall and machines by running tailscale in container.","category":"page"},{"location":"development/proposals/MEP9/README/#metal-api","page":"No Open Ports To the Data Center","title":"metal-api","text":"","category":"section"},{"location":"development/proposals/MEP9/README/","page":"No Open Ports To the Data Center","title":"No Open Ports To the Data Center","text":"Updates to metal-api should be made, so that it's able to add firewalls to VPNs. There should be one Tailscale namespace per project. So if multiple firewalls are created in single project, they will join the same namespace.","category":"page"},{"location":"development/proposals/MEP9/README/","page":"No Open Ports To the Data Center","title":"No Open Ports To the Data Center","text":"Two new flags should be introduced to connect metal-api to headscale gRPC server:","category":"page"},{"location":"development/proposals/MEP9/README/","page":"No Open Ports To the Data Center","title":"No Open Ports To the Data Center","text":"headscale-addr – specifies address of Headscale grpc API.\nheadscale-api-key – specifies temporary API key to connect to Headscale. It should be replaced and then rotated by metal-api.","category":"page"},{"location":"development/proposals/MEP9/README/","page":"No Open Ports To the Data Center","title":"No Open Ports To the Data Center","text":"If metal-api initialized with headscale connection it should automatically join all created firewalls to VPN.","category":"page"},{"location":"development/proposals/MEP9/README/","page":"No Open Ports To the Data Center","title":"No Open Ports To the Data Center","text":"Add new endpoint, that will be used by metalctl to connect to VPN:","category":"page"},{"location":"development/proposals/MEP9/README/","page":"No Open Ports To the Data Center","title":"No Open Ports To the Data Center","text":"/v1/vpn GET – requests auth key from headscale server.","category":"page"},{"location":"development/proposals/MEP9/README/#metal-hammer","page":"No Open Ports To the Data Center","title":"metal-hammer","text":"","category":"section"},{"location":"development/proposals/MEP9/README/","page":"No Open Ports To the Data Center","title":"No Open Ports To the Data Center","text":"metal-hammer acts as an intermediary for machine configuration between metal-api and machine's image. Specifically it writes to /etc/metal/install.yaml file, data from which later will be used by image's install.sh file.","category":"page"},{"location":"development/proposals/MEP9/README/","page":"No Open Ports To the Data Center","title":"No Open Ports To the Data Center","text":"To implement VPN support we have to add authentication key and VPN server address to install.yaml file. This key will be used to join machine to a VPN.","category":"page"},{"location":"development/proposals/MEP9/README/#metal-images","page":"No Open Ports To the Data Center","title":"metal-images","text":"","category":"section"},{"location":"development/proposals/MEP9/README/","page":"No Open Ports To the Data Center","title":"No Open Ports To the Data Center","text":"Images install.sh script have to be updated to work with authentication key and VPN server address, provided in install.yaml file. If this key is present, machine should connect to VPN.","category":"page"},{"location":"development/proposals/MEP9/README/#metal-networker","page":"No Open Ports To the Data Center","title":"metal-networker","text":"","category":"section"},{"location":"development/proposals/MEP9/README/","page":"No Open Ports To the Data Center","title":"No Open Ports To the Data Center","text":"metal-networker also have to know if VPN was configured. In that case we need to disable public access to SSH and allow all(?) traffic from WireGuard interface.","category":"page"},{"location":"development/proposals/MEP9/README/#firewall-controller","page":"No Open Ports To the Data Center","title":"firewall-controller","text":"","category":"section"},{"location":"development/proposals/MEP9/README/","page":"No Open Ports To the Data Center","title":"No Open Ports To the Data Center","text":"firewall-controller have to monitor changes in Firewall resource and keep tailscaled version up-to-date.","category":"page"},{"location":"development/proposals/MEP9/README/#Resources","page":"No Open Ports To the Data Center","title":"Resources","text":"","category":"section"},{"location":"development/proposals/MEP9/README/","page":"No Open Ports To the Data Center","title":"No Open Ports To the Data Center","text":"Update Firewall resource to include desired/actual tailscale version:","category":"page"},{"location":"development/proposals/MEP9/README/","page":"No Open Ports To the Data Center","title":"No Open Ports To the Data Center","text":"Firewall:\n Spec:\n tailscale:\n Version: Minimal version\n ...\n Status:\n ...\n VPN:\n Status: Boolean field\n tailscale:\n Version: Actual version\n ...","category":"page"},{"location":"development/proposals/MEP9/README/#bmc-reverse-proxy","page":"No Open Ports To the Data Center","title":"bmc-reverse-proxy","text":"","category":"section"},{"location":"development/proposals/MEP9/README/","page":"No Open Ports To the Data Center","title":"No Open Ports To the Data Center","text":"TODO","category":"page"},{"location":"development/proposals/MEP9/README/#References","page":"No Open Ports To the Data Center","title":"References","text":"","category":"section"},{"location":"development/proposals/MEP9/README/","page":"No Open Ports To the Data Center","title":"No Open Ports To the Data Center","text":"WireGuard: Next Generation Secure Network Tunnel\nHow Tailscale works\nTailscale is officially SOC 2 compliant\nWhy not Wireguard\nWireguard: Known Limitations\nWireguard: Things That Might Be Accomplished\nHeadscale: Tailscale control protocol v2","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_identify_off/#metalctl-machine-identify-off","page":"metalctl machine identify off","title":"metalctl machine identify off","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_identify_off/","page":"metalctl machine identify off","title":"metalctl machine identify off","text":"power off the machine chassis identify LED","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_identify_off/#Synopsis","page":"metalctl machine identify off","title":"Synopsis","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_identify_off/","page":"metalctl machine identify off","title":"metalctl machine identify off","text":"set the machine chassis identify LED to off state","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_identify_off/","page":"metalctl machine identify off","title":"metalctl machine identify off","text":"metalctl machine identify off [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_identify_off/#Options","page":"metalctl machine identify off","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_identify_off/","page":"metalctl machine identify off","title":"metalctl machine identify off","text":" -d, --description string description of the reason for chassis identify LED turn-off. (default \"Triggered by metalctl\")\n -h, --help help for off","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_identify_off/#Options-inherited-from-parent-commands","page":"metalctl machine identify off","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_identify_off/","page":"metalctl machine identify off","title":"metalctl machine identify off","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_identify_off/#SEE-ALSO","page":"metalctl machine identify off","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_identify_off/","page":"metalctl machine identify off","title":"metalctl machine identify off","text":"metalctl machine identify\t - manage machine chassis identify LED power","category":"page"},{"location":"external/metalctl/docs/metalctl_partition_capacity/#metalctl-partition-capacity","page":"metalctl partition capacity","title":"metalctl partition capacity","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_partition_capacity/","page":"metalctl partition capacity","title":"metalctl partition capacity","text":"show partition capacity","category":"page"},{"location":"external/metalctl/docs/metalctl_partition_capacity/","page":"metalctl partition capacity","title":"metalctl partition capacity","text":"metalctl partition capacity [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_partition_capacity/#Options","page":"metalctl partition capacity","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_partition_capacity/","page":"metalctl partition capacity","title":"metalctl partition capacity","text":" -h, --help help for capacity\n --id string filter on partition id. [optional]\n --size string filter on size id. [optional]\n --sort-by strings order by (comma separated) column(s), sort direction can be changed by appending :asc or :desc behind the column identifier. possible values: description|id|name","category":"page"},{"location":"external/metalctl/docs/metalctl_partition_capacity/#Options-inherited-from-parent-commands","page":"metalctl partition capacity","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_partition_capacity/","page":"metalctl partition capacity","title":"metalctl partition capacity","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_partition_capacity/#SEE-ALSO","page":"metalctl partition capacity","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_partition_capacity/","page":"metalctl partition capacity","title":"metalctl partition capacity","text":"metalctl partition\t - manage partition entities","category":"page"},{"location":"overview/comparison/#Comparison-with-Commercial-Solutions","page":"Comparison","title":"Comparison with Commercial Solutions","text":"","category":"section"},{"location":"overview/comparison/","page":"Comparison","title":"Comparison","text":"As metal-stack is the foundation to build Kubernetes clusters on premise on bare metal, there are several commercial solutions available which offer management of Kubernetes. In this document we describe the differences between some of the most popular solutions. It´s is not a complete list.","category":"page"},{"location":"overview/comparison/","page":"Comparison","title":"Comparison","text":"Pages = [\"comparison.md\"]\nDepth = 5","category":"page"},{"location":"overview/comparison/","page":"Comparison","title":"Comparison","text":"Comparison between Gardener on Metal Stack and Openshift running on VMWare.","category":"page"},{"location":"overview/comparison/#Gardener","page":"Comparison","title":"Gardener","text":"","category":"section"},{"location":"overview/comparison/","page":"Comparison","title":"Comparison","text":"Gardener is a Kubernetes cluster manager to organize a fleet of Kubernetes clusters at scale. It is designed to scale to thousands of clusters at a variety of IaaS Providers regardless where - in the cloud or on premise, virtualized or bare metal. It not only manages the creation and deletion of Kubernetes clusters, it also takes care of updating or upgrading Kubernetes and the operating system of the involved worker nodes in a automatic manner. Gardener is designed cloud-native and as such, it defines clusters, workers and all other components as Kubernetes resources (like pods and deployments) and reconciles these resources to the desired state.","category":"page"},{"location":"overview/comparison/#Kubernetes","page":"Comparison","title":"Kubernetes","text":"","category":"section"},{"location":"overview/comparison/","page":"Comparison","title":"Comparison","text":"Kubernetes is the de facto open-source standard for container scheduling and orchestration in the data center.","category":"page"},{"location":"overview/comparison/#Openshift","page":"Comparison","title":"Openshift","text":"","category":"section"},{"location":"overview/comparison/","page":"Comparison","title":"Comparison","text":"A fork of Kubernetes with proprietary addons, created by RedHat. For all details see: https://en.wikipedia.org/wiki/OpenShift.","category":"page"},{"location":"overview/comparison/#metal-stack","page":"Comparison","title":"metal-stack","text":"","category":"section"},{"location":"overview/comparison/","page":"Comparison","title":"Comparison","text":"Is an IaaS provider for bare metal focused to create Kubernetes cluster on premise. Gardener support is built in.","category":"page"},{"location":"overview/comparison/#VMWare","page":"Comparison","title":"VMWare","text":"","category":"section"},{"location":"overview/comparison/","page":"Comparison","title":"Comparison","text":"The most used virtualization technology in the enterprise data centers.","category":"page"},{"location":"overview/comparison/#Comparison-of-Gardener-on-Metal-Stack-vs.-Openshift-on-VMWare","page":"Comparison","title":"Comparison of Gardener on Metal Stack vs. Openshift on VMWare","text":"","category":"section"},{"location":"overview/comparison/","page":"Comparison","title":"Comparison","text":"Feature Gardener on Metal Stack Openshift on VMWare\nContainer Runtime docker, containerd, gvisor cri-o\nHost Operating System Ubuntu, Debian , also see OS RHEL, Fedora-Core\nNetwork Plugins Calico, Cilium(soon) Openshift SDN\nStorage Local NVME, Lightbits NVMEoTCP, all CSI compatible Solutions, also see Storage CSI compatible\nLoadbalancing BGP built in requires extra HW like F5, VMWare NSX\nIO at Native Speed Pods run on bare metal all IO must go through the Hypervisor\nHard Multitenancy Workers, firewall and load balancers are dedicated for every cluster on bare metal Shared virtualization hosts, shared load balancers\nUI Gardener Dashboard Openshift Console\nMulti-cluster management Yes (through Gardener) Requires extra licences SW: Redhat Advanced Cluster Manager\nAutomatic Kubernetes Updates Yes Yes\nAutomatic Worker Nodes Updates Yes Yes\nSupported IaaS Providers GCP, AWS, Azure, Alibaba, Openstack, VMWare, metal-stack and more GCP, AWS, Azure Openstack, VMWare\nMonitoring / Logging Stack Grafana/Loki, Kibana/Elastic Kibana/Elastic\nGitOPS Tool of choice via Helm Install Openshift GitOPS\nContainer Registry all public accessible registries, private deployed registry of choice all public accessible registries, in cluster registry\nCI/CD Tool of choice via Helm Install Jenkins\nSecurity K8s control plane isolated from tenant, PSP enabled by default Strong cluster defaults\nCNCF Kubernetes certified Yes (Gardener) Yes\nLocal development minikube, kind minishift\nProprietary extensions No DeploymentConfig and others\nkubectl access Yes Yes","category":"page"},{"location":"external/metalctl/docs/metalctl_project_apply/#metalctl-project-apply","page":"metalctl project apply","title":"metalctl project apply","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_project_apply/","page":"metalctl project apply","title":"metalctl project apply","text":"applies one or more projects from a given file","category":"page"},{"location":"external/metalctl/docs/metalctl_project_apply/","page":"metalctl project apply","title":"metalctl project apply","text":"metalctl project apply [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_project_apply/#Options","page":"metalctl project apply","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_project_apply/","page":"metalctl project apply","title":"metalctl project apply","text":" --bulk-output when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.\n -f, --file string filename of the create or update request in yaml format, or - for stdin.\n \n Example:\n $ metalctl project describe project-1 -o yaml > project.yaml\n $ vi project.yaml\n $ # either via stdin\n $ cat project.yaml | metalctl project apply -f -\n $ # or via file\n $ metalctl project apply -f project.yaml\n \n the file can also contain multiple documents and perform a bulk operation.\n \t\n -h, --help help for apply\n --skip-security-prompts skips security prompt for bulk operations\n --timestamps when used with --file (bulk operation): prints timestamps in-between the operations","category":"page"},{"location":"external/metalctl/docs/metalctl_project_apply/#Options-inherited-from-parent-commands","page":"metalctl project apply","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_project_apply/","page":"metalctl project apply","title":"metalctl project apply","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_project_apply/#SEE-ALSO","page":"metalctl project apply","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_project_apply/","page":"metalctl project apply","title":"metalctl project apply","text":"metalctl project\t - manage project entities","category":"page"},{"location":"external/metalctl/docs/metalctl_firewall_ssh/#metalctl-firewall-ssh","page":"metalctl firewall ssh","title":"metalctl firewall ssh","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_firewall_ssh/","page":"metalctl firewall ssh","title":"metalctl firewall ssh","text":"SSH to a firewall","category":"page"},{"location":"external/metalctl/docs/metalctl_firewall_ssh/#Synopsis","page":"metalctl firewall ssh","title":"Synopsis","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_firewall_ssh/","page":"metalctl firewall ssh","title":"metalctl firewall ssh","text":"SSH to a firewall via VPN.","category":"page"},{"location":"external/metalctl/docs/metalctl_firewall_ssh/","page":"metalctl firewall ssh","title":"metalctl firewall ssh","text":"metalctl firewall ssh [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_firewall_ssh/#Options","page":"metalctl firewall ssh","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_firewall_ssh/","page":"metalctl firewall ssh","title":"metalctl firewall ssh","text":" -h, --help help for ssh\n -i, --identity string specify identity file to SSH to the firewall like: -i path/to/id_rsa (default \"~/.ssh/id_rsa\")","category":"page"},{"location":"external/metalctl/docs/metalctl_firewall_ssh/#Options-inherited-from-parent-commands","page":"metalctl firewall ssh","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_firewall_ssh/","page":"metalctl firewall ssh","title":"metalctl firewall ssh","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_firewall_ssh/#SEE-ALSO","page":"metalctl firewall ssh","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_firewall_ssh/","page":"metalctl firewall ssh","title":"metalctl firewall ssh","text":"metalctl firewall\t - manage firewall entities","category":"page"},{"location":"external/metalctl/docs/metalctl_image_edit/#metalctl-image-edit","page":"metalctl image edit","title":"metalctl image edit","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_image_edit/","page":"metalctl image edit","title":"metalctl image edit","text":"edit the image through an editor and update","category":"page"},{"location":"external/metalctl/docs/metalctl_image_edit/","page":"metalctl image edit","title":"metalctl image edit","text":"metalctl image edit [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_image_edit/#Options","page":"metalctl image edit","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_image_edit/","page":"metalctl image edit","title":"metalctl image edit","text":" -h, --help help for edit","category":"page"},{"location":"external/metalctl/docs/metalctl_image_edit/#Options-inherited-from-parent-commands","page":"metalctl image edit","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_image_edit/","page":"metalctl image edit","title":"metalctl image edit","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_image_edit/#SEE-ALSO","page":"metalctl image edit","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_image_edit/","page":"metalctl image edit","title":"metalctl image edit","text":"metalctl image\t - manage image entities","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_power_disk/#metalctl-machine-power-disk","page":"metalctl machine power disk","title":"metalctl machine power disk","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_power_disk/","page":"metalctl machine power disk","title":"metalctl machine power disk","text":"boot a machine from disk","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_power_disk/#Synopsis","page":"metalctl machine power disk","title":"Synopsis","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_power_disk/","page":"metalctl machine power disk","title":"metalctl machine power disk","text":"the machine will boot from disk. (machine does not reboot automatically)","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_power_disk/","page":"metalctl machine power disk","title":"metalctl machine power disk","text":"metalctl machine power disk [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_power_disk/#Options","page":"metalctl machine power disk","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_power_disk/","page":"metalctl machine power disk","title":"metalctl machine power disk","text":" -h, --help help for disk","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_power_disk/#Options-inherited-from-parent-commands","page":"metalctl machine power disk","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_power_disk/","page":"metalctl machine power disk","title":"metalctl machine power disk","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_power_disk/#SEE-ALSO","page":"metalctl machine power disk","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_power_disk/","page":"metalctl machine power disk","title":"metalctl machine power disk","text":"metalctl machine power\t - manage machine power","category":"page"},{"location":"external/metalctl/docs/metalctl_image_describe/#metalctl-image-describe","page":"metalctl image describe","title":"metalctl image describe","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_image_describe/","page":"metalctl image describe","title":"metalctl image describe","text":"describes the image","category":"page"},{"location":"external/metalctl/docs/metalctl_image_describe/","page":"metalctl image describe","title":"metalctl image describe","text":"metalctl image describe [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_image_describe/#Options","page":"metalctl image describe","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_image_describe/","page":"metalctl image describe","title":"metalctl image describe","text":" -h, --help help for describe","category":"page"},{"location":"external/metalctl/docs/metalctl_image_describe/#Options-inherited-from-parent-commands","page":"metalctl image describe","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_image_describe/","page":"metalctl image describe","title":"metalctl image describe","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_image_describe/#SEE-ALSO","page":"metalctl image describe","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_image_describe/","page":"metalctl image describe","title":"metalctl image describe","text":"metalctl image\t - manage image entities","category":"page"},{"location":"external/metalctl/docs/metalctl_partition_list/#metalctl-partition-list","page":"metalctl partition list","title":"metalctl partition list","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_partition_list/","page":"metalctl partition list","title":"metalctl partition list","text":"list all partitions","category":"page"},{"location":"external/metalctl/docs/metalctl_partition_list/","page":"metalctl partition list","title":"metalctl partition list","text":"metalctl partition list [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_partition_list/#Options","page":"metalctl partition list","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_partition_list/","page":"metalctl partition list","title":"metalctl partition list","text":" -h, --help help for list\n --sort-by strings sort by (comma separated) column(s), sort direction can be changed by appending :asc or :desc behind the column identifier. possible values: description|id|name","category":"page"},{"location":"external/metalctl/docs/metalctl_partition_list/#Options-inherited-from-parent-commands","page":"metalctl partition list","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_partition_list/","page":"metalctl partition list","title":"metalctl partition list","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_partition_list/#SEE-ALSO","page":"metalctl partition list","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_partition_list/","page":"metalctl partition list","title":"metalctl partition list","text":"metalctl partition\t - manage partition entities","category":"page"},{"location":"external/metalctl/docs/metalctl_filesystemlayout_describe/#metalctl-filesystemlayout-describe","page":"metalctl filesystemlayout describe","title":"metalctl filesystemlayout describe","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_filesystemlayout_describe/","page":"metalctl filesystemlayout describe","title":"metalctl filesystemlayout describe","text":"describes the filesystemlayout","category":"page"},{"location":"external/metalctl/docs/metalctl_filesystemlayout_describe/","page":"metalctl filesystemlayout describe","title":"metalctl filesystemlayout describe","text":"metalctl filesystemlayout describe [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_filesystemlayout_describe/#Options","page":"metalctl filesystemlayout describe","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_filesystemlayout_describe/","page":"metalctl filesystemlayout describe","title":"metalctl filesystemlayout describe","text":" -h, --help help for describe","category":"page"},{"location":"external/metalctl/docs/metalctl_filesystemlayout_describe/#Options-inherited-from-parent-commands","page":"metalctl filesystemlayout describe","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_filesystemlayout_describe/","page":"metalctl filesystemlayout describe","title":"metalctl filesystemlayout describe","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_filesystemlayout_describe/#SEE-ALSO","page":"metalctl filesystemlayout describe","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_filesystemlayout_describe/","page":"metalctl filesystemlayout describe","title":"metalctl filesystemlayout describe","text":"metalctl filesystemlayout\t - manage filesystemlayout entities","category":"page"},{"location":"external/metalctl/docs/metalctl_partition_apply/#metalctl-partition-apply","page":"metalctl partition apply","title":"metalctl partition apply","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_partition_apply/","page":"metalctl partition apply","title":"metalctl partition apply","text":"applies one or more partitions from a given file","category":"page"},{"location":"external/metalctl/docs/metalctl_partition_apply/","page":"metalctl partition apply","title":"metalctl partition apply","text":"metalctl partition apply [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_partition_apply/#Options","page":"metalctl partition apply","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_partition_apply/","page":"metalctl partition apply","title":"metalctl partition apply","text":" --bulk-output when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.\n -f, --file string filename of the create or update request in yaml format, or - for stdin.\n \n Example:\n $ metalctl partition describe partition-1 -o yaml > partition.yaml\n $ vi partition.yaml\n $ # either via stdin\n $ cat partition.yaml | metalctl partition apply -f -\n $ # or via file\n $ metalctl partition apply -f partition.yaml\n \n the file can also contain multiple documents and perform a bulk operation.\n \t\n -h, --help help for apply\n --skip-security-prompts skips security prompt for bulk operations\n --timestamps when used with --file (bulk operation): prints timestamps in-between the operations","category":"page"},{"location":"external/metalctl/docs/metalctl_partition_apply/#Options-inherited-from-parent-commands","page":"metalctl partition apply","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_partition_apply/","page":"metalctl partition apply","title":"metalctl partition apply","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_partition_apply/#SEE-ALSO","page":"metalctl partition apply","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_partition_apply/","page":"metalctl partition apply","title":"metalctl partition apply","text":"metalctl partition\t - manage partition entities","category":"page"},{"location":"external/metalctl/docs/metalctl_firewall_list/#metalctl-firewall-list","page":"metalctl firewall list","title":"metalctl firewall list","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_firewall_list/","page":"metalctl firewall list","title":"metalctl firewall list","text":"list all firewalls","category":"page"},{"location":"external/metalctl/docs/metalctl_firewall_list/","page":"metalctl firewall list","title":"metalctl firewall list","text":"metalctl firewall list [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_firewall_list/#Options","page":"metalctl firewall list","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_firewall_list/","page":"metalctl firewall list","title":"metalctl firewall list","text":" -h, --help help for list\n --hostname string allocation hostname to filter [optional]\n --id string ID to filter [optional]\n --image string allocation image to filter [optional]\n --mac string mac to filter [optional]\n --name string allocation name to filter [optional]\n --partition string partition to filter [optional]\n --project string allocation project to filter [optional]\n --size string size to filter [optional]\n --sort-by strings sort by (comma separated) column(s), sort direction can be changed by appending :asc or :desc behind the column identifier. possible values: age|event|id|image|liveliness|partition|project|size|when\n --tags strings tags to filter, use it like: --tags \"tag1,tag2\" or --tags \"tag3\".","category":"page"},{"location":"external/metalctl/docs/metalctl_firewall_list/#Options-inherited-from-parent-commands","page":"metalctl firewall list","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_firewall_list/","page":"metalctl firewall list","title":"metalctl firewall list","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_firewall_list/#SEE-ALSO","page":"metalctl firewall list","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_firewall_list/","page":"metalctl firewall list","title":"metalctl firewall list","text":"metalctl firewall\t - manage firewall entities","category":"page"},{"location":"external/metalctl/docs/metalctl_project_list/#metalctl-project-list","page":"metalctl project list","title":"metalctl project list","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_project_list/","page":"metalctl project list","title":"metalctl project list","text":"list all projects","category":"page"},{"location":"external/metalctl/docs/metalctl_project_list/","page":"metalctl project list","title":"metalctl project list","text":"metalctl project list [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_project_list/#Options","page":"metalctl project list","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_project_list/","page":"metalctl project list","title":"metalctl project list","text":" -h, --help help for list\n --id string ID of the project.\n --name string Name of the project.\n --sort-by strings sort by (comma separated) column(s), sort direction can be changed by appending :asc or :desc behind the column identifier. possible values: description|id|name|tenant\n --tenant string tenant of this project.","category":"page"},{"location":"external/metalctl/docs/metalctl_project_list/#Options-inherited-from-parent-commands","page":"metalctl project list","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_project_list/","page":"metalctl project list","title":"metalctl project list","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_project_list/#SEE-ALSO","page":"metalctl project list","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_project_list/","page":"metalctl project list","title":"metalctl project list","text":"metalctl project\t - manage project entities","category":"page"},{"location":"external/metalctl/docs/metalctl_switch_console/#metalctl-switch-console","page":"metalctl switch console","title":"metalctl switch console","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_switch_console/","page":"metalctl switch console","title":"metalctl switch console","text":"connect to the switch console","category":"page"},{"location":"external/metalctl/docs/metalctl_switch_console/#Synopsis","page":"metalctl switch console","title":"Synopsis","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_switch_console/","page":"metalctl switch console","title":"metalctl switch console","text":"this requires a network connectivity to the ip address of the console server this switch is connected to.","category":"page"},{"location":"external/metalctl/docs/metalctl_switch_console/","page":"metalctl switch console","title":"metalctl switch console","text":"metalctl switch console [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_switch_console/#Options","page":"metalctl switch console","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_switch_console/","page":"metalctl switch console","title":"metalctl switch console","text":" -h, --help help for console","category":"page"},{"location":"external/metalctl/docs/metalctl_switch_console/#Options-inherited-from-parent-commands","page":"metalctl switch console","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_switch_console/","page":"metalctl switch console","title":"metalctl switch console","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_switch_console/#SEE-ALSO","page":"metalctl switch console","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_switch_console/","page":"metalctl switch console","title":"metalctl switch console","text":"metalctl switch\t - manage switch entities","category":"page"},{"location":"external/metalctl/docs/metalctl_size_imageconstraint_list/#metalctl-size-imageconstraint-list","page":"metalctl size imageconstraint list","title":"metalctl size imageconstraint list","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_imageconstraint_list/","page":"metalctl size imageconstraint list","title":"metalctl size imageconstraint list","text":"list all imageconstraints","category":"page"},{"location":"external/metalctl/docs/metalctl_size_imageconstraint_list/","page":"metalctl size imageconstraint list","title":"metalctl size imageconstraint list","text":"metalctl size imageconstraint list [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_size_imageconstraint_list/#Options","page":"metalctl size imageconstraint list","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_imageconstraint_list/","page":"metalctl size imageconstraint list","title":"metalctl size imageconstraint list","text":" -h, --help help for list\n --sort-by strings sort by (comma separated) column(s), sort direction can be changed by appending :asc or :desc behind the column identifier. possible values: description|id|name","category":"page"},{"location":"external/metalctl/docs/metalctl_size_imageconstraint_list/#Options-inherited-from-parent-commands","page":"metalctl size imageconstraint list","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_imageconstraint_list/","page":"metalctl size imageconstraint list","title":"metalctl size imageconstraint list","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_size_imageconstraint_list/#SEE-ALSO","page":"metalctl size imageconstraint list","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_imageconstraint_list/","page":"metalctl size imageconstraint list","title":"metalctl size imageconstraint list","text":"metalctl size imageconstraint\t - manage imageconstraint entities","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_power_pxe/#metalctl-machine-power-pxe","page":"metalctl machine power pxe","title":"metalctl machine power pxe","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_power_pxe/","page":"metalctl machine power pxe","title":"metalctl machine power pxe","text":"boot a machine from PXE","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_power_pxe/#Synopsis","page":"metalctl machine power pxe","title":"Synopsis","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_power_pxe/","page":"metalctl machine power pxe","title":"metalctl machine power pxe","text":"the machine will boot from PXE. (machine does not reboot automatically)","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_power_pxe/","page":"metalctl machine power pxe","title":"metalctl machine power pxe","text":"metalctl machine power pxe [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_power_pxe/#Options","page":"metalctl machine power pxe","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_power_pxe/","page":"metalctl machine power pxe","title":"metalctl machine power pxe","text":" -h, --help help for pxe","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_power_pxe/#Options-inherited-from-parent-commands","page":"metalctl machine power pxe","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_power_pxe/","page":"metalctl machine power pxe","title":"metalctl machine power pxe","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_power_pxe/#SEE-ALSO","page":"metalctl machine power pxe","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_power_pxe/","page":"metalctl machine power pxe","title":"metalctl machine power pxe","text":"metalctl machine power\t - manage machine power","category":"page"},{"location":"external/metalctl/docs/metalctl_size_reservation_create/#metalctl-size-reservation-create","page":"metalctl size reservation create","title":"metalctl size reservation create","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_reservation_create/","page":"metalctl size reservation create","title":"metalctl size reservation create","text":"creates the reservation","category":"page"},{"location":"external/metalctl/docs/metalctl_size_reservation_create/","page":"metalctl size reservation create","title":"metalctl size reservation create","text":"metalctl size reservation create [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_size_reservation_create/#Options","page":"metalctl size reservation create","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_reservation_create/","page":"metalctl size reservation create","title":"metalctl size reservation create","text":" --amount int32 the amount to associate with this reservation\n --bulk-output when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.\n --description string the description to associate with this reservation\n -f, --file string filename of the create or update request in yaml format, or - for stdin.\n \n Example:\n $ metalctl reservation describe reservation-1 -o yaml > reservation.yaml\n $ vi reservation.yaml\n $ # either via stdin\n $ cat reservation.yaml | metalctl reservation create -f -\n $ # or via file\n $ metalctl reservation create -f reservation.yaml\n \n the file can also contain multiple documents and perform a bulk operation.\n \t\n -h, --help help for create\n --id string the id to associate with this reservation\n --labels strings the labels to associate with this reservation\n --partitions strings the partition ids to associate with this reservation\n --project string the project id to associate with this reservation\n --size string the size id to associate with this reservation\n --skip-security-prompts skips security prompt for bulk operations\n --timestamps when used with --file (bulk operation): prints timestamps in-between the operations","category":"page"},{"location":"external/metalctl/docs/metalctl_size_reservation_create/#Options-inherited-from-parent-commands","page":"metalctl size reservation create","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_reservation_create/","page":"metalctl size reservation create","title":"metalctl size reservation create","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_size_reservation_create/#SEE-ALSO","page":"metalctl size reservation create","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_reservation_create/","page":"metalctl size reservation create","title":"metalctl size reservation create","text":"metalctl size reservation\t - manage reservation entities","category":"page"},{"location":"external/metalctl/docs/metalctl_partition_describe/#metalctl-partition-describe","page":"metalctl partition describe","title":"metalctl partition describe","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_partition_describe/","page":"metalctl partition describe","title":"metalctl partition describe","text":"describes the partition","category":"page"},{"location":"external/metalctl/docs/metalctl_partition_describe/","page":"metalctl partition describe","title":"metalctl partition describe","text":"metalctl partition describe [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_partition_describe/#Options","page":"metalctl partition describe","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_partition_describe/","page":"metalctl partition describe","title":"metalctl partition describe","text":" -h, --help help for describe","category":"page"},{"location":"external/metalctl/docs/metalctl_partition_describe/#Options-inherited-from-parent-commands","page":"metalctl partition describe","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_partition_describe/","page":"metalctl partition describe","title":"metalctl partition describe","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_partition_describe/#SEE-ALSO","page":"metalctl partition describe","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_partition_describe/","page":"metalctl partition describe","title":"metalctl partition describe","text":"metalctl partition\t - manage partition entities","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_edit/#metalctl-machine-edit","page":"metalctl machine edit","title":"metalctl machine edit","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_edit/","page":"metalctl machine edit","title":"metalctl machine edit","text":"edit the machine through an editor and update","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_edit/","page":"metalctl machine edit","title":"metalctl machine edit","text":"metalctl machine edit [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_edit/#Options","page":"metalctl machine edit","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_edit/","page":"metalctl machine edit","title":"metalctl machine edit","text":" -h, --help help for edit","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_edit/#Options-inherited-from-parent-commands","page":"metalctl machine edit","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_edit/","page":"metalctl machine edit","title":"metalctl machine edit","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_edit/#SEE-ALSO","page":"metalctl machine edit","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_edit/","page":"metalctl machine edit","title":"metalctl machine edit","text":"metalctl machine\t - manage machine entities","category":"page"},{"location":"external/metalctl/docs/metalctl_network_allocate/#metalctl-network-allocate","page":"metalctl network allocate","title":"metalctl network allocate","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_network_allocate/","page":"metalctl network allocate","title":"metalctl network allocate","text":"allocate a network","category":"page"},{"location":"external/metalctl/docs/metalctl_network_allocate/","page":"metalctl network allocate","title":"metalctl network allocate","text":"metalctl network allocate [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_network_allocate/#Options","page":"metalctl network allocate","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_network_allocate/","page":"metalctl network allocate","title":"metalctl network allocate","text":" -d, --description string description of the network to create. [optional]\n --dmz use this private network as dmz. [optional]\n -h, --help help for allocate\n --labels strings labels for this network. [optional]\n -n, --name string name of the network to create. [required]\n --partition string partition where this network should exist. [required]\n --project string partition where this network should exist. [required]\n --shared shared allows usage of this private network from other networks","category":"page"},{"location":"external/metalctl/docs/metalctl_network_allocate/#Options-inherited-from-parent-commands","page":"metalctl network allocate","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_network_allocate/","page":"metalctl network allocate","title":"metalctl network allocate","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_network_allocate/#SEE-ALSO","page":"metalctl network allocate","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_network_allocate/","page":"metalctl network allocate","title":"metalctl network allocate","text":"metalctl network\t - manage network entities","category":"page"},{"location":"development/proposals/MEP8/README/#Configurable-Filesystem-layout-for-Machine-Allocation","page":"Configurable Filesystem layout for Machine Allocation","title":"Configurable Filesystem layout for Machine Allocation","text":"","category":"section"},{"location":"development/proposals/MEP8/README/","page":"Configurable Filesystem layout for Machine Allocation","title":"Configurable Filesystem layout for Machine Allocation","text":"The current implementation uses a hard coded filesystem layout depending on the specified size and image. This is done in the metal-hammer. This worked well in the past because we had a small amount of sizes and images. But we reached a point where this is to restricted for all use cases we have to fulfill. It also forces us to modify the metal-hammer source code to support a new filesystem layout.","category":"page"},{"location":"development/proposals/MEP8/README/","page":"Configurable Filesystem layout for Machine Allocation","title":"Configurable Filesystem layout for Machine Allocation","text":"This proposal tries to address this issue by introducing a filesystem layout struct in the metal-api which is then configurable per machine allocation. The original behavior of automatic filesystem layout decision must still be present, because there must be no API change for existing API consumers. It should be a additional feature during machine allocation.","category":"page"},{"location":"development/proposals/MEP8/README/#API-and-behavior","page":"Configurable Filesystem layout for Machine Allocation","title":"API and behavior","text":"","category":"section"},{"location":"development/proposals/MEP8/README/","page":"Configurable Filesystem layout for Machine Allocation","title":"Configurable Filesystem layout for Machine Allocation","text":"The API will get a new endpoint filesystemlayoutsto create/update/delete a set of available filesystemlayouts.","category":"page"},{"location":"development/proposals/MEP8/README/#Constraints","page":"Configurable Filesystem layout for Machine Allocation","title":"Constraints","text":"","category":"section"},{"location":"development/proposals/MEP8/README/","page":"Configurable Filesystem layout for Machine Allocation","title":"Configurable Filesystem layout for Machine Allocation","text":"In order to keep the actual machine allocation api compatible, there must be no difference while allocating a machine. To achieve this every filesystemlayout defines constraints which specifies for which combination of sizes and images this layout should be used by default. The specified constraints over all filesystemlayouts therefore must be collision free, to be more specific, there must be exactly one layout outcome for every possible combination of sizes and images.","category":"page"},{"location":"development/proposals/MEP8/README/","page":"Configurable Filesystem layout for Machine Allocation","title":"Configurable Filesystem layout for Machine Allocation","text":"The size constraint must be a list of the exact size ids, the image constraint must be a map of os to semver compatible version constraint. For example:","category":"page"},{"location":"development/proposals/MEP8/README/","page":"Configurable Filesystem layout for Machine Allocation","title":"Configurable Filesystem layout for Machine Allocation","text":"debian: \">= 10.20210101\" or debian: \"< 10.20210101\"","category":"page"},{"location":"development/proposals/MEP8/README/","page":"Configurable Filesystem layout for Machine Allocation","title":"Configurable Filesystem layout for Machine Allocation","text":"The general form of a image constraint is a map from os to versionconstraint where:","category":"page"},{"location":"development/proposals/MEP8/README/","page":"Configurable Filesystem layout for Machine Allocation","title":"Configurable Filesystem layout for Machine Allocation","text":"os must match the first part of the image without the version. versionconstraint must be the comparator, a space and the version, or simply * to match all versions of this os. The comparator must be one of: \"=\", \"!=\", \">\", \"<\", \">=\", \"=>\", \"<=\", \"=<\", \"~\", \"~>\", \"^\"","category":"page"},{"location":"development/proposals/MEP8/README/","page":"Configurable Filesystem layout for Machine Allocation","title":"Configurable Filesystem layout for Machine Allocation","text":"It must also be possible to have a filesystemlayout in development or for other special purposes, which can be specified during the machine allocation. To have such a layout, both constraints sizes and imagesmust be empty list.","category":"page"},{"location":"development/proposals/MEP8/README/#Reinstall","page":"Configurable Filesystem layout for Machine Allocation","title":"Reinstall","text":"","category":"section"},{"location":"development/proposals/MEP8/README/","page":"Configurable Filesystem layout for Machine Allocation","title":"Configurable Filesystem layout for Machine Allocation","text":"The current reinstall implementation the metal-hammer detects during the installation on which disk the OS was installed and reports back to the metal-api the Report struct which has two properties primarydisk and ospartition. Both fields are not required anymore because the logic is now shifted to the filesystemlayout definition. If Disk.WipeOnReinstall is set to true, this disk will be wiped, default is false and is preserved.","category":"page"},{"location":"development/proposals/MEP8/README/#Handling-of-s2-xlarge-machines","page":"Configurable Filesystem layout for Machine Allocation","title":"Handling of s2-xlarge machines","text":"","category":"section"},{"location":"development/proposals/MEP8/README/","page":"Configurable Filesystem layout for Machine Allocation","title":"Configurable Filesystem layout for Machine Allocation","text":"These machines are a bit special compared to our c1-* machines because they have rotating hard disks for the mass storage purpose. The downside is that the on board SATA-DOM has the same naming as the HDDs and can not be specified as the first /dev/sda disk because all HDDs are also /dev/sd* disks. Therefore we had a special SATA-DOM detection algorithm inside metal-hammer which simply checks for the smallest /dev/sd disk and took this to install the OS.","category":"page"},{"location":"development/proposals/MEP8/README/","page":"Configurable Filesystem layout for Machine Allocation","title":"Configurable Filesystem layout for Machine Allocation","text":"This is not possible with the current approach, but we figured out that the SATA-DOM is always /dev/sde. So we can create a special filesystemlayout where the installations is made on this disk.","category":"page"},{"location":"development/proposals/MEP8/README/#Possible-Filesystemlayout-hierarchies","page":"Configurable Filesystem layout for Machine Allocation","title":"Possible Filesystemlayout hierarchies","text":"","category":"section"},{"location":"development/proposals/MEP8/README/","page":"Configurable Filesystem layout for Machine Allocation","title":"Configurable Filesystem layout for Machine Allocation","text":"It is only possible to create a filesystem on top of a block device. The creation of a block device can be done on multiple ways, depending on the requirements regarding performance, space and redundancy of the filesystem. It also depends on the disks available on the server.","category":"page"},{"location":"development/proposals/MEP8/README/","page":"Configurable Filesystem layout for Machine Allocation","title":"Configurable Filesystem layout for Machine Allocation","text":"The current approach implements the following hierarchies:","category":"page"},{"location":"development/proposals/MEP8/README/","page":"Configurable Filesystem layout for Machine Allocation","title":"Configurable Filesystem layout for Machine Allocation","text":"(Image: filesystems)","category":"page"},{"location":"development/proposals/MEP8/README/#Implementation","page":"Configurable Filesystem layout for Machine Allocation","title":"Implementation","text":"","category":"section"},{"location":"development/proposals/MEP8/README/","page":"Configurable Filesystem layout for Machine Allocation","title":"Configurable Filesystem layout for Machine Allocation","text":"// FilesystemLayout to be created on the given machine\ntype FilesystemLayout struct {\n // ID unique layout identifier\n ID string\n // Description is human readable\n Description string\n // Filesystems to create on the server\n Filesystems []Filesystem\n // Disks to configure in the server with their partitions\n Disks []Disk\n // Raid if not empty, create raid arrays out of the individual disks, to place filesystems onto\n Raid []Raid\n // VolumeGroups to create\n VolumeGroups []VolumeGroup\n // LogicalVolumes to create on top of VolumeGroups\n LogicalVolumes []LogicalVolume\n // Constraints which must match to select this Layout\n Constraints FilesystemLayoutConstraints\n}\n\ntype FilesystemLayoutConstraints struct {\n // Sizes defines the list of sizes this layout applies to\n Sizes []string\n // Images defines a map from os to versionconstraint\n // the combination of os and versionconstraint per size must be conflict free over all filesystemlayouts\n Images map[string]string\n}\n\ntype RaidLevel string\ntype Format string\ntype GPTType string\n\n// Filesystem defines a single filesystem to be mounted\ntype Filesystem struct {\n // Path defines the mountpoint, if nil, it will not be mounted\n Path *string\n // Device where the filesystem is created on, must be the full device path seen by the OS\n Device string\n // Format is the type of filesystem should be created\n Format Format\n // Label is optional enhances readability\n Label *string\n // MountOptions which might be required\n MountOptions []string\n // CreateOptions during filesystem creation\n CreateOptions []string\n}\n\n// Disk represents a single block device visible from the OS, required\ntype Disk struct {\n // Device is the full device path\n Device string\n // Partitions to create on this device\n Partitions []Partition\n // WipeOnReinstall, if set to true the whole disk will be erased if reinstall happens\n // during fresh install all disks are wiped\n WipeOnReinstall bool\n}\n\n// Raid is optional, if given the devices must match.\n// TODO inherit GPTType from underlay device ?\ntype Raid struct {\n // ArryName of the raid device, most often this will be /dev/md0 and so forth\n ArryName string\n // Devices the devices to form a raid device\n Devices []Device\n // Level the raidlevel to use, can be one of 0,1,5,10 \n // TODO what should be support\n Level RaidLevel\n // CreateOptions required during raid creation, example: --metadata=1.0 for uefi boot partition\n CreateOptions []string\n // Spares defaults to 0\n Spares int\n}\n\n\n// VolumeGroup is optional, if given the devices must match.\ntype VolumeGroup struct {\n // Name of the volumegroup without the /dev prefix\n Name string\n // Devices the devices to form a volumegroup device\n Devices []string\n // Tags to attach to the volumegroup\n Tags []string\n}\n\n// LogicalVolume is a block devices created with lvm on top of a volumegroup\ntype LogicalVolume struct {\n // Name the name of the logical volume, without /dev prefix, will be accessible at /dev/vgname/lvname\n Name string\n // VolumeGroup the name of the volumegroup\n VolumeGroup string\n // Size of this LV in mebibytes (MiB)\n Size uint64\n // LVMType can be either striped or raid1\n LVMType LVMType\n}\n\n// Partition is a single partition on a device, only GPT partition types are supported\ntype Partition struct {\n // Number of this partition, will be added to the device once partitioned\n Number int\n // Label to enhance readability\n Label *string\n // Size given in MebiBytes (MiB)\n // if \"0\" is given the rest of the device will be used, this requires Number to be the highest in this partition\n Size string\n // GPTType defines the GPT partition type\n GPTType *GPTType\n}\n\nconst (\n // VFAT is used for the UEFI boot partition\n VFAT = Format(\"vfat\")\n // EXT3 is usually only used for /boot\n EXT3 = Format(\"ext3\")\n // EXT4 is the default fs\n EXT4 = Format(\"ext4\")\n // SWAP is for the swap partition\n SWAP = Format(\"swap\")\n // None\n NONE = Format(\"none\")\n\n // GPTBoot EFI Boot Partition\n GPTBoot = GPTType(\"ef00\")\n // GPTLinux Linux Partition\n GPTLinux = GPTType(\"8300\")\n // GPTLinuxRaid Linux Raid Partition\n GPTLinuxRaid = GPTType(\"fd00\")\n // GPTLinux Linux Partition\n GPTLinuxLVM = GPTType(\"8e00\")\n\n // LVMTypeLinear append across all physical volumes\n LVMTypeLinear = LVMType(\"linear\")\n // LVMTypeStriped stripe across all physical volumes\n LVMTypeStriped = LVMType(\"striped\")\n // LVMTypeStripe mirror with raid across all physical volumes\n LVMTypeRaid1 = LVMType(\"raid1\")\n)","category":"page"},{"location":"development/proposals/MEP8/README/","page":"Configurable Filesystem layout for Machine Allocation","title":"Configurable Filesystem layout for Machine Allocation","text":"Example metalctl outputs:","category":"page"},{"location":"development/proposals/MEP8/README/","page":"Configurable Filesystem layout for Machine Allocation","title":"Configurable Filesystem layout for Machine Allocation","text":"$ metalctl filesystemlayouts ls\nID DESCRIPTION SIZES IMAGES\ndefault default fs layout c1-large-x86, c1-xlarge-x86 debian >=10, ubuntu >=20.04, centos >=7\nceph fs layout for ceph s2-large-x86, s2-xlarge-x86 debian >=10, ubuntu >=20.04\nfirewall firewall fs layout c1-large-x86, c1-xlarge-x86 firewall >=2\nstorage storage fs layout s3-large-x86 centos >=7\ns3 storage fs layout s2-xlarge-x86 debian >=10, ubuntu >=20.04, >=firewall-2\ndefault-devel devel fs layout ","category":"page"},{"location":"development/proposals/MEP8/README/","page":"Configurable Filesystem layout for Machine Allocation","title":"Configurable Filesystem layout for Machine Allocation","text":"The default layout reflects what is actually implemented in metal-hammer to guarantee backward compatibility.","category":"page"},{"location":"development/proposals/MEP8/README/","page":"Configurable Filesystem layout for Machine Allocation","title":"Configurable Filesystem layout for Machine Allocation","text":"---\nid: default\nconstraints:\n sizes:\n - c1-large-x86\n - c1-xlarge-x86\n images:\n debian: \">=10\"\n ubuntu: \">=20.04\"\n centos: \">=7\"\nfilesystems:\n - path: \"/boot/efi\"\n device: \"/dev/sda1\"\n format: \"vfat\"\n options: \"-F 32\"\n label: \"efi\" # required to be compatible with old images\n - path: \"/\"\n device: \"/dev/sda2\"\n format: \"ext4\"\n label: \"root\" # required to be compatible with old images\n - path: \"/var/lib\"\n device: \"/dev/sda3\"\n format: \"ext4\"\n label: \"varlib\" # required to be compatible with old images\n - path: \"/tmp\"\n device: \"tmpfs\"\n format: \"tmpfs\"\n mountoptions: [\"defaults\",\"noatime\",\"nosuid\",\"nodev\",\"noexec\",\"mode=1777\",\"size=512M\"]\ndisks:\n - device: \"/dev/sda\"\n wipe: true\n partitions:\n - number: 1\n label: \"efi\"\n size: 500\n type: GPTBoot\n - number: 2\n label: \"root\"\n size: 5000\n type: GPTLinux\n - number: 3\n label: \"varlib\"\n size: 0 # to end of partition\n type: GPTLinux","category":"page"},{"location":"development/proposals/MEP8/README/","page":"Configurable Filesystem layout for Machine Allocation","title":"Configurable Filesystem layout for Machine Allocation","text":"The firewall layout reuses the built in nvme disk to store the logs, which is way faster and larger than what the sata-dom ssd provides.","category":"page"},{"location":"development/proposals/MEP8/README/","page":"Configurable Filesystem layout for Machine Allocation","title":"Configurable Filesystem layout for Machine Allocation","text":"---\nid: firewall\nconstraints:\n sizes:\n - c1-large-x86\n - c1-xlarge-x86\n images:\n firewall: \">=2\"\nfilesystems:\n - path: \"/boot/efi\"\n device: \"/dev/sda1\"\n format: \"vfat\"\n options: \"-F 32\"\n - path: \"/\"\n device: \"/dev/sda2\"\n format: \"ext4\"\n - path: \"/var\"\n device: \"/dev/nvme0n1p1\"\n format: \"ext4\"\ndisks:\n - device: \"/dev/sda\"\n wipe: true\n partitions:\n - number: 1\n label: \"efi\"\n size: 500\n type: GPTBoot\n - number: 2\n label: \"root\"\n size: 5000\n type: GPTLinux\n - device: \"/dev/nvme0n1\"\n wipe: true\n partitions:\n - number: 1\n label: \"var\"\n size: 0\n type: GPTLinux","category":"page"},{"location":"development/proposals/MEP8/README/","page":"Configurable Filesystem layout for Machine Allocation","title":"Configurable Filesystem layout for Machine Allocation","text":"The storage layout will be used for the storage servers, which must have mirrored boot disks.","category":"page"},{"location":"development/proposals/MEP8/README/","page":"Configurable Filesystem layout for Machine Allocation","title":"Configurable Filesystem layout for Machine Allocation","text":"---\nid: storage\nconstraints:\n sizes:\n - s3-large-x86\n images:\n centos: \">=7\"\nfilesystems:\n - path: \"/boot/efi\"\n device: \"/dev/md1\"\n format: \"vfat\"\n options: \"-F32\"\n - path: \"/\"\n device: \"/dev/md2\"\n format: \"ext4\"\ndisks:\n - device: \"/dev/sda\"\n wipe: true\n partitions:\n - number: 1\n label: \"efi\"\n size: 500\n type: GPTLinuxRaid\n - number: 2\n label: \"root\"\n size: 5000\n type: GPTLinuxRaid\n - device: \"/dev/sdb\"\n wipe: true\n partitions:\n - number: 1\n label: \"efi\"\n size: 500\n type: GPTLinuxRaid\n - number: 2\n label: \"root\"\n size: 5000\n type: GPTLinuxRaid\nraid:\n - name: \"/dev/md1\"\n level: 1\n devices:\n - \"/dev/sda1\"\n - \"/dev/sdb1\"\n options: \"--metadata=1.0\"\n - name: \"/dev/md2\"\n level: 1\n devices:\n - \"/dev/sda2\"\n - \"/dev/sdb2\"\n options: \"--metadata=1.0\"","category":"page"},{"location":"development/proposals/MEP8/README/","page":"Configurable Filesystem layout for Machine Allocation","title":"Configurable Filesystem layout for Machine Allocation","text":"The s3-storage layout matches the special situation on the s2-xlarge machines.","category":"page"},{"location":"development/proposals/MEP8/README/","page":"Configurable Filesystem layout for Machine Allocation","title":"Configurable Filesystem layout for Machine Allocation","text":"---\nid: s3-storage\nconstraints:\n sizes:\n - c1-large-x86\n - s2-xlarge-x86\n images:\n debian: \">=10\"\n ubuntu: \">=20.04\"\n centos: \">=7\"\nfilesystems:\n - path: \"/boot/efi\"\n device: \"/dev/sde1\"\n format: \"vfat\"\n options: \"-F 32\"\n - path: \"/\"\n device: \"/dev/sde2\"\n format: \"ext4\"\n - path: \"/var/lib\"\n device: \"/dev/sde3\"\n format: \"ext4\"\ndisks:\n - device: \"/dev/sde\"\n wipe: true\n partitions:\n - number: 1\n label: \"efi\"\n size: 500\n type: GPTBoot\n - number: 2\n label: \"root\"\n size: 5000\n type: GPTLinux\n - number: 3\n label: \"varlib\"\n size: 0 # to end of partition\n type: GPTLinux","category":"page"},{"location":"development/proposals/MEP8/README/","page":"Configurable Filesystem layout for Machine Allocation","title":"Configurable Filesystem layout for Machine Allocation","text":"A sample lvm layout which puts /var/lib as stripe on the nvme device","category":"page"},{"location":"development/proposals/MEP8/README/","page":"Configurable Filesystem layout for Machine Allocation","title":"Configurable Filesystem layout for Machine Allocation","text":"---\nid: lvm\ndescription: \"lvm layout\"\nconstraints:\n size:\n - s2-xlarge-x86\n images:\n debian: \">=10\"\n ubuntu: \">=20.04\"\n centos: \">=7\"\nfilesystems:\n - path: \"/boot/efi\"\n device: \"/dev/sda1\"\n format: \"vfat\"\n createoptions: \n - \"-F 32\"\n label: \"efi\"\n - path: \"/\"\n device: \"/dev/sda2\"\n format: \"ext4\"\n label: \"root\"\n - path: \"/var/lib\"\n device: \"/dev/vg00/varlib\"\n format: \"ext4\"\n label: \"varlib\"\n - path: \"/tmp\"\n device: \"tmpfs\"\n format: \"tmpfs\"\n mountoptions: [\"defaults\",\"noatime\",\"nosuid\",\"nodev\",\"noexec\",\"mode=1777\",\"size=512M\"]\nvolumegroups:\n - name: \"vg00\"\n devices:\n - \"/dev/nvmne0n1\"\n - \"/dev/nvmne0n2\"\nlogicalvolumes:\n - name: \"varlib\"\n volumegroup: \"vg00\"\n size: 200\n lvmtype: \"striped\"\ndisks:\n - device: \"/dev/sda\"\n wipeonreinstall: true\n partitions:\n - number: 1\n label: \"efi\"\n size: 500\n gpttype: \"ef00\"\n - number: 2\n label: \"root\"\n size: 5000\n gpttype: \"8300\"\n - device: \"/dev/nvmne0n1\"\n wipeonreinstall: false\n - device: \"/dev/nvmne0n2\"\n wipeonreinstall: false","category":"page"},{"location":"development/proposals/MEP8/README/#Components-which-requires-modifications","page":"Configurable Filesystem layout for Machine Allocation","title":"Components which requires modifications","text":"","category":"section"},{"location":"development/proposals/MEP8/README/","page":"Configurable Filesystem layout for Machine Allocation","title":"Configurable Filesystem layout for Machine Allocation","text":"metal-hammer:\nchange implementation from build in hard coded logic\nmove logic to create fstab from install.sh to metal-hammer\nmetal-api:\nnew endpoint filesystemlayouts\nadd optional spec of filesystemlayout during allocation with validation if given filesystemlayout is possible on given size.\nadd allocation.filesystemlayout in the response, based on either the specified filesystemlayout or the calculated one.\nimplement filesystemlayouts validation for:\nmatching to disks in the size\nno overlapping with the sizes/imagefilter specified in filesystemlayouts\nall devices specified exists from top to bottom (fs -> disks -> device || fs -> raid -> devices)\nmetalctl:\nimplement filesystemlayouts\nmetal-go:\nadopt api changes\nmetal-images:\ninstall mdadm for raid support","category":"page"},{"location":"external/metalctl/docs/metalctl_network_update/#metalctl-network-update","page":"metalctl network update","title":"metalctl network update","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_network_update/","page":"metalctl network update","title":"metalctl network update","text":"updates the network","category":"page"},{"location":"external/metalctl/docs/metalctl_network_update/","page":"metalctl network update","title":"metalctl network update","text":"metalctl network update [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_network_update/#Options","page":"metalctl network update","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_network_update/","page":"metalctl network update","title":"metalctl network update","text":" --add-destinationprefixes strings destination prefixes to be added to the network [optional]\n --add-prefixes strings prefixes to be added to the network [optional]\n --additional-announcable-cidrs strings list of cidrs which are added to the route maps per tenant private network, these are typically pod- and service cidrs, can only be set in a supernetwork\n --bulk-output when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.\n --description string the description of the network [optional]\n -f, --file string filename of the create or update request in yaml format, or - for stdin.\n \n Example:\n $ metalctl network describe network-1 -o yaml > network.yaml\n $ vi network.yaml\n $ # either via stdin\n $ cat network.yaml | metalctl network update -f -\n $ # or via file\n $ metalctl network update -f network.yaml\n \n the file can also contain multiple documents and perform a bulk operation.\n \t\n -h, --help help for update\n --labels strings the labels of the network, must be in the form of key=value, use it like: --labels \"key1=value1,key2=value2\". [optional]\n --name string the name of the network [optional]\n --remove-destinationprefixes strings destination prefixes to be removed from the network [optional]\n --remove-prefixes strings prefixes to be removed from the network [optional]\n --shared marks a network as shared or not [optional]\n --skip-security-prompts skips security prompt for bulk operations\n --timestamps when used with --file (bulk operation): prints timestamps in-between the operations","category":"page"},{"location":"external/metalctl/docs/metalctl_network_update/#Options-inherited-from-parent-commands","page":"metalctl network update","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_network_update/","page":"metalctl network update","title":"metalctl network update","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_network_update/#SEE-ALSO","page":"metalctl network update","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_network_update/","page":"metalctl network update","title":"metalctl network update","text":"metalctl network\t - manage network entities","category":"page"},{"location":"external/metalctl/docs/metalctl_size_edit/#metalctl-size-edit","page":"metalctl size edit","title":"metalctl size edit","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_edit/","page":"metalctl size edit","title":"metalctl size edit","text":"edit the size through an editor and update","category":"page"},{"location":"external/metalctl/docs/metalctl_size_edit/","page":"metalctl size edit","title":"metalctl size edit","text":"metalctl size edit [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_size_edit/#Options","page":"metalctl size edit","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_edit/","page":"metalctl size edit","title":"metalctl size edit","text":" -h, --help help for edit","category":"page"},{"location":"external/metalctl/docs/metalctl_size_edit/#Options-inherited-from-parent-commands","page":"metalctl size edit","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_edit/","page":"metalctl size edit","title":"metalctl size edit","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_size_edit/#SEE-ALSO","page":"metalctl size edit","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_edit/","page":"metalctl size edit","title":"metalctl size edit","text":"metalctl size\t - manage size entities","category":"page"},{"location":"external/metalctl/docs/metalctl_size_imageconstraint_delete/#metalctl-size-imageconstraint-delete","page":"metalctl size imageconstraint delete","title":"metalctl size imageconstraint delete","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_imageconstraint_delete/","page":"metalctl size imageconstraint delete","title":"metalctl size imageconstraint delete","text":"deletes the imageconstraint","category":"page"},{"location":"external/metalctl/docs/metalctl_size_imageconstraint_delete/","page":"metalctl size imageconstraint delete","title":"metalctl size imageconstraint delete","text":"metalctl size imageconstraint delete [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_size_imageconstraint_delete/#Options","page":"metalctl size imageconstraint delete","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_imageconstraint_delete/","page":"metalctl size imageconstraint delete","title":"metalctl size imageconstraint delete","text":" --bulk-output when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.\n -f, --file string filename of the create or update request in yaml format, or - for stdin.\n \n Example:\n $ metalctl imageconstraint describe imageconstraint-1 -o yaml > imageconstraint.yaml\n $ vi imageconstraint.yaml\n $ # either via stdin\n $ cat imageconstraint.yaml | metalctl imageconstraint delete -f -\n $ # or via file\n $ metalctl imageconstraint delete -f imageconstraint.yaml\n \n the file can also contain multiple documents and perform a bulk operation.\n \t\n -h, --help help for delete\n --skip-security-prompts skips security prompt for bulk operations\n --timestamps when used with --file (bulk operation): prints timestamps in-between the operations","category":"page"},{"location":"external/metalctl/docs/metalctl_size_imageconstraint_delete/#Options-inherited-from-parent-commands","page":"metalctl size imageconstraint delete","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_imageconstraint_delete/","page":"metalctl size imageconstraint delete","title":"metalctl size imageconstraint delete","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_size_imageconstraint_delete/#SEE-ALSO","page":"metalctl size imageconstraint delete","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_imageconstraint_delete/","page":"metalctl size imageconstraint delete","title":"metalctl size imageconstraint delete","text":"metalctl size imageconstraint\t - manage imageconstraint entities","category":"page"},{"location":"development/proposals/MEP12/README/#Rack-Spreading","page":"Rack Spreading","title":"Rack Spreading","text":"","category":"section"},{"location":"development/proposals/MEP12/README/","page":"Rack Spreading","title":"Rack Spreading","text":"Currently, when creating a machine through the metal-api, the machine is placed randomly inside a partition. This algorithm does not consider spreading machines across different racks and different chassis. This may lead to the situation that a group of machines (that for example form a cluster) can end up being placed in the same rack and the same chassis.","category":"page"},{"location":"development/proposals/MEP12/README/","page":"Rack Spreading","title":"Rack Spreading","text":"Spreading a group of machines across racks can enhance availability for scenarios like a rack loosing power or a chassis meltdown.","category":"page"},{"location":"development/proposals/MEP12/README/","page":"Rack Spreading","title":"Rack Spreading","text":"So, instead of just randomly deciding the placement of a machine candidate, we want to propose a placement strategy that attempts to spread machine candidates across the racks inside a partition.","category":"page"},{"location":"development/proposals/MEP12/README/","page":"Rack Spreading","title":"Rack Spreading","text":"Furthermore a followup improvement to guarantee that machines are really spread across multiple racks, even if multiple machines are ordered in parallel, was implemented with PR490.","category":"page"},{"location":"development/proposals/MEP12/README/#Placement-Strategy","page":"Rack Spreading","title":"Placement Strategy","text":"","category":"section"},{"location":"development/proposals/MEP12/README/","page":"Rack Spreading","title":"Rack Spreading","text":"Machines in the project are spread across all available racks evenly within a partition (best effort). For this, an additional request to the datastore has to be made in order to find allocated machines within the project in the partition.","category":"page"},{"location":"development/proposals/MEP12/README/","page":"Rack Spreading","title":"Rack Spreading","text":"The algorithm will then figure out the least occupied racks and elect a machine candidate randomly from those racks.","category":"page"},{"location":"development/proposals/MEP12/README/","page":"Rack Spreading","title":"Rack Spreading","text":"The user can optionally pass placement tags which will be considered for spreading the machines as well (this will for example allow spreading by a cluster id tag inside the same project).","category":"page"},{"location":"development/proposals/MEP12/README/#API","page":"Rack Spreading","title":"API","text":"","category":"section"},{"location":"development/proposals/MEP12/README/","page":"Rack Spreading","title":"Rack Spreading","text":"// service/v1/machine.go\n\ntype MachineAllocation struct {\n // existing fields are omitted for readability\n PlacementTags []string `json:\"placement_tags\" description:\"by default machines are spread across the racks inside a partition for every project. if placement tags are provided, the machine candidate has an additional anti-affinity to other machines having the same tags\"`\n}","category":"page"},{"location":"external/mini-lab/CONTRIBUTING/#Contributing","page":"Contributing","title":"Contributing","text":"","category":"section"},{"location":"external/mini-lab/CONTRIBUTING/","page":"Contributing","title":"Contributing","text":"Please check out the contributing section in our docs.","category":"page"},{"location":"external/metalctl/docs/metalctl_completion/#metalctl-completion","page":"metalctl completion","title":"metalctl completion","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_completion/","page":"metalctl completion","title":"metalctl completion","text":"Generate the autocompletion script for the specified shell","category":"page"},{"location":"external/metalctl/docs/metalctl_completion/#Synopsis","page":"metalctl completion","title":"Synopsis","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_completion/","page":"metalctl completion","title":"metalctl completion","text":"Generate the autocompletion script for metalctl for the specified shell. See each sub-command's help for details on how to use the generated script.","category":"page"},{"location":"external/metalctl/docs/metalctl_completion/#Options","page":"metalctl completion","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_completion/","page":"metalctl completion","title":"metalctl completion","text":" -h, --help help for completion","category":"page"},{"location":"external/metalctl/docs/metalctl_completion/#Options-inherited-from-parent-commands","page":"metalctl completion","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_completion/","page":"metalctl completion","title":"metalctl completion","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_completion/#SEE-ALSO","page":"metalctl completion","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_completion/","page":"metalctl completion","title":"metalctl completion","text":"metalctl\t - a cli to manage entities in the metal-stack api\nmetalctl completion bash\t - Generate the autocompletion script for bash\nmetalctl completion fish\t - Generate the autocompletion script for fish\nmetalctl completion powershell\t - Generate the autocompletion script for powershell\nmetalctl completion zsh\t - Generate the autocompletion script for zsh","category":"page"},{"location":"external/metalctl/docs/metalctl_network_ip_list/#metalctl-network-ip-list","page":"metalctl network ip list","title":"metalctl network ip list","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_network_ip_list/","page":"metalctl network ip list","title":"metalctl network ip list","text":"list all ips","category":"page"},{"location":"external/metalctl/docs/metalctl_network_ip_list/","page":"metalctl network ip list","title":"metalctl network ip list","text":"metalctl network ip list [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_network_ip_list/#Options","page":"metalctl network ip list","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_network_ip_list/","page":"metalctl network ip list","title":"metalctl network ip list","text":" -h, --help help for list\n --ipaddress string ipaddress to filter [optional]\n --machineid string machineid to filter [optional]\n --name string name to filter [optional]\n --network string network to filter [optional]\n --prefix string prefix to filter [optional]\n --project string project to filter [optional]\n --sort-by strings sort by (comma separated) column(s), sort direction can be changed by appending :asc or :desc behind the column identifier. possible values: age|description|id|ipaddress|name|network|type\n --tags strings tags to filter [optional]\n --type string type to filter [optional]","category":"page"},{"location":"external/metalctl/docs/metalctl_network_ip_list/#Options-inherited-from-parent-commands","page":"metalctl network ip list","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_network_ip_list/","page":"metalctl network ip list","title":"metalctl network ip list","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_network_ip_list/#SEE-ALSO","page":"metalctl network ip list","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_network_ip_list/","page":"metalctl network ip list","title":"metalctl network ip list","text":"metalctl network ip\t - manage ip entities","category":"page"},{"location":"external/metalctl/docs/metalctl_size_update/#metalctl-size-update","page":"metalctl size update","title":"metalctl size update","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_update/","page":"metalctl size update","title":"metalctl size update","text":"updates the size","category":"page"},{"location":"external/metalctl/docs/metalctl_size_update/","page":"metalctl size update","title":"metalctl size update","text":"metalctl size update [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_size_update/#Options","page":"metalctl size update","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_update/","page":"metalctl size update","title":"metalctl size update","text":" --bulk-output when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.\n -f, --file string filename of the create or update request in yaml format, or - for stdin.\n \n Example:\n $ metalctl size describe size-1 -o yaml > size.yaml\n $ vi size.yaml\n $ # either via stdin\n $ cat size.yaml | metalctl size update -f -\n $ # or via file\n $ metalctl size update -f size.yaml\n \n the file can also contain multiple documents and perform a bulk operation.\n \t\n -h, --help help for update\n --skip-security-prompts skips security prompt for bulk operations\n --timestamps when used with --file (bulk operation): prints timestamps in-between the operations","category":"page"},{"location":"external/metalctl/docs/metalctl_size_update/#Options-inherited-from-parent-commands","page":"metalctl size update","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_update/","page":"metalctl size update","title":"metalctl size update","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_size_update/#SEE-ALSO","page":"metalctl size update","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_update/","page":"metalctl size update","title":"metalctl size update","text":"metalctl size\t - manage size entities","category":"page"},{"location":"external/metalctl/docs/metalctl_network_create/#metalctl-network-create","page":"metalctl network create","title":"metalctl network create","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_network_create/","page":"metalctl network create","title":"metalctl network create","text":"creates the network","category":"page"},{"location":"external/metalctl/docs/metalctl_network_create/","page":"metalctl network create","title":"metalctl network create","text":"metalctl network create [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_network_create/#Options","page":"metalctl network create","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_network_create/","page":"metalctl network create","title":"metalctl network create","text":" --additional-announcable-cidrs strings list of cidrs which are added to the route maps per tenant private network, these are typically pod- and service cidrs, can only be set in a supernetwork\n --bulk-output when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.\n -d, --description string description of the network to create. [optional]\n --destination-prefixes strings destination prefixes in this network.\n -f, --file string filename of the create or update request in yaml format, or - for stdin.\n \n Example:\n $ metalctl network describe network-1 -o yaml > network.yaml\n $ vi network.yaml\n $ # either via stdin\n $ cat network.yaml | metalctl network create -f -\n $ # or via file\n $ metalctl network create -f network.yaml\n \n the file can also contain multiple documents and perform a bulk operation.\n \t\n -h, --help help for create\n --id string id of the network to create. [optional]\n --labels strings add initial labels, must be in the form of key=value, use it like: --labels \"key1=value1,key2=value2\".\n -n, --name string name of the network to create. [optional]\n --nat set nat flag of network, if set to true, traffic from this network will be natted.\n -p, --partition string partition where this network should exist.\n --prefixes strings prefixes in this network.\n --privatesuper set private super flag of network, if set to true, this network is used to start machines there.\n --project string project of the network to create. [optional]\n --skip-security-prompts skips security prompt for bulk operations\n --timestamps when used with --file (bulk operation): prints timestamps in-between the operations\n --underlay set underlay flag of network, if set to true, this is used to transport underlay network traffic\n --vrf int vrf of this network\n --vrfshared vrf shared allows multiple networks to share a vrf","category":"page"},{"location":"external/metalctl/docs/metalctl_network_create/#Options-inherited-from-parent-commands","page":"metalctl network create","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_network_create/","page":"metalctl network create","title":"metalctl network create","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_network_create/#SEE-ALSO","page":"metalctl network create","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_network_create/","page":"metalctl network create","title":"metalctl network create","text":"metalctl network\t - manage network entities","category":"page"},{"location":"external/metalctl/docs/metalctl_size_reservation_update/#metalctl-size-reservation-update","page":"metalctl size reservation update","title":"metalctl size reservation update","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_reservation_update/","page":"metalctl size reservation update","title":"metalctl size reservation update","text":"updates the reservation","category":"page"},{"location":"external/metalctl/docs/metalctl_size_reservation_update/","page":"metalctl size reservation update","title":"metalctl size reservation update","text":"metalctl size reservation update [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_size_reservation_update/#Options","page":"metalctl size reservation update","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_reservation_update/","page":"metalctl size reservation update","title":"metalctl size reservation update","text":" --amount int32 the amount to associate with this reservation\n --bulk-output when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.\n --description string the description to associate with this reservation\n -f, --file string filename of the create or update request in yaml format, or - for stdin.\n \n Example:\n $ metalctl reservation describe reservation-1 -o yaml > reservation.yaml\n $ vi reservation.yaml\n $ # either via stdin\n $ cat reservation.yaml | metalctl reservation update -f -\n $ # or via file\n $ metalctl reservation update -f reservation.yaml\n \n the file can also contain multiple documents and perform a bulk operation.\n \t\n -h, --help help for update\n --labels strings the labels to associate with this reservation\n --partitions strings the partition ids to associate with this reservation\n --skip-security-prompts skips security prompt for bulk operations\n --timestamps when used with --file (bulk operation): prints timestamps in-between the operations","category":"page"},{"location":"external/metalctl/docs/metalctl_size_reservation_update/#Options-inherited-from-parent-commands","page":"metalctl size reservation update","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_reservation_update/","page":"metalctl size reservation update","title":"metalctl size reservation update","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_size_reservation_update/#SEE-ALSO","page":"metalctl size reservation update","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_reservation_update/","page":"metalctl size reservation update","title":"metalctl size reservation update","text":"metalctl size reservation\t - manage reservation entities","category":"page"},{"location":"external/metalctl/docs/metalctl_filesystemlayout_update/#metalctl-filesystemlayout-update","page":"metalctl filesystemlayout update","title":"metalctl filesystemlayout update","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_filesystemlayout_update/","page":"metalctl filesystemlayout update","title":"metalctl filesystemlayout update","text":"updates the filesystemlayout","category":"page"},{"location":"external/metalctl/docs/metalctl_filesystemlayout_update/","page":"metalctl filesystemlayout update","title":"metalctl filesystemlayout update","text":"metalctl filesystemlayout update [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_filesystemlayout_update/#Options","page":"metalctl filesystemlayout update","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_filesystemlayout_update/","page":"metalctl filesystemlayout update","title":"metalctl filesystemlayout update","text":" --bulk-output when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.\n -f, --file string filename of the create or update request in yaml format, or - for stdin.\n \n Example:\n $ metalctl filesystemlayout describe filesystemlayout-1 -o yaml > filesystemlayout.yaml\n $ vi filesystemlayout.yaml\n $ # either via stdin\n $ cat filesystemlayout.yaml | metalctl filesystemlayout update -f -\n $ # or via file\n $ metalctl filesystemlayout update -f filesystemlayout.yaml\n \n the file can also contain multiple documents and perform a bulk operation.\n \t\n -h, --help help for update\n --skip-security-prompts skips security prompt for bulk operations\n --timestamps when used with --file (bulk operation): prints timestamps in-between the operations","category":"page"},{"location":"external/metalctl/docs/metalctl_filesystemlayout_update/#Options-inherited-from-parent-commands","page":"metalctl filesystemlayout update","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_filesystemlayout_update/","page":"metalctl filesystemlayout update","title":"metalctl filesystemlayout update","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_filesystemlayout_update/#SEE-ALSO","page":"metalctl filesystemlayout update","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_filesystemlayout_update/","page":"metalctl filesystemlayout update","title":"metalctl filesystemlayout update","text":"metalctl filesystemlayout\t - manage filesystemlayout entities","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_reinstall/#metalctl-machine-reinstall","page":"metalctl machine reinstall","title":"metalctl machine reinstall","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_reinstall/","page":"metalctl machine reinstall","title":"metalctl machine reinstall","text":"reinstalls an already allocated machine","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_reinstall/#Synopsis","page":"metalctl machine reinstall","title":"Synopsis","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_reinstall/","page":"metalctl machine reinstall","title":"metalctl machine reinstall","text":"reinstalls an already allocated machine. If it is not yet allocated, nothing happens, otherwise only the machine's primary disk is wiped and the new image will subsequently be installed on that device","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_reinstall/","page":"metalctl machine reinstall","title":"metalctl machine reinstall","text":"metalctl machine reinstall [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_reinstall/#Options","page":"metalctl machine reinstall","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_reinstall/","page":"metalctl machine reinstall","title":"metalctl machine reinstall","text":" -d, --description string description of the reinstallation. [optional]\n -h, --help help for reinstall\n --image string id of the image to get installed. [required]","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_reinstall/#Options-inherited-from-parent-commands","page":"metalctl machine reinstall","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_reinstall/","page":"metalctl machine reinstall","title":"metalctl machine reinstall","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_reinstall/#SEE-ALSO","page":"metalctl machine reinstall","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_reinstall/","page":"metalctl machine reinstall","title":"metalctl machine reinstall","text":"metalctl machine\t - manage machine entities","category":"page"},{"location":"external/metalctl/docs/metalctl_network/#metalctl-network","page":"metalctl network","title":"metalctl network","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_network/","page":"metalctl network","title":"metalctl network","text":"manage network entities","category":"page"},{"location":"external/metalctl/docs/metalctl_network/#Synopsis","page":"metalctl network","title":"Synopsis","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_network/","page":"metalctl network","title":"metalctl network","text":"networks can be attached to a machine or firewall such that they can communicate with each other.","category":"page"},{"location":"external/metalctl/docs/metalctl_network/#Options","page":"metalctl network","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_network/","page":"metalctl network","title":"metalctl network","text":" -h, --help help for network","category":"page"},{"location":"external/metalctl/docs/metalctl_network/#Options-inherited-from-parent-commands","page":"metalctl network","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_network/","page":"metalctl network","title":"metalctl network","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_network/#SEE-ALSO","page":"metalctl network","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_network/","page":"metalctl network","title":"metalctl network","text":"metalctl\t - a cli to manage entities in the metal-stack api\nmetalctl network allocate\t - allocate a network\nmetalctl network apply\t - applies one or more networks from a given file\nmetalctl network create\t - creates the network\nmetalctl network delete\t - deletes the network\nmetalctl network describe\t - describes the network\nmetalctl network edit\t - edit the network through an editor and update\nmetalctl network free\t - free a network\nmetalctl network ip\t - manage ip entities\nmetalctl network list\t - list all networks\nmetalctl network update\t - updates the network","category":"page"},{"location":"external/metalctl/docs/metalctl_size_delete/#metalctl-size-delete","page":"metalctl size delete","title":"metalctl size delete","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_delete/","page":"metalctl size delete","title":"metalctl size delete","text":"deletes the size","category":"page"},{"location":"external/metalctl/docs/metalctl_size_delete/","page":"metalctl size delete","title":"metalctl size delete","text":"metalctl size delete [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_size_delete/#Options","page":"metalctl size delete","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_delete/","page":"metalctl size delete","title":"metalctl size delete","text":" --bulk-output when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.\n -f, --file string filename of the create or update request in yaml format, or - for stdin.\n \n Example:\n $ metalctl size describe size-1 -o yaml > size.yaml\n $ vi size.yaml\n $ # either via stdin\n $ cat size.yaml | metalctl size delete -f -\n $ # or via file\n $ metalctl size delete -f size.yaml\n \n the file can also contain multiple documents and perform a bulk operation.\n \t\n -h, --help help for delete\n --skip-security-prompts skips security prompt for bulk operations\n --timestamps when used with --file (bulk operation): prints timestamps in-between the operations","category":"page"},{"location":"external/metalctl/docs/metalctl_size_delete/#Options-inherited-from-parent-commands","page":"metalctl size delete","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_delete/","page":"metalctl size delete","title":"metalctl size delete","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_size_delete/#SEE-ALSO","page":"metalctl size delete","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_delete/","page":"metalctl size delete","title":"metalctl size delete","text":"metalctl size\t - manage size entities","category":"page"},{"location":"external/metalctl/docs/metalctl_completion_fish/#metalctl-completion-fish","page":"metalctl completion fish","title":"metalctl completion fish","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_completion_fish/","page":"metalctl completion fish","title":"metalctl completion fish","text":"Generate the autocompletion script for fish","category":"page"},{"location":"external/metalctl/docs/metalctl_completion_fish/#Synopsis","page":"metalctl completion fish","title":"Synopsis","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_completion_fish/","page":"metalctl completion fish","title":"metalctl completion fish","text":"Generate the autocompletion script for the fish shell.","category":"page"},{"location":"external/metalctl/docs/metalctl_completion_fish/","page":"metalctl completion fish","title":"metalctl completion fish","text":"To load completions in your current shell session:","category":"page"},{"location":"external/metalctl/docs/metalctl_completion_fish/","page":"metalctl completion fish","title":"metalctl completion fish","text":"metalctl completion fish | source","category":"page"},{"location":"external/metalctl/docs/metalctl_completion_fish/","page":"metalctl completion fish","title":"metalctl completion fish","text":"To load completions for every new session, execute once:","category":"page"},{"location":"external/metalctl/docs/metalctl_completion_fish/","page":"metalctl completion fish","title":"metalctl completion fish","text":"metalctl completion fish > ~/.config/fish/completions/metalctl.fish","category":"page"},{"location":"external/metalctl/docs/metalctl_completion_fish/","page":"metalctl completion fish","title":"metalctl completion fish","text":"You will need to start a new shell for this setup to take effect.","category":"page"},{"location":"external/metalctl/docs/metalctl_completion_fish/","page":"metalctl completion fish","title":"metalctl completion fish","text":"metalctl completion fish [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_completion_fish/#Options","page":"metalctl completion fish","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_completion_fish/","page":"metalctl completion fish","title":"metalctl completion fish","text":" -h, --help help for fish\n --no-descriptions disable completion descriptions","category":"page"},{"location":"external/metalctl/docs/metalctl_completion_fish/#Options-inherited-from-parent-commands","page":"metalctl completion fish","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_completion_fish/","page":"metalctl completion fish","title":"metalctl completion fish","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_completion_fish/#SEE-ALSO","page":"metalctl completion fish","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_completion_fish/","page":"metalctl completion fish","title":"metalctl completion fish","text":"metalctl completion\t - Generate the autocompletion script for the specified shell","category":"page"},{"location":"external/metalctl/docs/metalctl_size_imageconstraint_edit/#metalctl-size-imageconstraint-edit","page":"metalctl size imageconstraint edit","title":"metalctl size imageconstraint edit","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_imageconstraint_edit/","page":"metalctl size imageconstraint edit","title":"metalctl size imageconstraint edit","text":"edit the imageconstraint through an editor and update","category":"page"},{"location":"external/metalctl/docs/metalctl_size_imageconstraint_edit/","page":"metalctl size imageconstraint edit","title":"metalctl size imageconstraint edit","text":"metalctl size imageconstraint edit [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_size_imageconstraint_edit/#Options","page":"metalctl size imageconstraint edit","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_imageconstraint_edit/","page":"metalctl size imageconstraint edit","title":"metalctl size imageconstraint edit","text":" -h, --help help for edit","category":"page"},{"location":"external/metalctl/docs/metalctl_size_imageconstraint_edit/#Options-inherited-from-parent-commands","page":"metalctl size imageconstraint edit","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_imageconstraint_edit/","page":"metalctl size imageconstraint edit","title":"metalctl size imageconstraint edit","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_size_imageconstraint_edit/#SEE-ALSO","page":"metalctl size imageconstraint edit","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_imageconstraint_edit/","page":"metalctl size imageconstraint edit","title":"metalctl size imageconstraint edit","text":"metalctl size imageconstraint\t - manage imageconstraint entities","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_ipmi/#metalctl-machine-ipmi","page":"metalctl machine ipmi","title":"metalctl machine ipmi","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_ipmi/","page":"metalctl machine ipmi","title":"metalctl machine ipmi","text":"display ipmi details of the machine, if no machine ID is given all ipmi addresses are returned.","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_ipmi/#Synopsis","page":"metalctl machine ipmi","title":"Synopsis","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_ipmi/","page":"metalctl machine ipmi","title":"metalctl machine ipmi","text":"display ipmi details of the machine, if no machine ID is given all ipmi addresses are returned.","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_ipmi/","page":"metalctl machine ipmi","title":"metalctl machine ipmi","text":"Meaning of the emojis:","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_ipmi/","page":"metalctl machine ipmi","title":"metalctl machine ipmi","text":"🚧 Machine is reserved. Reserved machines are not considered for random allocation until the reservation flag is removed. 🔒 Machine is locked. Locked machines can not be deleted until the lock is removed. 💀 Machine is dead. The metal-api does not receive any events from this machine. ❗ Machine has a last event error. The machine has recently encountered an error during the provisioning lifecycle. ❓ Machine is in unknown condition. The metal-api does not receive phoned home events anymore or has never booted successfully. ⭕ Machine is in a provisioning crash loop. Flag can be reset through an API-triggered reboot or when the machine reaches the phoned home state. 🚑 Machine reclaim has failed. The machine was deleted but it is not going back into the available machine pool. 🛡 Machine is connected to our VPN, ssh access only possible via this VPN.","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_ipmi/","page":"metalctl machine ipmi","title":"metalctl machine ipmi","text":"metalctl machine ipmi [] [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_ipmi/#Options","page":"metalctl machine ipmi","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_ipmi/","page":"metalctl machine ipmi","title":"metalctl machine ipmi","text":" --bmc-address string bmc ipmi address (needs to include port) to filter [optional]\n --bmc-mac string bmc mac address to filter [optional]\n --board-part-number string fru board part number to filter [optional]\n -h, --help help for ipmi\n --hostname string allocation hostname to filter [optional]\n --id string ID to filter [optional]\n --image string allocation image to filter [optional]\n --last-event-error-threshold duration the duration up to how long in the past a machine last event error will be counted as an issue [optional] (default 1h0m0s)\n --mac string mac to filter [optional]\n --manufacturer string fru manufacturer to filter [optional]\n --name string allocation name to filter [optional]\n --network-destination-prefixes string network destination prefixes to filter [optional]\n --network-ids string network ids to filter [optional]\n --network-ips string network ips to filter [optional]\n --partition string partition to filter [optional]\n --product-part-number string fru product part number to filter [optional]\n --product-serial string fru product serial to filter [optional]\n --project string allocation project to filter [optional]\n --rack string rack to filter [optional]\n --role string allocation role to filter [optional]\n --size string size to filter [optional]\n --sort-by strings sort by (comma separated) column(s), sort direction can be changed by appending :asc or :desc behind the column identifier. possible values: age|bios|bmc|event|id|liveliness|partition|project|rack|size|when\n --state string state to filter [optional]\n --tags strings tags to filter, use it like: --tags \"tag1,tag2\" or --tags \"tag3\".","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_ipmi/#Options-inherited-from-parent-commands","page":"metalctl machine ipmi","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_ipmi/","page":"metalctl machine ipmi","title":"metalctl machine ipmi","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_ipmi/#SEE-ALSO","page":"metalctl machine ipmi","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_ipmi/","page":"metalctl machine ipmi","title":"metalctl machine ipmi","text":"metalctl machine\t - manage machine entities\nmetalctl machine ipmi events\t - display machine hardware events","category":"page"},{"location":"external/metalctl/docs/metalctl_size_reservation_apply/#metalctl-size-reservation-apply","page":"metalctl size reservation apply","title":"metalctl size reservation apply","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_reservation_apply/","page":"metalctl size reservation apply","title":"metalctl size reservation apply","text":"applies one or more reservations from a given file","category":"page"},{"location":"external/metalctl/docs/metalctl_size_reservation_apply/","page":"metalctl size reservation apply","title":"metalctl size reservation apply","text":"metalctl size reservation apply [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_size_reservation_apply/#Options","page":"metalctl size reservation apply","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_reservation_apply/","page":"metalctl size reservation apply","title":"metalctl size reservation apply","text":" --bulk-output when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.\n -f, --file string filename of the create or update request in yaml format, or - for stdin.\n \n Example:\n $ metalctl reservation describe reservation-1 -o yaml > reservation.yaml\n $ vi reservation.yaml\n $ # either via stdin\n $ cat reservation.yaml | metalctl reservation apply -f -\n $ # or via file\n $ metalctl reservation apply -f reservation.yaml\n \n the file can also contain multiple documents and perform a bulk operation.\n \t\n -h, --help help for apply\n --skip-security-prompts skips security prompt for bulk operations\n --timestamps when used with --file (bulk operation): prints timestamps in-between the operations","category":"page"},{"location":"external/metalctl/docs/metalctl_size_reservation_apply/#Options-inherited-from-parent-commands","page":"metalctl size reservation apply","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_reservation_apply/","page":"metalctl size reservation apply","title":"metalctl size reservation apply","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_size_reservation_apply/#SEE-ALSO","page":"metalctl size reservation apply","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_reservation_apply/","page":"metalctl size reservation apply","title":"metalctl size reservation apply","text":"metalctl size reservation\t - manage reservation entities","category":"page"},{"location":"external/metalctl/docs/metalctl_whoami/#metalctl-whoami","page":"metalctl whoami","title":"metalctl whoami","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_whoami/","page":"metalctl whoami","title":"metalctl whoami","text":"shows current user","category":"page"},{"location":"external/metalctl/docs/metalctl_whoami/#Synopsis","page":"metalctl whoami","title":"Synopsis","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_whoami/","page":"metalctl whoami","title":"metalctl whoami","text":"shows the current user, that will be used to authenticate commands.","category":"page"},{"location":"external/metalctl/docs/metalctl_whoami/","page":"metalctl whoami","title":"metalctl whoami","text":"metalctl whoami [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_whoami/#Options","page":"metalctl whoami","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_whoami/","page":"metalctl whoami","title":"metalctl whoami","text":" -h, --help help for whoami","category":"page"},{"location":"external/metalctl/docs/metalctl_whoami/#Options-inherited-from-parent-commands","page":"metalctl whoami","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_whoami/","page":"metalctl whoami","title":"metalctl whoami","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_whoami/#SEE-ALSO","page":"metalctl whoami","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_whoami/","page":"metalctl whoami","title":"metalctl whoami","text":"metalctl\t - a cli to manage entities in the metal-stack api","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_power/#metalctl-machine-power","page":"metalctl machine power","title":"metalctl machine power","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_power/","page":"metalctl machine power","title":"metalctl machine power","text":"manage machine power","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_power/#Options","page":"metalctl machine power","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_power/","page":"metalctl machine power","title":"metalctl machine power","text":" -h, --help help for power","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_power/#Options-inherited-from-parent-commands","page":"metalctl machine power","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_power/","page":"metalctl machine power","title":"metalctl machine power","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_power/#SEE-ALSO","page":"metalctl machine power","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_power/","page":"metalctl machine power","title":"metalctl machine power","text":"metalctl machine\t - manage machine entities\nmetalctl machine power bios\t - boot a machine into BIOS\nmetalctl machine power cycle\t - power cycle a machine (graceful shutdown)\nmetalctl machine power disk\t - boot a machine from disk\nmetalctl machine power off\t - power off a machine\nmetalctl machine power on\t - power on a machine\nmetalctl machine power pxe\t - boot a machine from PXE\nmetalctl machine power reset\t - power reset a machine","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_ipmi_events/#metalctl-machine-ipmi-events","page":"metalctl machine ipmi events","title":"metalctl machine ipmi events","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_ipmi_events/","page":"metalctl machine ipmi events","title":"metalctl machine ipmi events","text":"display machine hardware events","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_ipmi_events/","page":"metalctl machine ipmi events","title":"metalctl machine ipmi events","text":"metalctl machine ipmi events [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_ipmi_events/#Options","page":"metalctl machine ipmi events","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_ipmi_events/","page":"metalctl machine ipmi events","title":"metalctl machine ipmi events","text":" -h, --help help for events\n --ipmipassword string overwrite ipmi password (admin only).\n --ipmiuser string overwrite ipmi user (admin only).\n -n, --last string show last log entries. (default \"10\")","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_ipmi_events/#Options-inherited-from-parent-commands","page":"metalctl machine ipmi events","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_ipmi_events/","page":"metalctl machine ipmi events","title":"metalctl machine ipmi events","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_ipmi_events/#SEE-ALSO","page":"metalctl machine ipmi events","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_ipmi_events/","page":"metalctl machine ipmi events","title":"metalctl machine ipmi events","text":"metalctl machine ipmi\t - display ipmi details of the machine, if no machine ID is given all ipmi addresses are returned.","category":"page"},{"location":"external/metalctl/docs/metalctl_filesystemlayout_try/#metalctl-filesystemlayout-try","page":"metalctl filesystemlayout try","title":"metalctl filesystemlayout try","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_filesystemlayout_try/","page":"metalctl filesystemlayout try","title":"metalctl filesystemlayout try","text":"try to detect a filesystem by given size and image","category":"page"},{"location":"external/metalctl/docs/metalctl_filesystemlayout_try/","page":"metalctl filesystemlayout try","title":"metalctl filesystemlayout try","text":"metalctl filesystemlayout try [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_filesystemlayout_try/#Options","page":"metalctl filesystemlayout try","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_filesystemlayout_try/","page":"metalctl filesystemlayout try","title":"metalctl filesystemlayout try","text":" -h, --help help for try\n --image string image to try\n --size string size to try","category":"page"},{"location":"external/metalctl/docs/metalctl_filesystemlayout_try/#Options-inherited-from-parent-commands","page":"metalctl filesystemlayout try","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_filesystemlayout_try/","page":"metalctl filesystemlayout try","title":"metalctl filesystemlayout try","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_filesystemlayout_try/#SEE-ALSO","page":"metalctl filesystemlayout try","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_filesystemlayout_try/","page":"metalctl filesystemlayout try","title":"metalctl filesystemlayout try","text":"metalctl filesystemlayout\t - manage filesystemlayout entities","category":"page"},{"location":"overview/kubernetes/#Kubernetes-Integration","page":"Kubernetes Integration","title":"Kubernetes Integration","text":"","category":"section"},{"location":"overview/kubernetes/","page":"Kubernetes Integration","title":"Kubernetes Integration","text":"With the help of the Gardener project, metal-stack can be used for spinning up Kubernetes clusters quickly and reliably on bare metal machines.","category":"page"},{"location":"overview/kubernetes/","page":"Kubernetes Integration","title":"Kubernetes Integration","text":"To make this happen, we implemented a couple of components, which are described here.","category":"page"},{"location":"overview/kubernetes/","page":"Kubernetes Integration","title":"Kubernetes Integration","text":"Pages = [\"kubernetes.md\"]\nDepth = 5","category":"page"},{"location":"overview/kubernetes/#metal-ccm","page":"Kubernetes Integration","title":"metal-ccm","text":"","category":"section"},{"location":"overview/kubernetes/","page":"Kubernetes Integration","title":"Kubernetes Integration","text":"CCM stands for cloud-controller-manager and is the bridge between Kubernetes and a cloud-provider.","category":"page"},{"location":"overview/kubernetes/","page":"Kubernetes Integration","title":"Kubernetes Integration","text":"We implemented the cloud provider interface in the metal-ccm repository. With the help of the cloud-controller-controller we provide metal-stack-specific properties for Kubernetes clusters, e.g. load balancer configuration through MetalLB or node properties.","category":"page"},{"location":"overview/kubernetes/#firewall-controller","page":"Kubernetes Integration","title":"firewall-controller","text":"","category":"section"},{"location":"overview/kubernetes/","page":"Kubernetes Integration","title":"Kubernetes Integration","text":"To make the firewalls created with metal-stack easily configurable through Kubernetes resources, we add our firewall-controller to the firewall image. The controller watches special CRDs, enabling users to manage:","category":"page"},{"location":"overview/kubernetes/","page":"Kubernetes Integration","title":"Kubernetes Integration","text":"nftables rules\nIntrusion-detection with suricata\nnetwork metric collection","category":"page"},{"location":"overview/kubernetes/","page":"Kubernetes Integration","title":"Kubernetes Integration","text":"Please check out the guide on how to use it.","category":"page"},{"location":"overview/kubernetes/#Gardener-components","page":"Kubernetes Integration","title":"Gardener components","text":"","category":"section"},{"location":"overview/kubernetes/","page":"Kubernetes Integration","title":"Kubernetes Integration","text":"There are some Gardener resources that need be reconciled when you act as a cloud provider for the Gardener. This section briefly describes the controllers implemented for deploying Kubernetes clusters through Gardener.","category":"page"},{"location":"overview/kubernetes/","page":"Kubernetes Integration","title":"Kubernetes Integration","text":"If you want to learn how to deploy metal-stack with Gardener, please check out the installation section.","category":"page"},{"location":"overview/kubernetes/#gardener-extension-provider-metal","page":"Kubernetes Integration","title":"gardener-extension-provider-metal","text":"","category":"section"},{"location":"overview/kubernetes/","page":"Kubernetes Integration","title":"Kubernetes Integration","text":"The gardener-extension-provider-metal contains of a set of webhooks and controllers for reconciling or mutating Gardener-specific resources.","category":"page"},{"location":"overview/kubernetes/","page":"Kubernetes Integration","title":"Kubernetes Integration","text":"The project also contains a validator for metal-type Gardener resources, which you should also deploy in case you want to use metal-stack in combination with Gardener.","category":"page"},{"location":"overview/kubernetes/#os-metal-extension","page":"Kubernetes Integration","title":"os-metal-extension","text":"","category":"section"},{"location":"overview/kubernetes/","page":"Kubernetes Integration","title":"Kubernetes Integration","text":"Due to the reason we use ignition in our operating system images for userdata, we had to provide an own extension controller for metal-stack, which you can find at Github in the os-metal-extension repository.","category":"page"},{"location":"overview/kubernetes/#machine-controller-manager-provider-metal","page":"Kubernetes Integration","title":"machine-controller-manager-provider-metal","text":"","category":"section"},{"location":"overview/kubernetes/","page":"Kubernetes Integration","title":"Kubernetes Integration","text":"Worker nodes are managed through Gardener's machine-controller-manager (MCM). The MCM allows out-of-tree provider implementation via sidecar, which is what we implemented in the machine-controller-manager-provider-metal repository.","category":"page"},{"location":"external/metalctl/docs/metalctl_network_apply/#metalctl-network-apply","page":"metalctl network apply","title":"metalctl network apply","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_network_apply/","page":"metalctl network apply","title":"metalctl network apply","text":"applies one or more networks from a given file","category":"page"},{"location":"external/metalctl/docs/metalctl_network_apply/","page":"metalctl network apply","title":"metalctl network apply","text":"metalctl network apply [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_network_apply/#Options","page":"metalctl network apply","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_network_apply/","page":"metalctl network apply","title":"metalctl network apply","text":" --bulk-output when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.\n -f, --file string filename of the create or update request in yaml format, or - for stdin.\n \n Example:\n $ metalctl network describe network-1 -o yaml > network.yaml\n $ vi network.yaml\n $ # either via stdin\n $ cat network.yaml | metalctl network apply -f -\n $ # or via file\n $ metalctl network apply -f network.yaml\n \n the file can also contain multiple documents and perform a bulk operation.\n \t\n -h, --help help for apply\n --skip-security-prompts skips security prompt for bulk operations\n --timestamps when used with --file (bulk operation): prints timestamps in-between the operations","category":"page"},{"location":"external/metalctl/docs/metalctl_network_apply/#Options-inherited-from-parent-commands","page":"metalctl network apply","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_network_apply/","page":"metalctl network apply","title":"metalctl network apply","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_network_apply/#SEE-ALSO","page":"metalctl network apply","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_network_apply/","page":"metalctl network apply","title":"metalctl network apply","text":"metalctl network\t - manage network entities","category":"page"},{"location":"external/metalctl/docs/metalctl_switch_update/#metalctl-switch-update","page":"metalctl switch update","title":"metalctl switch update","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_switch_update/","page":"metalctl switch update","title":"metalctl switch update","text":"updates the switch","category":"page"},{"location":"external/metalctl/docs/metalctl_switch_update/","page":"metalctl switch update","title":"metalctl switch update","text":"metalctl switch update [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_switch_update/#Options","page":"metalctl switch update","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_switch_update/","page":"metalctl switch update","title":"metalctl switch update","text":" --bulk-output when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.\n -f, --file string filename of the create or update request in yaml format, or - for stdin.\n \n Example:\n $ metalctl switch describe switch-1 -o yaml > switch.yaml\n $ vi switch.yaml\n $ # either via stdin\n $ cat switch.yaml | metalctl switch update -f -\n $ # or via file\n $ metalctl switch update -f switch.yaml\n \n the file can also contain multiple documents and perform a bulk operation.\n \t\n -h, --help help for update\n --skip-security-prompts skips security prompt for bulk operations\n --timestamps when used with --file (bulk operation): prints timestamps in-between the operations","category":"page"},{"location":"external/metalctl/docs/metalctl_switch_update/#Options-inherited-from-parent-commands","page":"metalctl switch update","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_switch_update/","page":"metalctl switch update","title":"metalctl switch update","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_switch_update/#SEE-ALSO","page":"metalctl switch update","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_switch_update/","page":"metalctl switch update","title":"metalctl switch update","text":"metalctl switch\t - manage switch entities","category":"page"},{"location":"external/metalctl/docs/metalctl_context/#metalctl-context","page":"metalctl context","title":"metalctl context","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_context/","page":"metalctl context","title":"metalctl context","text":"manage metalctl context","category":"page"},{"location":"external/metalctl/docs/metalctl_context/#Synopsis","page":"metalctl context","title":"Synopsis","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_context/","page":"metalctl context","title":"metalctl context","text":"context defines the backend to which metalctl talks to. You can switch back and forth with \"-\"","category":"page"},{"location":"external/metalctl/docs/metalctl_context/","page":"metalctl context","title":"metalctl context","text":"metalctl context [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_context/#Examples","page":"metalctl context","title":"Examples","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_context/","page":"metalctl context","title":"metalctl context","text":"\n~/.metalctl/config.yaml\n---\ncurrent: prod\ncontexts:\n prod:\n url: https://api.metal-stack.io/metal\n issuer_url: https://dex.metal-stack.io/dex\n client_id: metal_client\n client_secret: 456\n dev:\n url: https://api.metal-stack.dev/metal\n issuer_url: https://dex.metal-stack.dev/dex\n client_id: metal_client\n client_secret: 123\n...\n","category":"page"},{"location":"external/metalctl/docs/metalctl_context/#Options","page":"metalctl context","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_context/","page":"metalctl context","title":"metalctl context","text":" -h, --help help for context","category":"page"},{"location":"external/metalctl/docs/metalctl_context/#Options-inherited-from-parent-commands","page":"metalctl context","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_context/","page":"metalctl context","title":"metalctl context","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_context/#SEE-ALSO","page":"metalctl context","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_context/","page":"metalctl context","title":"metalctl context","text":"metalctl\t - a cli to manage entities in the metal-stack api\nmetalctl context short\t - only show the default context name","category":"page"},{"location":"overview/storage/#Storage","page":"Storage","title":"Storage","text":"","category":"section"},{"location":"overview/storage/","page":"Storage","title":"Storage","text":"When working with bare-metal servers, providing cloud storage is a challenge. With physical machines there is no opportunity that a hypervisor can mount storage devices into the servers and thus, we have to implement other mechanisms that are capable of dynamically mounting storage onto the machines.","category":"page"},{"location":"overview/storage/","page":"Storage","title":"Storage","text":"In the meantime, we have started to integrate third-party solutions into our metal-stack landscape. They help us to provide modern, well-integrated and scalable storage solutions to our end-users.","category":"page"},{"location":"overview/storage/","page":"Storage","title":"Storage","text":"Pages = [\"persistent_storage.md\"]\nDepth = 5","category":"page"},{"location":"overview/storage/#Lightbits-Labs-NVMe-over-TCP-Storage-Integration","page":"Storage","title":"Lightbits Labs NVMe over TCP Storage Integration","text":"","category":"section"},{"location":"overview/storage/","page":"Storage","title":"Storage","text":"Lightbits Labs offers a proprietary implementation of persistent storage using NVMe over TCP. The solution has some very superior traits that fit very well to metal-stack. The strongest advantages are:","category":"page"},{"location":"overview/storage/","page":"Storage","title":"Storage","text":"High performance\nBuilt-in multi-tenant capabilities\nConfigurable compression and replication factors","category":"page"},{"location":"overview/storage/","page":"Storage","title":"Storage","text":"We are maintaining an open source integration for running LightOS in our Gardener cluster provisioning. You can enable it through the controller registration of the gardener-extension-provider-metal.","category":"page"},{"location":"overview/storage/","page":"Storage","title":"Storage","text":"With the integration in place, the extension-provider deploys a duros-controller along with a Duros Storage CRD into the seed's shoot namespace. The duros-controller takes care of creating projects and managing credentials at the Lightbits Duros API. It also provides storage classes as configured in the extension-provider's controller registration to the customer's shoot cluster such that users can start consuming the Lightbits storage immediately.","category":"page"},{"location":"overview/storage/#Simple-Node-Local-Storage-with-csi-driver-lvm","page":"Storage","title":"Simple Node Local Storage with csi-driver-lvm","text":"","category":"section"},{"location":"overview/storage/","page":"Storage","title":"Storage","text":"If you wish to quickly start off with cluster provisioning without caring so much about complex cloud storage solutions, we recommend using a small storage driver we wrote called csi-driver-lvm. It provides a storage class that manages node-local storage through LVM.","category":"page"},{"location":"overview/storage/","page":"Storage","title":"Storage","text":"A definition of a PVC can look like this:","category":"page"},{"location":"overview/storage/","page":"Storage","title":"Storage","text":"apiVersion: v1\nkind: PersistentVolumeClaim\nmetadata:\n name: csi-pvc\nspec:\n accessModes:\n - ReadWriteOnce\n resources:\n requests:\n storage: 100Mi\n storageClassName: csi-lvm-sc-linear","category":"page"},{"location":"overview/storage/","page":"Storage","title":"Storage","text":"The solution does not provide cloud-storage or whatsoever, but it improves the user's accessibility of local storage on bare-metal machines through Kubernetes. Check out the driver's documentation here.","category":"page"},{"location":"external/metalctl/docs/metalctl_partition_edit/#metalctl-partition-edit","page":"metalctl partition edit","title":"metalctl partition edit","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_partition_edit/","page":"metalctl partition edit","title":"metalctl partition edit","text":"edit the partition through an editor and update","category":"page"},{"location":"external/metalctl/docs/metalctl_partition_edit/","page":"metalctl partition edit","title":"metalctl partition edit","text":"metalctl partition edit [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_partition_edit/#Options","page":"metalctl partition edit","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_partition_edit/","page":"metalctl partition edit","title":"metalctl partition edit","text":" -h, --help help for edit","category":"page"},{"location":"external/metalctl/docs/metalctl_partition_edit/#Options-inherited-from-parent-commands","page":"metalctl partition edit","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_partition_edit/","page":"metalctl partition edit","title":"metalctl partition edit","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_partition_edit/#SEE-ALSO","page":"metalctl partition edit","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_partition_edit/","page":"metalctl partition edit","title":"metalctl partition edit","text":"metalctl partition\t - manage partition entities","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_identify/#metalctl-machine-identify","page":"metalctl machine identify","title":"metalctl machine identify","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_identify/","page":"metalctl machine identify","title":"metalctl machine identify","text":"manage machine chassis identify LED power","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_identify/#Options","page":"metalctl machine identify","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_identify/","page":"metalctl machine identify","title":"metalctl machine identify","text":" -h, --help help for identify","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_identify/#Options-inherited-from-parent-commands","page":"metalctl machine identify","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_identify/","page":"metalctl machine identify","title":"metalctl machine identify","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_identify/#SEE-ALSO","page":"metalctl machine identify","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_identify/","page":"metalctl machine identify","title":"metalctl machine identify","text":"metalctl machine\t - manage machine entities\nmetalctl machine identify off\t - power off the machine chassis identify LED\nmetalctl machine identify on\t - power on the machine chassis identify LED","category":"page"},{"location":"external/metalctl/docs/metalctl_partition_create/#metalctl-partition-create","page":"metalctl partition create","title":"metalctl partition create","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_partition_create/","page":"metalctl partition create","title":"metalctl partition create","text":"creates the partition","category":"page"},{"location":"external/metalctl/docs/metalctl_partition_create/","page":"metalctl partition create","title":"metalctl partition create","text":"metalctl partition create [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_partition_create/#Options","page":"metalctl partition create","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_partition_create/","page":"metalctl partition create","title":"metalctl partition create","text":" --bulk-output when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.\n --cmdline string kernel commandline for the metal-hammer in the partition. [required]\n -d, --description string Description of the partition. [required]\n -f, --file string filename of the create or update request in yaml format, or - for stdin.\n \n Example:\n $ metalctl partition describe partition-1 -o yaml > partition.yaml\n $ vi partition.yaml\n $ # either via stdin\n $ cat partition.yaml | metalctl partition create -f -\n $ # or via file\n $ metalctl partition create -f partition.yaml\n \n the file can also contain multiple documents and perform a bulk operation.\n \t\n -h, --help help for create\n --id string ID of the partition. [required]\n --imageurl string initrd for the metal-hammer in the partition. [required]\n --kernelurl string kernel url for the metal-hammer in the partition. [required]\n --mgmtserver string management server address in the partition. [required]\n -n, --name string Name of the partition. [optional]\n --skip-security-prompts skips security prompt for bulk operations\n --timestamps when used with --file (bulk operation): prints timestamps in-between the operations","category":"page"},{"location":"external/metalctl/docs/metalctl_partition_create/#Options-inherited-from-parent-commands","page":"metalctl partition create","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_partition_create/","page":"metalctl partition create","title":"metalctl partition create","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_partition_create/#SEE-ALSO","page":"metalctl partition create","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_partition_create/","page":"metalctl partition create","title":"metalctl partition create","text":"metalctl partition\t - manage partition entities","category":"page"},{"location":"external/metalctl/docs/metalctl_filesystemlayout/#metalctl-filesystemlayout","page":"metalctl filesystemlayout","title":"metalctl filesystemlayout","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_filesystemlayout/","page":"metalctl filesystemlayout","title":"metalctl filesystemlayout","text":"manage filesystemlayout entities","category":"page"},{"location":"external/metalctl/docs/metalctl_filesystemlayout/#Synopsis","page":"metalctl filesystemlayout","title":"Synopsis","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_filesystemlayout/","page":"metalctl filesystemlayout","title":"metalctl filesystemlayout","text":"a filesystemlayout is a specification how the disks in a machine are partitioned, formatted and mounted.","category":"page"},{"location":"external/metalctl/docs/metalctl_filesystemlayout/#Options","page":"metalctl filesystemlayout","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_filesystemlayout/","page":"metalctl filesystemlayout","title":"metalctl filesystemlayout","text":" -h, --help help for filesystemlayout","category":"page"},{"location":"external/metalctl/docs/metalctl_filesystemlayout/#Options-inherited-from-parent-commands","page":"metalctl filesystemlayout","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_filesystemlayout/","page":"metalctl filesystemlayout","title":"metalctl filesystemlayout","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_filesystemlayout/#SEE-ALSO","page":"metalctl filesystemlayout","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_filesystemlayout/","page":"metalctl filesystemlayout","title":"metalctl filesystemlayout","text":"metalctl\t - a cli to manage entities in the metal-stack api\nmetalctl filesystemlayout apply\t - applies one or more filesystemlayouts from a given file\nmetalctl filesystemlayout create\t - creates the filesystemlayout\nmetalctl filesystemlayout delete\t - deletes the filesystemlayout\nmetalctl filesystemlayout describe\t - describes the filesystemlayout\nmetalctl filesystemlayout edit\t - edit the filesystemlayout through an editor and update\nmetalctl filesystemlayout list\t - list all filesystemlayouts\nmetalctl filesystemlayout match\t - check if a machine satisfies all disk requirements of a given filesystemlayout\nmetalctl filesystemlayout try\t - try to detect a filesystem by given size and image\nmetalctl filesystemlayout update\t - updates the filesystemlayout","category":"page"},{"location":"external/metalctl/docs/metalctl_size_imageconstraint_apply/#metalctl-size-imageconstraint-apply","page":"metalctl size imageconstraint apply","title":"metalctl size imageconstraint apply","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_imageconstraint_apply/","page":"metalctl size imageconstraint apply","title":"metalctl size imageconstraint apply","text":"applies one or more imageconstraints from a given file","category":"page"},{"location":"external/metalctl/docs/metalctl_size_imageconstraint_apply/","page":"metalctl size imageconstraint apply","title":"metalctl size imageconstraint apply","text":"metalctl size imageconstraint apply [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_size_imageconstraint_apply/#Options","page":"metalctl size imageconstraint apply","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_imageconstraint_apply/","page":"metalctl size imageconstraint apply","title":"metalctl size imageconstraint apply","text":" --bulk-output when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.\n -f, --file string filename of the create or update request in yaml format, or - for stdin.\n \n Example:\n $ metalctl imageconstraint describe imageconstraint-1 -o yaml > imageconstraint.yaml\n $ vi imageconstraint.yaml\n $ # either via stdin\n $ cat imageconstraint.yaml | metalctl imageconstraint apply -f -\n $ # or via file\n $ metalctl imageconstraint apply -f imageconstraint.yaml\n \n the file can also contain multiple documents and perform a bulk operation.\n \t\n -h, --help help for apply\n --skip-security-prompts skips security prompt for bulk operations\n --timestamps when used with --file (bulk operation): prints timestamps in-between the operations","category":"page"},{"location":"external/metalctl/docs/metalctl_size_imageconstraint_apply/#Options-inherited-from-parent-commands","page":"metalctl size imageconstraint apply","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_imageconstraint_apply/","page":"metalctl size imageconstraint apply","title":"metalctl size imageconstraint apply","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_size_imageconstraint_apply/#SEE-ALSO","page":"metalctl size imageconstraint apply","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_imageconstraint_apply/","page":"metalctl size imageconstraint apply","title":"metalctl size imageconstraint apply","text":"metalctl size imageconstraint\t - manage imageconstraint entities","category":"page"},{"location":"external/metalctl/docs/metalctl/#metalctl","page":"metalctl","title":"metalctl","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl/","page":"metalctl","title":"metalctl","text":"a cli to manage entities in the metal-stack api","category":"page"},{"location":"external/metalctl/docs/metalctl/#Options","page":"metalctl","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl/","page":"metalctl","title":"metalctl","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n -h, --help help for metalctl\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl/#SEE-ALSO","page":"metalctl","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl/","page":"metalctl","title":"metalctl","text":"metalctl audit\t - manage audit trace entities\nmetalctl completion\t - Generate the autocompletion script for the specified shell\nmetalctl context\t - manage metalctl context\nmetalctl filesystemlayout\t - manage filesystemlayout entities\nmetalctl firewall\t - manage firewall entities\nmetalctl firmware\t - manage firmwares\nmetalctl health\t - shows the server health\nmetalctl image\t - manage image entities\nmetalctl login\t - login user and receive token\nmetalctl logout\t - logout user from OIDC SSO session\nmetalctl machine\t - manage machine entities\nmetalctl markdown\t - create markdown documentation\nmetalctl network\t - manage network entities\nmetalctl partition\t - manage partition entities\nmetalctl project\t - manage project entities\nmetalctl size\t - manage size entities\nmetalctl switch\t - manage switch entities\nmetalctl tenant\t - manage tenant entities\nmetalctl update\t - update the program\nmetalctl version\t - print the client and server version information\nmetalctl vpn\t - access VPN\nmetalctl whoami\t - shows current user","category":"page"},{"location":"external/metalctl/docs/metalctl_size_reservation_delete/#metalctl-size-reservation-delete","page":"metalctl size reservation delete","title":"metalctl size reservation delete","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_reservation_delete/","page":"metalctl size reservation delete","title":"metalctl size reservation delete","text":"deletes the reservation","category":"page"},{"location":"external/metalctl/docs/metalctl_size_reservation_delete/","page":"metalctl size reservation delete","title":"metalctl size reservation delete","text":"metalctl size reservation delete [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_size_reservation_delete/#Options","page":"metalctl size reservation delete","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_reservation_delete/","page":"metalctl size reservation delete","title":"metalctl size reservation delete","text":" --bulk-output when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.\n -f, --file string filename of the create or update request in yaml format, or - for stdin.\n \n Example:\n $ metalctl reservation describe reservation-1 -o yaml > reservation.yaml\n $ vi reservation.yaml\n $ # either via stdin\n $ cat reservation.yaml | metalctl reservation delete -f -\n $ # or via file\n $ metalctl reservation delete -f reservation.yaml\n \n the file can also contain multiple documents and perform a bulk operation.\n \t\n -h, --help help for delete\n --skip-security-prompts skips security prompt for bulk operations\n --timestamps when used with --file (bulk operation): prints timestamps in-between the operations","category":"page"},{"location":"external/metalctl/docs/metalctl_size_reservation_delete/#Options-inherited-from-parent-commands","page":"metalctl size reservation delete","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_reservation_delete/","page":"metalctl size reservation delete","title":"metalctl size reservation delete","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_size_reservation_delete/#SEE-ALSO","page":"metalctl size reservation delete","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_reservation_delete/","page":"metalctl size reservation delete","title":"metalctl size reservation delete","text":"metalctl size reservation\t - manage reservation entities","category":"page"},{"location":"overview/architecture/#Architecture","page":"Architecture","title":"Architecture","text":"","category":"section"},{"location":"overview/architecture/","page":"Architecture","title":"Architecture","text":"The metal-stack is a compound of microservices predominantly written in Golang.","category":"page"},{"location":"overview/architecture/","page":"Architecture","title":"Architecture","text":"This page gives you an overview over which microservices exist, how they communicate with each other and where they are deployed.","category":"page"},{"location":"overview/architecture/","page":"Architecture","title":"Architecture","text":"Pages = [\"architecture.md\"]\nDepth = 5","category":"page"},{"location":"overview/architecture/#Target-Deployment-Platforms","page":"Architecture","title":"Target Deployment Platforms","text":"","category":"section"},{"location":"overview/architecture/","page":"Architecture","title":"Architecture","text":"For our environments, we chose to deploy the metal-stack into a Kubernetes cluster. This means that also our entire installation was developed for metal-stack being run on Kubernetes. Running applications on Kubernetes gives you a lot of benefits regarding ease-of-deployment, scalability, reliability and so on.","category":"page"},{"location":"overview/architecture/","page":"Architecture","title":"Architecture","text":"However, very early we decided that we do not want to depend on technical Kubernetes functionality with our software (i.e. we did not implement the stack \"kube-native\" by using controllers and Kubernetes CRDs and things like that). With the following paragraph we want to point out the reasoning behind this \"philosophical\" decision that may sound conservative at first glance. But not relying on Kubernetes technology:","category":"page"},{"location":"overview/architecture/","page":"Architecture","title":"Architecture","text":"Makes deployments of the stack without Kubernetes theoretically possible.\nWe believe that cloud providers should be able to act beneath Kubernetes\nThis way it is possible to use metal-stack for providing your own Kubernetes offering without relying on Kubernetes yourself (breaks the chicken-egg problem)\nFollows an important claim in microservice development: \"Be agnostic to your choice of technology\"\nFor applications that are purely made for being run on Kubernetes, it does not matter to rely on this technology (we even do the same a lot with our applications that integrate the metal-stack with Gardener) but as soon as you start using things like the underlying reconciliation abilities (which admittedly are fanstatic) you are locking your code into a certain technology\nWe don't know what comes after Kubernetes but we believe that a cloud offering should have the potential to survive a choice of technology\nBy this decision we ensured that we can migrate the stack to another future technology and survive the change","category":"page"},{"location":"overview/architecture/","page":"Architecture","title":"Architecture","text":"One more word towards determining the location for your metal control plane: It is not strictly required to run the control plane inside the same data center as your servers. It even makes sense not to do so because this way you can place your control plane and your servers into a different failure domains, which makes your installation more robust to data center meltdown. Externally hosting the control plane brings you up and running quickly plus having the advantage of higher security through geo-distribution.","category":"page"},{"location":"overview/architecture/#Metal-Control-Plane","page":"Architecture","title":"Metal Control Plane","text":"","category":"section"},{"location":"overview/architecture/","page":"Architecture","title":"Architecture","text":"The foundation of the metal-stack is what we call the metal control plane.","category":"page"},{"location":"overview/architecture/","page":"Architecture","title":"Architecture","text":"The control plane contains a couple of essential microservices for the metal-stack including:","category":"page"},{"location":"overview/architecture/","page":"Architecture","title":"Architecture","text":"metal-api The API to manage control plane resources like machines, switches, operating system images, machine sizes, networks, IP addresses and more. The exposed API is an old-fashioned REST API with different authentication methods. The metal-api stores the state of these entities in a RethinkDB database. The metal-api also has its own IP address management (go-ipam), which writes IP address and network allocations into a PostgreSQL backend.\nmasterdata-api Manages tenant and project entities, which can be described as entities used for company-specific resource separation and grouping. Having these \"higher level entities\" managed by a separate microservice was a design choice that allows to re-use the information by other microservices without having them to know the metal-api at all. The masterdata gets persisted in a dedicated PostgreSQL database.\nmetal-console Provides access for users to a machine's serial console via SSH. It can be seen as an optional component.\nnsq A message queuing system (not developed by the metal-stack) used for decoupling microservices and distributing tasks.","category":"page"},{"location":"overview/architecture/","page":"Architecture","title":"Architecture","text":"The following figure shows the relationships between these microservices:","category":"page"},{"location":"overview/architecture/","page":"Architecture","title":"Architecture","text":"(Image: Metal Control Plane)","category":"page"},{"location":"overview/architecture/","page":"Architecture","title":"Architecture","text":"Figure 1: The metal control plane deployed in a Kubernetes environment with an ingress-controller exposing additional services via service exposal.","category":"page"},{"location":"overview/architecture/","page":"Architecture","title":"Architecture","text":"Some notes on this picture:","category":"page"},{"location":"overview/architecture/","page":"Architecture","title":"Architecture","text":"Users can access the metal-api with the CLI client called metalctl.\nYou can programmatically access the metal-api with client libraries (e.g. metal-go).\nOur databases are wrapped in a specially built backup-restore-sidecar, which is consistently backing up the databases in external blob storage.\nThe metal-api can be scaled out using replicas when being deployed in Kubernetes.","category":"page"},{"location":"overview/architecture/#Partitions","page":"Architecture","title":"Partitions","text":"","category":"section"},{"location":"overview/architecture/","page":"Architecture","title":"Architecture","text":"A partition is our term for describing hardware in the data center controlled by the metal-stack with all the hardware participating in the same network topology. Being in the same network topology causes the hardware inside a partition to build a failure domain. Even though the network topology for running the metal-stack is required to be redundant by design, you should consider setting up multiple partitions. With multiple partitions it is possible for users to maintain availability of their applications by spreading them across the partitions. Installing partitions in multiple data centers would be even better in regards of fail-safe application performance, which would even tolerate the meltdown of a data center.","category":"page"},{"location":"overview/architecture/","page":"Architecture","title":"Architecture","text":"tip: Tip\nIn our setups, we encode the name of a region and a zone name into our partition names. However, we do not have dedicated entities for regions and zones in our APIs.A region is a geographic area in which data centers are located.Zones are geographic locations in a region usually in different fire compartments. Regions can consist of several zones.A zone can consist of several partitions. Usually, a partition spans a rack or a group of racks.","category":"page"},{"location":"overview/architecture/","page":"Architecture","title":"Architecture","text":"We strongly advise to group your hardware into racks that are specifically assembled for running metal-stack. When using modular rack design, the amount of compute resources of a partition can easily be extended by adding more racks to your partition.","category":"page"},{"location":"overview/architecture/","page":"Architecture","title":"Architecture","text":"info: Info\nThe hardware that we currently support to be placed inside a partition is described in the hardware document.","category":"page"},{"location":"overview/architecture/","page":"Architecture","title":"Architecture","text":"info: Info\nHow large you can grow your partitions and how the network topology inside a partition looks like is described in the networking document.","category":"page"},{"location":"overview/architecture/","page":"Architecture","title":"Architecture","text":"The metal-stack has microservices running on the leaf switches in a partition. For this reason, your leaf switches are required to run a Linux distribution that you have full access to. Additionally, there are a servers not added to the pool of user-allocatable machines, which are instead required for running metal-stack and we call them management servers. We also call the entirety of switches inside a partition the switch plane.","category":"page"},{"location":"overview/architecture/","page":"Architecture","title":"Architecture","text":"The microservices running inside a partition are:","category":"page"},{"location":"overview/architecture/","page":"Architecture","title":"Architecture","text":"metal-hammer (runs on a server when not allocated by user, often referred to as discovery image) An initrd, which is booted up in PXE mode, preparing and registering a machine. When a user allocates a machine, the metal-hammer will install the target operating system on this machine and kexec into the new operating system kernel.\nmetal-core (runs on leaf switches) Dynamically configures the leaf switch from information provided by the metal-api. It also proxies requests from the metal-hammer to the metal-api including publishment of machine lifecycle events and machine registration requests.\npixiecore (preferably runs on management servers, forked by metal-stack) Provides the capability of PXE booting servers in the PXE boot network.\nmetal-bmc (runs on management servers) Reports the ip addresses that are leased to ipmi devices together with their machine uuids to the metal-api. This provides machine discovery in the partition machines and keeps all IPMI interface access data up-to-date. Also forwards metal-console requests to the actual machine, allowing user access to the machine's serial console. Furthermore it processes firmware updates and power on/off, led on/off, boot order changes.","category":"page"},{"location":"overview/architecture/","page":"Architecture","title":"Architecture","text":"(Image: Partition)","category":"page"},{"location":"overview/architecture/","page":"Architecture","title":"Architecture","text":"Figure 2: Simplified illustration of services running inside a partition.","category":"page"},{"location":"overview/architecture/","page":"Architecture","title":"Architecture","text":"Some notes on this picture:","category":"page"},{"location":"overview/architecture/","page":"Architecture","title":"Architecture","text":"This figure is slightly simplified. The switch plane consists of spine switches, exit routers, management firewalls and a bastion router with more software components deployed on these entities. Please refer to the networking document to see the full overview over the switch plane.\nThe image-cache is an optional component consisting of multiple services to allow caching images from the public image store inside a partition. This brings increased download performance on machine allocation and increases independence of a partition on the internet connection.","category":"page"},{"location":"overview/architecture/#Complete-View","page":"Architecture","title":"Complete View","text":"","category":"section"},{"location":"overview/architecture/","page":"Architecture","title":"Architecture","text":"The following figure shows several partitions connected to a single metal control plane. Of course, it is also possible to have multiple metal control planes, which can be useful for staging.","category":"page"},{"location":"overview/architecture/","page":"Architecture","title":"Architecture","text":"(Image: metal-stack)","category":"page"},{"location":"overview/architecture/","page":"Architecture","title":"Architecture","text":"Figure 3: Reduced view on the communication between the metal control plane and multiple partitions.","category":"page"},{"location":"overview/architecture/","page":"Architecture","title":"Architecture","text":"Some notes on this picture:","category":"page"},{"location":"overview/architecture/","page":"Architecture","title":"Architecture","text":"By design, a partition only has very few ports open for incoming-connections from the internet. This contributes to a smaller attack surface and higher security of your infrastructure.\nWith the help of NSQ, it is not required to have connections from the metal control plane to the metal-core. The metal-core instances register at the message bus and can then consume partition-specific topics, e.g. when a machine deletion gets issued by a user.","category":"page"},{"location":"overview/architecture/#Machine-Provisioning-Sequence","page":"Architecture","title":"Machine Provisioning Sequence","text":"","category":"section"},{"location":"overview/architecture/","page":"Architecture","title":"Architecture","text":"The following sequence diagram illustrates some of the main principles of the machine provisioning lifecycle.","category":"page"},{"location":"overview/architecture/","page":"Architecture","title":"Architecture","text":"(Image: provisioning sequence)","category":"page"},{"location":"overview/architecture/","page":"Architecture","title":"Architecture","text":"Figure 4: Sequence diagram of the machine provisioning sequence.","category":"page"},{"location":"overview/architecture/","page":"Architecture","title":"Architecture","text":"Here is a video showing a screen capture of a machine's serial console while running the metal-hammer in \"wait mode\". Then, a user allocates the machine and the metal-hammer installs the target operating system and the machine boots into the new operating system kernel via the kexec system call.","category":"page"},{"location":"overview/architecture/","page":"Architecture","title":"Architecture","text":"
    \n\n
    ","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_update-firmware_bios/#metalctl-machine-update-firmware-bios","page":"metalctl machine update-firmware bios","title":"metalctl machine update-firmware bios","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_update-firmware_bios/","page":"metalctl machine update-firmware bios","title":"metalctl machine update-firmware bios","text":"update a machine BIOS","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_update-firmware_bios/#Synopsis","page":"metalctl machine update-firmware bios","title":"Synopsis","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_update-firmware_bios/","page":"metalctl machine update-firmware bios","title":"metalctl machine update-firmware bios","text":"the machine BIOS will be updated to given revision. If revision flag is not specified an update plan will be printed instead.","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_update-firmware_bios/","page":"metalctl machine update-firmware bios","title":"metalctl machine update-firmware bios","text":"metalctl machine update-firmware bios [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_update-firmware_bios/#Options","page":"metalctl machine update-firmware bios","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_update-firmware_bios/","page":"metalctl machine update-firmware bios","title":"metalctl machine update-firmware bios","text":" --description string the reason why the BIOS should be updated\n -h, --help help for bios\n --revision string the BIOS revision","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_update-firmware_bios/#Options-inherited-from-parent-commands","page":"metalctl machine update-firmware bios","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_update-firmware_bios/","page":"metalctl machine update-firmware bios","title":"metalctl machine update-firmware bios","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_update-firmware_bios/#SEE-ALSO","page":"metalctl machine update-firmware bios","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_update-firmware_bios/","page":"metalctl machine update-firmware bios","title":"metalctl machine update-firmware bios","text":"metalctl machine update-firmware\t - update a machine firmware","category":"page"},{"location":"external/metalctl/docs/metalctl_switch_delete/#metalctl-switch-delete","page":"metalctl switch delete","title":"metalctl switch delete","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_switch_delete/","page":"metalctl switch delete","title":"metalctl switch delete","text":"deletes the switch","category":"page"},{"location":"external/metalctl/docs/metalctl_switch_delete/","page":"metalctl switch delete","title":"metalctl switch delete","text":"metalctl switch delete [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_switch_delete/#Options","page":"metalctl switch delete","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_switch_delete/","page":"metalctl switch delete","title":"metalctl switch delete","text":" --bulk-output when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.\n -f, --file string filename of the create or update request in yaml format, or - for stdin.\n \n Example:\n $ metalctl switch describe switch-1 -o yaml > switch.yaml\n $ vi switch.yaml\n $ # either via stdin\n $ cat switch.yaml | metalctl switch delete -f -\n $ # or via file\n $ metalctl switch delete -f switch.yaml\n \n the file can also contain multiple documents and perform a bulk operation.\n \t\n --force forcefully delete the switch accepting the risk that it still has machines connected to it\n -h, --help help for delete\n --skip-security-prompts skips security prompt for bulk operations\n --timestamps when used with --file (bulk operation): prints timestamps in-between the operations","category":"page"},{"location":"external/metalctl/docs/metalctl_switch_delete/#Options-inherited-from-parent-commands","page":"metalctl switch delete","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_switch_delete/","page":"metalctl switch delete","title":"metalctl switch delete","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_switch_delete/#SEE-ALSO","page":"metalctl switch delete","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_switch_delete/","page":"metalctl switch delete","title":"metalctl switch delete","text":"metalctl switch\t - manage switch entities","category":"page"},{"location":"external/metalctl/docs/metalctl_size_imageconstraint_create/#metalctl-size-imageconstraint-create","page":"metalctl size imageconstraint create","title":"metalctl size imageconstraint create","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_imageconstraint_create/","page":"metalctl size imageconstraint create","title":"metalctl size imageconstraint create","text":"creates the imageconstraint","category":"page"},{"location":"external/metalctl/docs/metalctl_size_imageconstraint_create/","page":"metalctl size imageconstraint create","title":"metalctl size imageconstraint create","text":"metalctl size imageconstraint create [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_size_imageconstraint_create/#Options","page":"metalctl size imageconstraint create","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_imageconstraint_create/","page":"metalctl size imageconstraint create","title":"metalctl size imageconstraint create","text":" --bulk-output when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.\n -f, --file string filename of the create or update request in yaml format, or - for stdin.\n \n Example:\n $ metalctl imageconstraint describe imageconstraint-1 -o yaml > imageconstraint.yaml\n $ vi imageconstraint.yaml\n $ # either via stdin\n $ cat imageconstraint.yaml | metalctl imageconstraint create -f -\n $ # or via file\n $ metalctl imageconstraint create -f imageconstraint.yaml\n \n the file can also contain multiple documents and perform a bulk operation.\n \t\n -h, --help help for create\n --skip-security-prompts skips security prompt for bulk operations\n --timestamps when used with --file (bulk operation): prints timestamps in-between the operations","category":"page"},{"location":"external/metalctl/docs/metalctl_size_imageconstraint_create/#Options-inherited-from-parent-commands","page":"metalctl size imageconstraint create","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_imageconstraint_create/","page":"metalctl size imageconstraint create","title":"metalctl size imageconstraint create","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_size_imageconstraint_create/#SEE-ALSO","page":"metalctl size imageconstraint create","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_imageconstraint_create/","page":"metalctl size imageconstraint create","title":"metalctl size imageconstraint create","text":"metalctl size imageconstraint\t - manage imageconstraint entities","category":"page"},{"location":"external/metalctl/docs/metalctl_network_ip_issues/#metalctl-network-ip-issues","page":"metalctl network ip issues","title":"metalctl network ip issues","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_network_ip_issues/","page":"metalctl network ip issues","title":"metalctl network ip issues","text":"display ips which are in a potential bad state","category":"page"},{"location":"external/metalctl/docs/metalctl_network_ip_issues/","page":"metalctl network ip issues","title":"metalctl network ip issues","text":"metalctl network ip issues [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_network_ip_issues/#Options","page":"metalctl network ip issues","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_network_ip_issues/","page":"metalctl network ip issues","title":"metalctl network ip issues","text":" -h, --help help for issues","category":"page"},{"location":"external/metalctl/docs/metalctl_network_ip_issues/#Options-inherited-from-parent-commands","page":"metalctl network ip issues","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_network_ip_issues/","page":"metalctl network ip issues","title":"metalctl network ip issues","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_network_ip_issues/#SEE-ALSO","page":"metalctl network ip issues","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_network_ip_issues/","page":"metalctl network ip issues","title":"metalctl network ip issues","text":"metalctl network ip\t - manage ip entities","category":"page"},{"location":"external/metalctl/docs/metalctl_version/#metalctl-version","page":"metalctl version","title":"metalctl version","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_version/","page":"metalctl version","title":"metalctl version","text":"print the client and server version information","category":"page"},{"location":"external/metalctl/docs/metalctl_version/","page":"metalctl version","title":"metalctl version","text":"metalctl version [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_version/#Options","page":"metalctl version","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_version/","page":"metalctl version","title":"metalctl version","text":" -h, --help help for version","category":"page"},{"location":"external/metalctl/docs/metalctl_version/#Options-inherited-from-parent-commands","page":"metalctl version","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_version/","page":"metalctl version","title":"metalctl version","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_version/#SEE-ALSO","page":"metalctl version","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_version/","page":"metalctl version","title":"metalctl version","text":"metalctl\t - a cli to manage entities in the metal-stack api","category":"page"},{"location":"external/metalctl/docs/metalctl_tenant_edit/#metalctl-tenant-edit","page":"metalctl tenant edit","title":"metalctl tenant edit","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_tenant_edit/","page":"metalctl tenant edit","title":"metalctl tenant edit","text":"edit the tenant through an editor and update","category":"page"},{"location":"external/metalctl/docs/metalctl_tenant_edit/","page":"metalctl tenant edit","title":"metalctl tenant edit","text":"metalctl tenant edit [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_tenant_edit/#Options","page":"metalctl tenant edit","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_tenant_edit/","page":"metalctl tenant edit","title":"metalctl tenant edit","text":" -h, --help help for edit","category":"page"},{"location":"external/metalctl/docs/metalctl_tenant_edit/#Options-inherited-from-parent-commands","page":"metalctl tenant edit","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_tenant_edit/","page":"metalctl tenant edit","title":"metalctl tenant edit","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_tenant_edit/#SEE-ALSO","page":"metalctl tenant edit","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_tenant_edit/","page":"metalctl tenant edit","title":"metalctl tenant edit","text":"metalctl tenant\t - manage tenant entities","category":"page"},{"location":"external/metalctl/docs/metalctl_size_apply/#metalctl-size-apply","page":"metalctl size apply","title":"metalctl size apply","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_apply/","page":"metalctl size apply","title":"metalctl size apply","text":"applies one or more sizes from a given file","category":"page"},{"location":"external/metalctl/docs/metalctl_size_apply/","page":"metalctl size apply","title":"metalctl size apply","text":"metalctl size apply [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_size_apply/#Options","page":"metalctl size apply","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_apply/","page":"metalctl size apply","title":"metalctl size apply","text":" --bulk-output when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.\n -f, --file string filename of the create or update request in yaml format, or - for stdin.\n \n Example:\n $ metalctl size describe size-1 -o yaml > size.yaml\n $ vi size.yaml\n $ # either via stdin\n $ cat size.yaml | metalctl size apply -f -\n $ # or via file\n $ metalctl size apply -f size.yaml\n \n the file can also contain multiple documents and perform a bulk operation.\n \t\n -h, --help help for apply\n --skip-security-prompts skips security prompt for bulk operations\n --timestamps when used with --file (bulk operation): prints timestamps in-between the operations","category":"page"},{"location":"external/metalctl/docs/metalctl_size_apply/#Options-inherited-from-parent-commands","page":"metalctl size apply","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_apply/","page":"metalctl size apply","title":"metalctl size apply","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_size_apply/#SEE-ALSO","page":"metalctl size apply","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_apply/","page":"metalctl size apply","title":"metalctl size apply","text":"metalctl size\t - manage size entities","category":"page"},{"location":"external/metalctl/docs/metalctl_size_imageconstraint_update/#metalctl-size-imageconstraint-update","page":"metalctl size imageconstraint update","title":"metalctl size imageconstraint update","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_imageconstraint_update/","page":"metalctl size imageconstraint update","title":"metalctl size imageconstraint update","text":"updates the imageconstraint","category":"page"},{"location":"external/metalctl/docs/metalctl_size_imageconstraint_update/","page":"metalctl size imageconstraint update","title":"metalctl size imageconstraint update","text":"metalctl size imageconstraint update [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_size_imageconstraint_update/#Options","page":"metalctl size imageconstraint update","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_imageconstraint_update/","page":"metalctl size imageconstraint update","title":"metalctl size imageconstraint update","text":" --bulk-output when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.\n -f, --file string filename of the create or update request in yaml format, or - for stdin.\n \n Example:\n $ metalctl imageconstraint describe imageconstraint-1 -o yaml > imageconstraint.yaml\n $ vi imageconstraint.yaml\n $ # either via stdin\n $ cat imageconstraint.yaml | metalctl imageconstraint update -f -\n $ # or via file\n $ metalctl imageconstraint update -f imageconstraint.yaml\n \n the file can also contain multiple documents and perform a bulk operation.\n \t\n -h, --help help for update\n --skip-security-prompts skips security prompt for bulk operations\n --timestamps when used with --file (bulk operation): prints timestamps in-between the operations","category":"page"},{"location":"external/metalctl/docs/metalctl_size_imageconstraint_update/#Options-inherited-from-parent-commands","page":"metalctl size imageconstraint update","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_imageconstraint_update/","page":"metalctl size imageconstraint update","title":"metalctl size imageconstraint update","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_size_imageconstraint_update/#SEE-ALSO","page":"metalctl size imageconstraint update","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_imageconstraint_update/","page":"metalctl size imageconstraint update","title":"metalctl size imageconstraint update","text":"metalctl size imageconstraint\t - manage imageconstraint entities","category":"page"},{"location":"external/firewall-controller/README/#Firewall-Controller","page":"firewall-controller","title":"Firewall Controller","text":"","category":"section"},{"location":"external/firewall-controller/README/","page":"firewall-controller","title":"firewall-controller","text":"This controller is installed on a bare-metal firewall in front of several kubernetes worker nodes and responsible to reconcile a ClusterwideNetworkPolicy to nftables rules to control access to and from the kubernetes cluster. It allows also to control the traffic rate going through, to limit network resources for restricted usage scenarios. Nftable and node metrics are exposed with the nftables-exporter and node-exporter, the ips are visible as service and endpoint from the kubernetes cluster.","category":"page"},{"location":"external/firewall-controller/README/","page":"firewall-controller","title":"firewall-controller","text":"Additional an IDS is managed on the firewall to detect known network anomalies. suricata is used for this purpose. Right now, only basic statistics about the amount of scanned packets is reported. In a future release, access to all alarms will be provided.","category":"page"},{"location":"external/firewall-controller/README/#Architecture","page":"firewall-controller","title":"Architecture","text":"","category":"section"},{"location":"external/firewall-controller/README/","page":"firewall-controller","title":"firewall-controller","text":"(Image: Architecture)","category":"page"},{"location":"external/firewall-controller/README/#Automatically-generated-ingress-rules","page":"firewall-controller","title":"Automatically generated ingress rules","text":"","category":"section"},{"location":"external/firewall-controller/README/","page":"firewall-controller","title":"firewall-controller","text":"For every Service of type LoadBalancer in the cluster, the corresponding ingress rules will be automatically generated.","category":"page"},{"location":"external/firewall-controller/README/","page":"firewall-controller","title":"firewall-controller","text":"If loadBalancerSourceRanges is not specified, incomig traffic to this service will be allowed for any source ip addresses.","category":"page"},{"location":"external/firewall-controller/README/#Configuration","page":"firewall-controller","title":"Configuration","text":"","category":"section"},{"location":"external/firewall-controller/README/","page":"firewall-controller","title":"firewall-controller","text":"Firewall Controller is configured with 2 CRDs: firewalls.metal-stack.io and clusterwidenetworkpolicies.metal-stack.io. Both are namespaced and must reside in the firewall namespace. The firewalls CRD is typically written from the gardener-extension-provider-metal, the clusterwidenetworkpolicy should be provided by the deployment of your application.","category":"page"},{"location":"external/firewall-controller/README/","page":"firewall-controller","title":"firewall-controller","text":"Example Firewall CRD:","category":"page"},{"location":"external/firewall-controller/README/","page":"firewall-controller","title":"firewall-controller","text":"apiVersion: metal-stack.io/v1\nkind: Firewall\nmetadata:\n namespace: firewall\n name: firewall\nspec:\n # Interval of reconciliation if nftables rules and network traffic accounting\n interval: 10s\n # Ratelimits specify on which physical interface, which maximum rate of traffic is allowed\n ratelimits:\n # The name of the interface visible with ip link show\n - interface: vrf104009\n # The maximum rate in MBits/s\n rate: 10\n # Internalprefixes defines a list of prefixes where the traffic going to, or coming from is considered internal, e.g. not leaving into external networks\n # given the architecture picture above this would be:\n internalprefixes:\n - \"1.2.3.0/24\n - \"172.17.0.0/16\"\n - \"10.0.0.0/8\"","category":"page"},{"location":"external/firewall-controller/README/","page":"firewall-controller","title":"firewall-controller","text":"Example ClusterwideNetworkPolicy:","category":"page"},{"location":"external/firewall-controller/README/","page":"firewall-controller","title":"firewall-controller","text":"apiVersion: metal-stack.io/v1\nkind: ClusterwideNetworkPolicy\nmetadata:\n namespace: firewall\n name: clusterwidenetworkpolicy-sample\nspec:\n egress:\n - to:\n - cidr: 1.1.0.0/24\n except:\n - 1.1.1.0/16\n - cidr: 8.8.8.8/32\n ports:\n - protocol: UDP\n port: 53\n - protocol: TCP\n port: 53","category":"page"},{"location":"external/firewall-controller/README/#Status","page":"firewall-controller","title":"Status","text":"","category":"section"},{"location":"external/firewall-controller/README/","page":"firewall-controller","title":"firewall-controller","text":"Once the firewall-controller is running, it will report several statistics to the Firewall CRD Status: This can be inspected by running:","category":"page"},{"location":"external/firewall-controller/README/","page":"firewall-controller","title":"firewall-controller","text":"kubectl describe -n firewall firewall","category":"page"},{"location":"external/firewall-controller/README/","page":"firewall-controller","title":"firewall-controller","text":"The output would look like:","category":"page"},{"location":"external/firewall-controller/README/","page":"firewall-controller","title":"firewall-controller","text":"Status:\n Last Run: 2020-06-17T13:18:58Z\n Stats:\n # Network traffic in bytes separated into external and internal in/out/total\n Devices:\n External:\n In: 91696\n Out: 34600\n Total: 0\n Internal:\n In: 0\n Out: 0\n Total: 2678671\n # IDS Statistics by interface\n Idsstats:\n vrf104009:\n Drop: 1992\n Invalidchecksums: 0\n Packets: 4997276\n # nftable rule statistics by rule name\n Rules:\n Accept:\n BGP unnumbered:\n Counter:\n Bytes: 0\n Packets: 0\n SSH incoming connections:\n Counter:\n Bytes: 936\n Packets: 16\n accept established connections:\n Counter:\n Bytes: 21211168\n Packets: 39785\n accept icmp:\n Counter:\n Bytes: 0\n Packets: 0\n accept traffic for k8s service kube-system/vpn-shoot:\n Counter:\n Bytes: 360\n Packets: 6\n Drop:\n drop invalid packets:\n Counter:\n Bytes: 52\n Packets: 1\n drop invalid packets from forwarding to prevent malicious activity:\n Counter:\n Bytes: 0\n Packets: 0\n drop invalid packets to prevent malicious activity:\n Counter:\n Bytes: 0\n Packets: 0\n drop packets with invalid ct state:\n Counter:\n Bytes: 0\n Packets: 0\n drop ping floods:\n Counter:\n Bytes: 0\n Packets: 0\n Other:\n block bgp forward to machines:\n Counter:\n Bytes: 0\n Packets: 0\n count and log dropped packets:\n Counter:\n Bytes: 2528\n Packets: 51\n snat (networkid: internet):\n Counter:\n Bytes: 36960\n Packets: 486","category":"page"},{"location":"external/firewall-controller/README/#Prometheus-integration","page":"firewall-controller","title":"Prometheus integration","text":"","category":"section"},{"location":"external/firewall-controller/README/","page":"firewall-controller","title":"firewall-controller","text":"There are two exporters running on the firewall to report essential metrics from this machine:","category":"page"},{"location":"external/firewall-controller/README/","page":"firewall-controller","title":"firewall-controller","text":"node-exporter for machine specific metrics like cpu, ram and disk usage, see node-exporter for details.\nnftables-exporter for nftables metrics, see nftables-exporter","category":"page"},{"location":"external/firewall-controller/README/","page":"firewall-controller","title":"firewall-controller","text":"Both exporters are exposed as services:","category":"page"},{"location":"external/firewall-controller/README/","page":"firewall-controller","title":"firewall-controller","text":"kubectl get svc -n firewall\nNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE\nnftables-exporter ClusterIP None 9630/TCP 13h\nnode-exporter ClusterIP None 9100/TCP 13h","category":"page"},{"location":"external/firewall-controller/README/","page":"firewall-controller","title":"firewall-controller","text":"These services are in front of virtual endpoints:","category":"page"},{"location":"external/firewall-controller/README/","page":"firewall-controller","title":"firewall-controller","text":"kubectl get ep -n firewall\nNAME ENDPOINTS AGE\nnftables-exporter 10.3.164.1:9630 13h\nnode-exporter 10.3.164.1:9100 13h","category":"page"},{"location":"external/firewall-controller/README/","page":"firewall-controller","title":"firewall-controller","text":"You can scrape these services in you prometheus installation to get the metrics.","category":"page"},{"location":"external/firewall-controller/README/","page":"firewall-controller","title":"firewall-controller","text":"To check you can run:","category":"page"},{"location":"external/firewall-controller/README/","page":"firewall-controller","title":"firewall-controller","text":"curl nftables-exporter.firewall.svc.cluster.local:9630/metrics\ncurl node-exporter.firewall.svc.cluster.local:9100/metrics","category":"page"},{"location":"external/firewall-controller/README/#Firewall-Logs","page":"firewall-controller","title":"Firewall Logs","text":"","category":"section"},{"location":"external/firewall-controller/README/","page":"firewall-controller","title":"firewall-controller","text":"It is also possible to tail for the dropped packets with the following command (install stern from stern ):","category":"page"},{"location":"external/firewall-controller/README/","page":"firewall-controller","title":"firewall-controller","text":"stern -n firewall drop","category":"page"},{"location":"external/firewall-controller/README/","page":"firewall-controller","title":"firewall-controller","text":"The output will look like:","category":"page"},{"location":"external/firewall-controller/README/","page":"firewall-controller","title":"firewall-controller","text":"\ndroptailer-6d556bd988-4g8gp droptailer 2020-06-17 13:23:27 +0000 UTC {\"DPT\":\"4000\",\"DST\":\"1.2.3.4\",\"ID\":\"54321\",\"IN\":\"vrf104009\",\"LEN\":\"40\",\"MAC\":\"ca:41:f9:80:fa:89:aa:bb:0e:62:8c:a6:08:00\",\"OUT\":\"vlan179\",\"PREC\":\"0x00\",\"PROTO\":\"TCP\",\"RES\":\"0x00\",\"SPT\":\"38464\",\"SRC\":\"2.3.4.5\",\"SYN\":\"\",\"TOS\":\"0x00\",\"TTL\":\"236\",\"URGP\":\"0\",\"WINDOW\":\"65535\",\"timestamp\":\"2020-06-17 13:23:27 +0000 UTC\"}\ndroptailer-6d556bd988-4g8gp droptailer 2020-06-17 13:23:34 +0000 UTC {\"DPT\":\"2362\",\"DST\":\"1.2.3.4\",\"ID\":\"44545\",\"IN\":\"vrf104009\",\"LEN\":\"40\",\"MAC\":\"ca:41:f9:80:fa:89:aa:bb:0e:62:8c:a6:08:00\",\"OUT\":\"\",\"PREC\":\"0x00\",\"PROTO\":\"TCP\",\"RES\":\"0x00\",\"SPT\":\"40194\",\"SRC\":\"2.3.4.5\",\"SYN\":\"\",\"TOS\":\"0x00\",\"TTL\":\"242\",\"URGP\":\"0\",\"WINDOW\":\"1024\",\"timestamp\":\"2020-06-17 13:23:34 +0000 UTC\"}\ndroptailer-6d556bd988-4g8gp droptailer 2020-06-17 13:23:30 +0000 UTC {\"DPT\":\"650\",\"DST\":\"1.2.3.4\",\"ID\":\"12399\",\"IN\":\"vrf104009\",\"LEN\":\"40\",\"MAC\":\"ca:41:f9:80:fa:89:aa:bb:0e:62:8c:a6:08:00\",\"OUT\":\"vlan179\",\"PREC\":\"0x00\",\"PROTO\":\"TCP\",\"RES\":\"0x00\",\"SPT\":\"40194\",\"SRC\":\"2.3.4.5\",\"SYN\":\"\",\"TOS\":\"0x00\",\"TTL\":\"241\",\"URGP\":\"0\",\"WINDOW\":\"1024\",\"timestamp\":\"2020-06-17 13:23:30 +0000 UTC\"}\ndroptailer-6d556bd988-4g8gp droptailer 2020-06-17 13:23:34 +0000 UTC {\"DPT\":\"2362\",\"DST\":\"1.2.3.4\",\"ID\":\"44545\",\"IN\":\"vrf104009\",\"LEN\":\"40\",\"MAC\":\"ca:41:f9:80:fa:89:aa:bb:0e:62:8c:a6:08:00\",\"OUT\":\"\",\"PREC\":\"0x00\",\"PROTO\":\"TCP\",\"RES\":\"0x00\",\"SPT\":\"40194\",\"SRC\":\"2.3.4.5\",\"SYN\":\"\",\"TOS\":\"0x00\",\"TTL\":\"242\",\"URGP\":\"0\",\"WINDOW\":\"1024\",\"timestamp\":\"2020-06-17 13:23:34 +0000 UTC\"}\ndroptailer-6d556bd988-4g8gp droptailer 2020-06-17 13:23:10 +0000 UTC {\"DPT\":\"63351\",\"DST\":\"1.2.3.4\",\"ID\":\"11855\",\"IN\":\"vrf104009\",\"LEN\":\"40\",\"MAC\":\"ca:41:f9:80:fa:89:aa:bb:0e:62:8c:a6:08:00\",\"OUT\":\"vlan179\",\"PREC\":\"0x00\",\"PROTO\":\"TCP\",\"RES\":\"0x00\",\"SPT\":\"54589\",\"SRC\":\"2.3.4.5\",\"SYN\":\"\",\"TOS\":\"0x00\",\"TTL\":\"245\",\"URGP\":\"0\",\"WINDOW\":\"1024\",\"timestamp\":\"2020-06-17 13:23:10 +0000 UTC\"}\ndroptailer-6d556bd988-4g8gp droptailer 2020-06-17 13:23:51 +0000 UTC {\"DPT\":\"8002\",\"DST\":\"1.2.3.4\",\"ID\":\"17539\",\"IN\":\"vrf104009\",\"LEN\":\"40\",\"MAC\":\"ca:41:f9:80:fa:89:aa:bb:0e:62:8c:a6:08:00\",\"OUT\":\"\",\"PREC\":\"0x00\",\"PROTO\":\"TCP\",\"RES\":\"0x00\",\"SPT\":\"47615\",\"SRC\":\"2.3.4.5\",\"SYN\":\"\",\"TOS\":\"0x08\",\"TTL\":\"239\",\"URGP\":\"0\",\"WINDOW\":\"1024\",\"timestamp\":\"2020-06-17 13:23:51 +0000 UTC\"}","category":"page"},{"location":"external/firewall-controller/README/","page":"firewall-controller","title":"firewall-controller","text":"You can forward the droptailer logs to any log aggregation infrastructure you have in place.","category":"page"},{"location":"external/firewall-controller/README/#Page-Tree","page":"firewall-controller","title":"Page Tree","text":"","category":"section"},{"location":"external/firewall-controller/README/","page":"firewall-controller","title":"firewall-controller","text":"Pages = vcat([[joinpath(root, file)[length(@__DIR__)+2:end] for file in files] for (root, dirs, files) in walkdir(@__DIR__)]...)","category":"page"},{"location":"external/metalctl/docs/metalctl_tenant_list/#metalctl-tenant-list","page":"metalctl tenant list","title":"metalctl tenant list","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_tenant_list/","page":"metalctl tenant list","title":"metalctl tenant list","text":"list all tenants","category":"page"},{"location":"external/metalctl/docs/metalctl_tenant_list/","page":"metalctl tenant list","title":"metalctl tenant list","text":"metalctl tenant list [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_tenant_list/#Options","page":"metalctl tenant list","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_tenant_list/","page":"metalctl tenant list","title":"metalctl tenant list","text":" --annotations strings annotations\n -h, --help help for list\n --id string ID of the tenant.\n --name string Name of the tenant.\n --sort-by strings sort by (comma separated) column(s), sort direction can be changed by appending :asc or :desc behind the column identifier. possible values: description|id|name","category":"page"},{"location":"external/metalctl/docs/metalctl_tenant_list/#Options-inherited-from-parent-commands","page":"metalctl tenant list","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_tenant_list/","page":"metalctl tenant list","title":"metalctl tenant list","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_tenant_list/#SEE-ALSO","page":"metalctl tenant list","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_tenant_list/","page":"metalctl tenant list","title":"metalctl tenant list","text":"metalctl tenant\t - manage tenant entities","category":"page"},{"location":"external/metalctl/docs/metalctl_machine/#metalctl-machine","page":"metalctl machine","title":"metalctl machine","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine/","page":"metalctl machine","title":"metalctl machine","text":"manage machine entities","category":"page"},{"location":"external/metalctl/docs/metalctl_machine/#Synopsis","page":"metalctl machine","title":"Synopsis","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine/","page":"metalctl machine","title":"metalctl machine","text":"a machine is a bare metal server provisioned through metal-stack that is intended to run user workload.","category":"page"},{"location":"external/metalctl/docs/metalctl_machine/#Options","page":"metalctl machine","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine/","page":"metalctl machine","title":"metalctl machine","text":" -h, --help help for machine","category":"page"},{"location":"external/metalctl/docs/metalctl_machine/#Options-inherited-from-parent-commands","page":"metalctl machine","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine/","page":"metalctl machine","title":"metalctl machine","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_machine/#SEE-ALSO","page":"metalctl machine","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine/","page":"metalctl machine","title":"metalctl machine","text":"metalctl\t - a cli to manage entities in the metal-stack api\nmetalctl machine apply\t - applies one or more machines from a given file\nmetalctl machine console\t - console access to a machine\nmetalctl machine consolepassword\t - fetch the consolepassword for a machine\nmetalctl machine create\t - creates the machine\nmetalctl machine delete\t - deletes the machine\nmetalctl machine describe\t - describes the machine\nmetalctl machine edit\t - edit the machine through an editor and update\nmetalctl machine identify\t - manage machine chassis identify LED power\nmetalctl machine ipmi\t - display ipmi details of the machine, if no machine ID is given all ipmi addresses are returned.\nmetalctl machine issues\t - display machines which are in a potential bad state\nmetalctl machine list\t - list all machines\nmetalctl machine lock\t - lock a machine\nmetalctl machine logs\t - display machine provisioning logs\nmetalctl machine power\t - manage machine power\nmetalctl machine reinstall\t - reinstalls an already allocated machine\nmetalctl machine reserve\t - reserve a machine\nmetalctl machine update\t - updates the machine\nmetalctl machine update-firmware\t - update a machine firmware","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_describe/#metalctl-machine-describe","page":"metalctl machine describe","title":"metalctl machine describe","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_describe/","page":"metalctl machine describe","title":"metalctl machine describe","text":"describes the machine","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_describe/","page":"metalctl machine describe","title":"metalctl machine describe","text":"metalctl machine describe [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_describe/#Options","page":"metalctl machine describe","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_describe/","page":"metalctl machine describe","title":"metalctl machine describe","text":" -h, --help help for describe","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_describe/#Options-inherited-from-parent-commands","page":"metalctl machine describe","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_describe/","page":"metalctl machine describe","title":"metalctl machine describe","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_describe/#SEE-ALSO","page":"metalctl machine describe","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_describe/","page":"metalctl machine describe","title":"metalctl machine describe","text":"metalctl machine\t - manage machine entities","category":"page"},{"location":"installation/deployment/#Deploying-metal-stack","page":"Installation","title":"Deploying metal-stack","text":"","category":"section"},{"location":"installation/deployment/","page":"Installation","title":"Installation","text":"We are bootstrapping the metal control plane as well as our partitions with Ansible through CI.","category":"page"},{"location":"installation/deployment/","page":"Installation","title":"Installation","text":"In order to build up your deployment, we recommend to make use of the same Ansible roles that we are using by ourselves in order to deploy the metal-stack. You can find them in the repository called metal-roles.","category":"page"},{"location":"installation/deployment/","page":"Installation","title":"Installation","text":"In order to wrap up deployment dependencies there is a special deployment base image hosted on GitHub that you can use for running the deployment. Using this Docker image eliminates a lot of moving parts in the deployment and should keep the footprints on your system fairly small and maintainable.","category":"page"},{"location":"installation/deployment/","page":"Installation","title":"Installation","text":"This document will from now on assume that you want to use our Ansible deployment roles for setting up metal-stack. We will also use the deployment base image, so you should also have Docker installed. It is in the nature of software deployments to differ from site to site, company to company, user to user. Therefore, we can only describe you the way of how the deployment works for us. It is up to you to tweak the deployment described in this document to your requirements.","category":"page"},{"location":"installation/deployment/","page":"Installation","title":"Installation","text":"Pages = [\"deployment.md\"]\nDepth = 5","category":"page"},{"location":"installation/deployment/","page":"Installation","title":"Installation","text":"warning: Warning\nProbably you need to learn writing Ansible playbooks if you want to be able to deploy the metal-stack as presented in this documentation. However, even when starting without any knowledge about Ansible it should be possible to follow these docs. In case you need further explanations regarding Ansible please refer to docs.ansible.com.","category":"page"},{"location":"installation/deployment/","page":"Installation","title":"Installation","text":"info: Info\nIf you do not want to use Ansible for deployment, you need to come up with a deployment mechanism by yourself. However, you will probably be able to re-use some of our contents from our metal-roles repository, e.g. the Helm chart for deploying the metal control plane.","category":"page"},{"location":"installation/deployment/","page":"Installation","title":"Installation","text":"tip: Tip\nYou can use the mini-lab as a template project for your own deployment. It uses the same approach as described in this document.","category":"page"},{"location":"installation/deployment/#Metal-Control-Plane-Deployment","page":"Installation","title":"Metal Control Plane Deployment","text":"","category":"section"},{"location":"installation/deployment/","page":"Installation","title":"Installation","text":"The metal control plane is typically deployed in a Kubernetes cluster. Therefore, this document will assume that you have a Kubernetes cluster ready for getting deployed. Even though it is theoretically possible to deploy metal-stack without Kubernetes, we strongly advise you to use the described method because we believe that Kubernetes gives you a lot of benefits regarding the stability and maintainability of the application deployment.","category":"page"},{"location":"installation/deployment/","page":"Installation","title":"Installation","text":"tip: Tip\nFor metal-stack it does not matter where your control plane Kubernetes cluster is located. You can of course use a cluster managed by a hyperscaler. This has the advantage of not having to setup Kubernetes by yourself and could even become beneficial in terms of fail-safe operation. The only requirement from metal-stack is that your partitions can establish network connections to the metal control plane. If you are interested, you can find a reasoning behind this deployment decision here.","category":"page"},{"location":"installation/deployment/","page":"Installation","title":"Installation","text":"Let's start off with a fresh folder for your deployment:","category":"page"},{"location":"installation/deployment/","page":"Installation","title":"Installation","text":"mkdir -p metal-stack-deployment\ncd metal-stack-deployment","category":"page"},{"location":"installation/deployment/","page":"Installation","title":"Installation","text":"At the end of this section we are gonna end up with the following files and folder structures:","category":"page"},{"location":"installation/deployment/","page":"Installation","title":"Installation","text":".\n├── ansible.cfg\n├── deploy_metal_control_plane.yaml\n├── files\n│   └── certs\n│      ├── ca-config.json\n│      ├── ca-csr.json\n│      ├── metal-api-grpc\n│      │   ├── client.json\n│      │   ├── server.json\n│      ├── masterdata-api\n│      │   ├── client.json\n│      │   ├── server.json\n│      └── roll_certs.sh\n├── inventories\n│   ├── control-plane.yaml\n│   └── group_vars\n│      ├── all\n│      │   └── images.yaml\n│      └── control-plane\n│        ├── common.yaml\n│         └── metal.yml\n├── generate_role_requirements.yaml\n└── roles\n └── ingress-controller\n └── tasks\n └── main.yaml","category":"page"},{"location":"installation/deployment/","page":"Installation","title":"Installation","text":"You can already define the inventories/group_vars/all/images.yaml file. It contains the metal-stack version you are gonna deploy:","category":"page"},{"location":"installation/deployment/","page":"Installation","title":"Installation","text":"using Docs\n\nt = \"\"\"\n```yaml\n---\nmetal_stack_release_version: %s\n```\n\"\"\"\n\nmarkdownTemplate(t, releaseVersion())","category":"page"},{"location":"installation/deployment/#Releases-and-Ansible-Role-Dependencies","page":"Installation","title":"Releases and Ansible Role Dependencies","text":"","category":"section"},{"location":"installation/deployment/","page":"Installation","title":"Installation","text":"As metal-stack consists of many microservices all having individual versions, we have come up with a releases repository. It contains a YAML file (we often call it release vector) describing the fitting versions of all components for every release of metal-stack.","category":"page"},{"location":"installation/deployment/","page":"Installation","title":"Installation","text":"Ansible role dependencies are also part of a metal-stack release. Therefore, we will now write up a playbook, which dynamically renders a requirements.yaml file from the ansible-roles defined in the release repository. The requirements.yaml can then be used to resolve the actual role dependencies through Ansible Galaxy. Define the following playbook in generate_role_requirements.yaml:","category":"page"},{"location":"installation/deployment/","page":"Installation","title":"Installation","text":"---\n- name: generate requirements.yaml\n hosts: control-plane\n connection: local\n gather_facts: false\n vars:\n release_vector_url: \"https://raw.githubusercontent.com/metal-stack/releases/{{ metal_stack_release_version }}/release.yaml\"\n tasks:\n - name: download release vector\n uri:\n url: \"{{ release_vector_url }}\"\n return_content: yes\n register: release_vector\n\n - name: write requirements.yaml from release vector\n copy:\n dest: \"{{ playbook_dir }}/requirements.yaml\"\n content: |\n {% for role_name, role_params in (release_vector.content | from_yaml).get('ansible-roles').items() %}\n - src: {{ role_params.get('repository') }}\n name: {{ role_name }}\n version: {{ hostvars[inventory_hostname][role_name | lower | replace('-', '_') + '_version'] | default(role_params.get('version'), true) }}\n {% endfor %}","category":"page"},{"location":"installation/deployment/","page":"Installation","title":"Installation","text":"This playbook will always be run before the actual metal-stack deployment and provide you with the proper versions of the Ansible role dependencies.","category":"page"},{"location":"installation/deployment/#Inventory","page":"Installation","title":"Inventory","text":"","category":"section"},{"location":"installation/deployment/","page":"Installation","title":"Installation","text":"Then, there will be an inventory for the control plane deployment in inventories/control-plane.yaml that adds the localhost to the control-plane host group:","category":"page"},{"location":"installation/deployment/","page":"Installation","title":"Installation","text":"---\ncontrol-plane:\n hosts:\n localhost:\n ansible_python_interpreter: \"{{ ansible_playbook_python }}\"","category":"page"},{"location":"installation/deployment/","page":"Installation","title":"Installation","text":"We do this since we are deploying to Kubernetes and do not need to SSH-connect to any hosts for the deployment (which is what Ansible typically does). This inventory is also necessary to pick up the variables inside inventories/group_vars/control-plane during the deployment.","category":"page"},{"location":"installation/deployment/","page":"Installation","title":"Installation","text":"We recommend using the following ansible.cfg:","category":"page"},{"location":"installation/deployment/","page":"Installation","title":"Installation","text":"[defaults]\nretry_files_enabled = false\nforce_color = true\nhost_key_checking = false\nstdout_callback = yaml\njinja2_native = true\ntransport = ssh\ntimeout = 30\nforce_valid_group_names = ignore\n\n[ssh_connection]\nretries=3\nssh_executable = /usr/bin/ssh","category":"page"},{"location":"installation/deployment/","page":"Installation","title":"Installation","text":"Most of the properties in there are up to taste, but make sure you enable the Jinja2 native environment as this is needed for some of our roles in certain cases.","category":"page"},{"location":"installation/deployment/#Control-Plane-Playbook","page":"Installation","title":"Control Plane Playbook","text":"","category":"section"},{"location":"installation/deployment/","page":"Installation","title":"Installation","text":"Next, we will define the actual deployment playbook in a file called deploy_metal_control_plane.yaml. You can start with the following lines:","category":"page"},{"location":"installation/deployment/","page":"Installation","title":"Installation","text":"---\n- name: Deploy Control Plane\n hosts: control-plane\n connection: local\n gather_facts: no\n vars:\n setup_yaml:\n - url: https://raw.githubusercontent.com/metal-stack/releases/{{ metal_stack_release_version }}/release.yaml\n meta_var: metal_stack_release\n roles:\n - name: ansible-common\n tags: always\n - name: ingress-controller\n tags: ingress-controller\n - name: metal-roles/control-plane/roles/prepare\n tags: prepare\n - name: metal-roles/control-plane/roles/nsq\n tags: nsq\n - name: metal-roles/control-plane/roles/metal-db\n tags: metal-db\n - name: metal-roles/control-plane/roles/ipam-db\n tags: ipam-db\n - name: metal-roles/control-plane/roles/masterdata-db\n tags: masterdata-db\n - name: metal-roles/control-plane/roles/metal\n tags: metal","category":"page"},{"location":"installation/deployment/","page":"Installation","title":"Installation","text":"Basically, this playbook does the following:","category":"page"},{"location":"installation/deployment/","page":"Installation","title":"Installation","text":"Include all the modules, filter plugins, etc. of ansible-common into the play\nDeploys an ingress-controller into your cluster\nDeploys the metal-stack by\nRunning preparation tasks\nDeploying NSQ\nDeploying the rethinkdb database for the metal-api (wrapped in a backup-restore-sidecar),\nDeploying the postgres database for go-ipam (wrapped in a backup-restore-sidecar)\nDeploying the postgres database for the masterdata-api (wrapped in a backup-restore-sidecar)\nApplying the metal control plane helm chart","category":"page"},{"location":"installation/deployment/#Setup-an-ingress-controller","page":"Installation","title":"Setup an ingress-controller","text":"","category":"section"},{"location":"installation/deployment/","page":"Installation","title":"Installation","text":"As a next step you have to add a task for deploying an ingress-controller into your cluster. nginx-ingress is what we use. If you want to use another ingress-controller, you need to parametrize the metal roles carefully. When you just use ingress-nginx, make sure to also deploy it to the default namespace ingress-nginx.","category":"page"},{"location":"installation/deployment/","page":"Installation","title":"Installation","text":"This is how your roles/ingress-controller/tasks/main.yaml could look like:","category":"page"},{"location":"installation/deployment/","page":"Installation","title":"Installation","text":"- name: Deploy ingress-controller\n include_role:\n name: ansible-common/roles/helm-chart\n vars:\n helm_repo: \"https://helm.nginx.com/stable\"\n helm_chart: nginx-ingress\n helm_release_name: nginx-ingress\n helm_target_namespace: ingress-nginx","category":"page"},{"location":"installation/deployment/","page":"Installation","title":"Installation","text":"tip: Tip\nThe ansible-common repository contains very general roles and modules that you can also use when extending your deployment further.","category":"page"},{"location":"installation/deployment/#Deployment-Parametrization","page":"Installation","title":"Deployment Parametrization","text":"","category":"section"},{"location":"installation/deployment/","page":"Installation","title":"Installation","text":"Now you can parametrize the referenced roles to fit your environment. The role parametrization can be looked up in the role documentation on metal-roles/control-plane. You should not need to define a lot of variables for the beginning as most values are reasonably defaulted. You can start with the following content for group_vars/control-plane/common.yaml:","category":"page"},{"location":"installation/deployment/","page":"Installation","title":"Installation","text":"---\nmetal_control_plane_ingress_dns: # if you do not have a DNS entry, you could also start with .nip.io","category":"page"},{"location":"installation/deployment/#Providing-Certificates","page":"Installation","title":"Providing Certificates","text":"","category":"section"},{"location":"installation/deployment/","page":"Installation","title":"Installation","text":"We have several components in our stack that communicate over encrypted gRPC just like Kubernetes components do.","category":"page"},{"location":"installation/deployment/","page":"Installation","title":"Installation","text":"For the very basic setup you will need to create self-signed certificates for the communication between the following components (see architecture document):","category":"page"},{"location":"installation/deployment/","page":"Installation","title":"Installation","text":"metal-api and masterdata-api (in-cluster traffic communication)\nmetal-api and metal-hammer (partition to control plane communication)","category":"page"},{"location":"installation/deployment/","page":"Installation","title":"Installation","text":"Here is a snippet for files/roll_certs.sh that you can use for generating your certificates (requires cfssl):","category":"page"},{"location":"installation/deployment/","page":"Installation","title":"Installation","text":"#!/usr/bin/env bash\nset -eo pipefail\n\nfor i in \"$@\"\ndo\ncase $i in\n -t=*|--target=*)\n TARGET=\"${i#*=}\"\n shift\n ;;\n *)\n echo \"unknown parameter passed: $1\"\n exit 1\n ;;\nesac\ndone\n\nif [ -z \"$TARGET\" ]; then\n echo \"generating ca cert\"\n cfssl genkey -initca ca-csr.json | cfssljson -bare ca\n rm *.csr\nfi\n\nif [ -z \"$TARGET\" ] || [ $TARGET == \"grpc\" ]; then\n pushd metal-api-grpc\n echo \"generating grpc certs\"\n cfssl gencert -ca=../ca.pem -ca-key=../ca-key.pem -config=../ca-config.json -profile=server server.json | cfssljson -bare server\n cfssl gencert -ca=../ca.pem -ca-key=../ca-key.pem -config=../ca-config.json -profile=client client.json | cfssljson -bare client\n rm *.csr\n popd\nfi\n\nif [ -z \"$TARGET\" ] || [ $TARGET == \"masterdata-api\" ]; then\n pushd masterdata-api\n echo \"generating masterdata-api certs\"\n rm -f *.pem\n cfssl gencert -ca=../ca.pem -ca-key=../ca-key.pem -config=../ca-config.json -profile=client-server server.json | cfssljson -bare server\n cfssl gencert -ca=../ca.pem -ca-key=../ca-key.pem -config=../ca-config.json -profile=client client.json | cfssljson -bare client\n rm *.csr\n popd\nfi","category":"page"},{"location":"installation/deployment/","page":"Installation","title":"Installation","text":"Also define the following configurations for cfssl:","category":"page"},{"location":"installation/deployment/","page":"Installation","title":"Installation","text":"files/certs/ca-config.json\n{\n \"signing\": {\n \"default\": {\n \"expiry\": \"43800h\"\n },\n \"profiles\": {\n \"server\": {\n \"expiry\": \"43800h\",\n \"usages\": [\"signing\", \"key encipherment\", \"server auth\"]\n },\n \"client\": {\n \"expiry\": \"43800h\",\n \"usages\": [\"signing\", \"key encipherment\", \"client auth\"]\n },\n \"client-server\": {\n \"expiry\": \"43800h\",\n \"usages\": [\n \"signing\",\n \"key encipherment\",\n \"client auth\",\n \"server auth\"\n ]\n }\n }\n }\n}\nfiles/certs/ca-csr.json\n{\n \"CN\": \"metal-control-plane\",\n \"hosts\": [],\n \"key\": {\n \"algo\": \"rsa\",\n \"size\": 4096\n },\n \"names\": [\n {\n \"C\": \"DE\",\n \"L\": \"Munich\",\n \"O\": \"Metal-Stack\",\n \"OU\": \"DevOps\",\n \"ST\": \"Bavaria\"\n }\n ]\n}\nfiles/certs/masterdata-api/client.json\n{\n \"CN\": \"masterdata-client\",\n \"hosts\": [\"\"],\n \"key\": {\n \"algo\": \"ecdsa\",\n \"size\": 256\n },\n \"names\": [\n {\n \"C\": \"DE\",\n \"L\": \"Munich\",\n \"O\": \"Metal-Stack\",\n \"OU\": \"DevOps\",\n \"ST\": \"Bavaria\"\n }\n ]\n}\nfiles/certs/masterdata-api/server.json\n{\n \"CN\": \"masterdata-api\",\n \"hosts\": [\n \"localhost\",\n \"masterdata-api\",\n \"masterdata-api.metal-control-plane.svc\",\n \"masterdata-api.metal-control-plane.svc.cluster.local\"\n ],\n \"key\": {\n \"algo\": \"ecdsa\",\n \"size\": 256\n },\n \"names\": [\n {\n \"C\": \"DE\",\n \"L\": \"Munich\",\n \"O\": \"Metal-Stack\",\n \"OU\": \"DevOps\",\n \"ST\": \"Bavaria\"\n }\n ]\n}\nfiles/certs/metal-api-grpc/client.json\n{\n \"CN\": \"grpc-client\",\n \"hosts\": [\"\"],\n \"key\": {\n \"algo\": \"rsa\",\n \"size\": 4096\n },\n \"names\": [\n {\n \"C\": \"DE\",\n \"L\": \"Munich\",\n \"O\": \"Metal-Stack\",\n \"OU\": \"DevOps\",\n \"ST\": \"Bavaria\"\n }\n ]\n}\nfiles/certs/metal-api-grpc/server.json (Fill in your control plane ingress DNS here)\n{\n \"CN\": \"metal-api\",\n \"hosts\": [\"\"],\n \"key\": {\n \"algo\": \"rsa\",\n \"size\": 4096\n },\n \"names\": [\n {\n \"C\": \"DE\",\n \"L\": \"Munich\",\n \"O\": \"Metal-Stack\",\n \"OU\": \"DevOps\",\n \"ST\": \"Bavaria\"\n }\n ]\n}","category":"page"},{"location":"installation/deployment/","page":"Installation","title":"Installation","text":"Running the roll_certs.sh bash script without any arguments should generate you the required certificates.","category":"page"},{"location":"installation/deployment/","page":"Installation","title":"Installation","text":"Now Provide the paths to these certificates in group_vars/control-plane/metal.yaml:","category":"page"},{"location":"installation/deployment/","page":"Installation","title":"Installation","text":"---\nmetal_masterdata_api_tls_ca: \"{{ lookup('file', 'certs/ca.pem') }}\"\nmetal_masterdata_api_tls_cert: \"{{ lookup('file', 'certs/masterdata-api/server.pem') }}\"\nmetal_masterdata_api_tls_cert_key: \"{{ lookup('file', 'certs/masterdata-api/server-key.pem') }}\"\nmetal_masterdata_api_tls_client_cert: \"{{ lookup('file', 'certs/masterdata-api/client.pem') }}\"\nmetal_masterdata_api_tls_client_key: \"{{ lookup('file', 'certs/masterdata-api/client-key.pem') }}\"\n\nmetal_api_grpc_certs_server_key: \"{{ lookup('file', 'certs/metal-api-grpc/server-key.pem') }}\"\nmetal_api_grpc_certs_server_cert: \"{{ lookup('file', 'certs/metal-api-grpc/server.pem') }}\"\nmetal_api_grpc_certs_client_key: \"{{ lookup('file', 'certs/metal-api-grpc/client-key.pem') }}\"\nmetal_api_grpc_certs_client_cert: \"{{ lookup('file', 'certs/metal-api-grpc/client.pem') }}\"\nmetal_api_grpc_certs_ca_cert: \"{{ lookup('file', 'certs/ca.pem') }}\"","category":"page"},{"location":"installation/deployment/","page":"Installation","title":"Installation","text":"tip: Tip\nFor the actual communication between the metal-api and the user clients (REST API, runs over the ingress-controller you deployed before), you can simply deploy a tool like cert-manager into your Kubernetes cluster, which will automatically provide your ingress domains with Let's Encrypt certificates.","category":"page"},{"location":"installation/deployment/#Running-the-Deployment","page":"Installation","title":"Running the Deployment","text":"","category":"section"},{"location":"installation/deployment/","page":"Installation","title":"Installation","text":"Finally, it should be possible to run the deployment through a Docker container. Make sure to have the Kubeconfig file of your cluster and set the path in the following command accordingly:","category":"page"},{"location":"installation/deployment/","page":"Installation","title":"Installation","text":"using Docs\n\nbase_image = releaseVector()[\"docker-images\"][\"metal-stack\"][\"generic\"][\"deployment-base\"][\"tag\"]\n\nt = raw\"\"\"\n```bash\nexport KUBECONFIG=\ndocker run --rm -it \\\n -v $(pwd):/workdir \\\n --workdir /workdir \\\n -e KUBECONFIG=\"${KUBECONFIG}\" \\\n -e K8S_AUTH_KUBECONFIG=\"${KUBECONFIG}\" \\\n -e ANSIBLE_INVENTORY=inventories/control-plane.yaml \\\n metalstack/metal-deployment-base:%s \\\n /bin/bash -ce \\\n \"ansible-playbook obtain_role_requirements.yaml\n ansible-galaxy install -r requirements.yaml\n ansible-playbook deploy_metal_control_plane.yaml\"\n```\n\"\"\"\n\nmarkdownTemplate(t, base_image)","category":"page"},{"location":"installation/deployment/","page":"Installation","title":"Installation","text":"tip: Tip\nIf you are having issues regarding the deployment take a look at the troubleshoot document. Please give feedback such that we can make the deployment of the metal-stack easier for you and for others!","category":"page"},{"location":"installation/deployment/#Providing-Images","page":"Installation","title":"Providing Images","text":"","category":"section"},{"location":"installation/deployment/","page":"Installation","title":"Installation","text":"After the deployment has finished (hopefully without any issues!), you should consider deploying some masterdata entities into your metal-api. For example, you can add your first machine sizes and operating system images. You can do this by further parametrizing the metal role. We will just add an operating system for demonstration purposes. Add the following variable to your inventories/group_vars/control-plane/common.yaml:","category":"page"},{"location":"installation/deployment/","page":"Installation","title":"Installation","text":"metal_api_images:\n- id: firewall-ubuntu-2.0.20201004\n name: Firewall 2 Ubuntu 20201004\n description: Firewall 2 Ubuntu 20201004\n url: http://images.metal-stack.io/metal-os/master/firewall/2.0-ubuntu/20201004/img.tar.lz4\n features:\n - firewall\n- id: ubuntu-20.04.20201004\n name: Ubuntu 20.04 20201004\n description: Ubuntu 20.04 20201004\n url: http://images.metal-stack.io/metal-os/master/ubuntu/20.04/20201004/img.tar.lz4\n features:\n - machine","category":"page"},{"location":"installation/deployment/","page":"Installation","title":"Installation","text":"Then, re-run the deployment to apply your changes. Our playbooks are idempotent.","category":"page"},{"location":"installation/deployment/","page":"Installation","title":"Installation","text":"info: Info\nImage versions should be regularly checked for updates.","category":"page"},{"location":"installation/deployment/#Setting-up-metalctl","page":"Installation","title":"Setting up metalctl","text":"","category":"section"},{"location":"installation/deployment/","page":"Installation","title":"Installation","text":"You can now verify the existence of the operating system images in the metal-api using our CLI client called metalctl. The configuration for metalctl should look like this:","category":"page"},{"location":"installation/deployment/","page":"Installation","title":"Installation","text":"# ~/.metalctl/config.yaml\n---\ncurrent: test\ncontexts:\n test:\n # the metal-api endpoint depends on your dns name specified before\n # you can look up the url to the metal-api via the kubernetes ingress\n # resource with:\n # $ kubectl get ingress -n metal-control-plane\n url: \n # in the future you have to change the HMAC to a strong, random string\n # in order to protect against unauthorized api access\n # the default hmac is \"change-me\"\n hmac: change-me","category":"page"},{"location":"installation/deployment/","page":"Installation","title":"Installation","text":"Issue the following command:","category":"page"},{"location":"installation/deployment/","page":"Installation","title":"Installation","text":"$ metalctl image ls\nID \tNAME \tDESCRIPTION \tFEATURES\tEXPIRATION\tSTATUS\nubuntu-19.10.20200331 \tUbuntu 19.10 20200331 \tUbuntu 19.10 20200331 \tmachine \t89d 23h \tpreview","category":"page"},{"location":"installation/deployment/","page":"Installation","title":"Installation","text":"The basic principles of how the metal control plane can be deployed should now be clear. It is now up to you to move the deployment execution into your CI and add things like certificates for the ingress-controller and NSQ.","category":"page"},{"location":"installation/deployment/#Setting-Up-the-backup-restore-sidecar","page":"Installation","title":"Setting Up the backup-restore-sidecar","text":"","category":"section"},{"location":"installation/deployment/","page":"Installation","title":"Installation","text":"The backup-restore-sidecar can come up very handy when you want to add another layer of security to the metal-stack databases in your Kubernetes cluster. The sidecar takes backups of the metal databases in small time intervals and stores them in a blobstore of a cloud provider. This way your metal-stack setup can even survive the deletion of your Kubernetes control plane cluster (including all volumes getting lost). After re-deploying metal-stack to another Kubernetes clusters, the databases come up with the latest backup data in a matter of seconds.","category":"page"},{"location":"installation/deployment/","page":"Installation","title":"Installation","text":"Checkout the role documentation of the individual databases to find out how to configure the sidecar properly. You can also try out the mechanism from the backup-restore-sidecar repository.","category":"page"},{"location":"installation/deployment/#Auth","page":"Installation","title":"Auth","text":"","category":"section"},{"location":"installation/deployment/","page":"Installation","title":"Installation","text":"metal-stack currently supports two authentication methods:","category":"page"},{"location":"installation/deployment/","page":"Installation","title":"Installation","text":"dex for providing user authentication through OpenID Connect (OIDC)\nHMAC auth, typically used for access by technical users (because we do not have service account tokens at the time being)","category":"page"},{"location":"installation/deployment/","page":"Installation","title":"Installation","text":"In the metal-api, we have three different user roles for authorization:","category":"page"},{"location":"installation/deployment/","page":"Installation","title":"Installation","text":"Admin\nEdit\nView","category":"page"},{"location":"installation/deployment/","page":"Installation","title":"Installation","text":"How the user permissions are used is documented in the technical API docs.","category":"page"},{"location":"installation/deployment/","page":"Installation","title":"Installation","text":"If you decided to set up a dex server, you can parametrize the metal role for using the dex server by defining the variable metal_api_dex_address.","category":"page"},{"location":"installation/deployment/","page":"Installation","title":"Installation","text":"info: Info\nWe also have dedicated controllers for using the dex server for Kubernetes clusters when deploying metal-stack along with the Gardener in your environment. The approach is described in further detail in the section Gardener with metal-stack.","category":"page"},{"location":"installation/deployment/#Bootstrapping-a-Partition","page":"Installation","title":"Bootstrapping a Partition","text":"","category":"section"},{"location":"installation/deployment/#Out-Of-Band-Network","page":"Installation","title":"Out-Of-Band-Network","text":"","category":"section"},{"location":"installation/deployment/","page":"Installation","title":"Installation","text":"To be able to deploy and maintain a metal-stack partition, you need to bootstrap the Out-Of-Band-Network first. Some considerations must be made to fulfill the requirements of our infrastructure, a partition is designed to be:","category":"page"},{"location":"installation/deployment/","page":"Installation","title":"Installation","text":"secure\nfully routable (BGP)\nscalable\nresilient\ndeployable via CI/CD jobs\naccessible from the internet from specific IPs","category":"page"},{"location":"installation/deployment/","page":"Installation","title":"Installation","text":"In order to accomplish this task remotely and in a nearly automatic manner, you have to bootstrap the components in this order:","category":"page"},{"location":"installation/deployment/","page":"Installation","title":"Installation","text":"management firewalls\nmanagement servers\nmanagement spines\nmanagement leaves\nleaves, spines and exits","category":"page"},{"location":"installation/deployment/","page":"Installation","title":"Installation","text":"This document assumes that all cabling is done. Here is a quick overview of the architecture:","category":"page"},{"location":"installation/deployment/","page":"Installation","title":"Installation","text":"(Image: Out-of-Band-Network)","category":"page"},{"location":"installation/deployment/#Management-Firewalls","page":"Installation","title":"Management Firewalls","text":"","category":"section"},{"location":"installation/deployment/","page":"Installation","title":"Installation","text":"As you can see, the management firewalls are the first bastion hosts in a partition to provide access to our infrastructure. There are two of them in each partition to guarantee high availability and load balancing. The very first configuration of these routers has to be done manually to solve the chicken and egg problem that you need the management firewalls in place to deploy the partition. Manually means that we generate a configuration template with ansible that we deploy with copy/paste, and the load, through the machine console. Once the management server has been deployed, we are able to deploy this configuration via CI runner and ansible. For this you need the user and the ssh-key, which is deployed with the configuration file mentioned above. The Edgerouters has to fulfill some requirements including:","category":"page"},{"location":"installation/deployment/","page":"Installation","title":"Installation","text":"provide and restrict access to the Out-Of-Band-Network from the internet with a firewall ruleset\nprovide destination NAT to the management server and its IPMI interface\nprovide Onie Boot and ztp via DHCP options for the management spine\nprovide DHCP management addresses for management spine, management server and ipmi interface of the management server\nHairpin-NAT for the management server to access itself via its puplic IP, needed by the CI runner to delegate CI Jobs.\npropagate a default gateway via BGP","category":"page"},{"location":"installation/deployment/#Management-Servers","page":"Installation","title":"Management Servers","text":"","category":"section"},{"location":"installation/deployment/","page":"Installation","title":"Installation","text":"The second bastion hosts are the management servers. They are the main bootstrapping components of the Out-Of-Band-Network. They also act as jump hosts for all components in a partition. Once they are installed and deployed, we are able to bootstrap all the other components. To bootstrap the management servers, we generate an ISO image which will automatically install an OS and an ansible user with ssh keys. It is preconfigured with a preseed file to allow an unattended OS installation for our needs. This is why we need remote access to the IPMI interface of the management servers: The generated ISO is attached via the virtual media function of the BMC. After that, all we have to do is boot from that virtual CD-ROM and wait for the installation to finish. Deployment jobs (Gitlab-CI) in a partition are delegated to the appropriate management servers, therefore we need a CI runner active on each management server.","category":"page"},{"location":"installation/deployment/","page":"Installation","title":"Installation","text":"After the CI runner has been installed, you can trigger your Playbooks from the the CI. The Ansible-Playbooks have to make sure that these functionalities are present on the management servers:","category":"page"},{"location":"installation/deployment/","page":"Installation","title":"Installation","text":"Prometheus and exporters\nCI runner\nmetal-bmc\nimage-cache\nsimple webserver to provide images\nOnie Boot and ZTP\nDHCP addresses for ipmi interfaces of the workers\nDHCP addresses for switches","category":"page"},{"location":"installation/deployment/#Management-Spines","page":"Installation","title":"Management Spines","text":"","category":"section"},{"location":"installation/deployment/","page":"Installation","title":"Installation","text":"tip: Tip\nIf you are using SONiC switches, you should make use of Zero Touch Provisioning and Onie Boot","category":"page"},{"location":"installation/deployment/","page":"Installation","title":"Installation","text":"The purpose of these switches is to connect the management interfaces of all switches to the management servers. The management spine's own management interface is connected to the management firewall for the bootstrapping of the management spine itself. The management firewall will provide a DHCP address and DHCP options to start SONiC's Zero Touch Provisioning; the images for all switches are downloaded from the management server (nginx container). Each management leaf is connected to both management spines to provide redundant connectivity to both management servers. BGP is used as a routing protocol such that, when a link goes down, an alternate path is used. In the picture above you can see that there are also switch management interfaces connected to the management spine. This has to be done so that we can bootstrap these switches; the management spine relays the DHCP requests from these switches to the management servers so that they are able to Onie Boot and get their ZTP scripts.","category":"page"},{"location":"installation/deployment/#Management-Leaves","page":"Installation","title":"Management Leaves","text":"","category":"section"},{"location":"installation/deployment/","page":"Installation","title":"Installation","text":"All workers have to be connected with their IPMI/BMC interface to the management leaves to get DHCP addresses from the management server. The management leaves are relaying those DHCP requests to the management server which will answer the requests and provide IPs from a given range. The management interfaces of the management leaves also have to be reachable from the management server, and need to get their IP address via DHCP for the bootstrapping process.","category":"page"},{"location":"installation/deployment/","page":"Installation","title":"Installation","text":"In the example setup, these interfaces are connected to an end-of-row-switch which aggregates them and connects them to the management spines with a fiber-optics connection. If you can reach the management spines from the management leaves with copper cables, you do not need the end of row switch. After the initial bootstrapping, the management interfaces of the management leaves continue to be used for access to the switches' command line, and for subsequent OS updates. (update=reset+bootrap+deployment)","category":"page"},{"location":"installation/deployment/#Partition-Deployment","page":"Installation","title":"Partition Deployment","text":"","category":"section"},{"location":"installation/deployment/#Gardener-with-metal-stack","page":"Installation","title":"Gardener with metal-stack","text":"","category":"section"},{"location":"installation/deployment/","page":"Installation","title":"Installation","text":"If you want to deploy metal-stack as a cloud provider for Gardener, you should follow the regular Gardener installation instructions and setup a Gardener cluster first. It's perfectly fine to setup the Gardener cluster in the same cluster that you use for hosting metal-stack.","category":"page"},{"location":"installation/deployment/","page":"Installation","title":"Installation","text":"You can find installation instructions for Gardener on the Gardener website beneath docs. metal-stack is an out-of-tree provider and therefore you will not find example files for metal-stack resources in the Gardener repositories. The following list describes the resources and components that you need to deploy into the Gardener cluster in order to make Gardener work with metal-stack:","category":"page"},{"location":"installation/deployment/","page":"Installation","title":"Installation","text":"warning: Warning\nThe following list assumes you have Gardener installed in a Kubernetes cluster and that you have a basic understanding of how Gardener works. If you need further help with the following steps, you can also come and ask in our Slack channel.","category":"page"},{"location":"installation/deployment/","page":"Installation","title":"Installation","text":"Deploy the validator from the gardener-extension-provider-metal repository to your cluster via Helm\nAdd a cloud profile called metal containing all your machine images, machine types and regions (region names can be chosen freely, the zone names need to match your partition names) together with our metal-stack-specific provider config as defined here\nRegister the gardener-extension-provider-metal controller by deploying the controller-registration into your Gardener cluster, parametrize the embedded chart in the controller registration's values section if necessary (this is the corresponding values file)\nmetal-stack does not provide an own backup storage infrastructure for now. If you want to enable ETCD backups (which you should do because metal-stack also does not have persistent storage out of the box, which makes these backups even more valuable), you should deploy an extension-provider of another cloud provider and configure it to only reconcile the backup buckets (you can reference this backup infrastructure used for the metal shoot in the shoot spec)\nRegister the os-extension-provider-metal controller by deploying the controller-registration into your Gardener cluster, this controller can transform the operating system configuration from Gardener into Ignition user data\nYou need to use the Gardener's networking-calico controller for setting up shoot CNI, you will have to put specific provider configuration into the shoot spec to make it work with metal-stack:\nnetworking:\n type: calico\n # we can peer with the frr within 10.244.0.0/16, which we do with the metallb\n # the networks for the shoot need to be disjunct with the networks of the seed, otherwise the VPN connection will not work properly\n # the seeds are typically deployed with podCIDR 10.244.128.0/18 and serviceCIDR 10.244.192.0/18\n # the shoots are typically deployed with podCIDR 10.244.0.0/18 and serviceCIDR 10.244.64.0/18\n pods: 10.244.0.0/18\n services: 10.244.64.0/18\n providerConfig:\n apiVersion: calico.networking.extensions.gardener.cloud/v1alpha1\n kind: NetworkConfig\n backend: vxlan\n ipv4:\n pool: vxlan\n mode: Always\n autoDetectionMethod: interface=lo\n typha:\n enabled: false\nFor your seed cluster you will need to provide the provider secret for metal-stack containing the key metalAPIHMac, which is the API HMAC to grant editor access to the metal-api\nCheckout our current provider configuration for infrastructure and control-plane before deploying your shoot","category":"page"},{"location":"installation/deployment/","page":"Installation","title":"Installation","text":"tip: Tip\nWe are officially supported by Gardener dashboard. The dashboard can also help you setting up some of the resources mentioned above.","category":"page"},{"location":"external/metalctl/docs/metalctl_switch_list/#metalctl-switch-list","page":"metalctl switch list","title":"metalctl switch list","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_switch_list/","page":"metalctl switch list","title":"metalctl switch list","text":"list all switches","category":"page"},{"location":"external/metalctl/docs/metalctl_switch_list/","page":"metalctl switch list","title":"metalctl switch list","text":"metalctl switch list [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_switch_list/#Options","page":"metalctl switch list","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_switch_list/","page":"metalctl switch list","title":"metalctl switch list","text":" -h, --help help for list\n --id string ID of the switch.\n --name string Name of the switch.\n --os-vendor string OS vendor of this switch.\n --os-version string OS version of this switch.\n --partition string Partition of this switch.\n --rack string Rack of this switch.\n --sort-by strings sort by (comma separated) column(s), sort direction can be changed by appending :asc or :desc behind the column identifier. possible values: description|id|name","category":"page"},{"location":"external/metalctl/docs/metalctl_switch_list/#Options-inherited-from-parent-commands","page":"metalctl switch list","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_switch_list/","page":"metalctl switch list","title":"metalctl switch list","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_switch_list/#SEE-ALSO","page":"metalctl switch list","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_switch_list/","page":"metalctl switch list","title":"metalctl switch list","text":"metalctl switch\t - manage switch entities","category":"page"},{"location":"external/metalctl/docs/metalctl_network_ip_apply/#metalctl-network-ip-apply","page":"metalctl network ip apply","title":"metalctl network ip apply","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_network_ip_apply/","page":"metalctl network ip apply","title":"metalctl network ip apply","text":"applies one or more ips from a given file","category":"page"},{"location":"external/metalctl/docs/metalctl_network_ip_apply/","page":"metalctl network ip apply","title":"metalctl network ip apply","text":"metalctl network ip apply [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_network_ip_apply/#Options","page":"metalctl network ip apply","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_network_ip_apply/","page":"metalctl network ip apply","title":"metalctl network ip apply","text":" --bulk-output when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.\n -f, --file string filename of the create or update request in yaml format, or - for stdin.\n \n Example:\n $ metalctl ip describe ip-1 -o yaml > ip.yaml\n $ vi ip.yaml\n $ # either via stdin\n $ cat ip.yaml | metalctl ip apply -f -\n $ # or via file\n $ metalctl ip apply -f ip.yaml\n \n the file can also contain multiple documents and perform a bulk operation.\n \t\n -h, --help help for apply\n --skip-security-prompts skips security prompt for bulk operations\n --timestamps when used with --file (bulk operation): prints timestamps in-between the operations","category":"page"},{"location":"external/metalctl/docs/metalctl_network_ip_apply/#Options-inherited-from-parent-commands","page":"metalctl network ip apply","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_network_ip_apply/","page":"metalctl network ip apply","title":"metalctl network ip apply","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_network_ip_apply/#SEE-ALSO","page":"metalctl network ip apply","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_network_ip_apply/","page":"metalctl network ip apply","title":"metalctl network ip apply","text":"metalctl network ip\t - manage ip entities","category":"page"},{"location":"external/metalctl/docs/metalctl_image_create/#metalctl-image-create","page":"metalctl image create","title":"metalctl image create","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_image_create/","page":"metalctl image create","title":"metalctl image create","text":"creates the image","category":"page"},{"location":"external/metalctl/docs/metalctl_image_create/","page":"metalctl image create","title":"metalctl image create","text":"metalctl image create [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_image_create/#Options","page":"metalctl image create","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_image_create/","page":"metalctl image create","title":"metalctl image create","text":" --bulk-output when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.\n -d, --description string Description of the image.\n --features strings features of the image, can be one of machine|firewall\n -f, --file string filename of the create or update request in yaml format, or - for stdin.\n \n Example:\n $ metalctl image describe image-1 -o yaml > image.yaml\n $ vi image.yaml\n $ # either via stdin\n $ cat image.yaml | metalctl image create -f -\n $ # or via file\n $ metalctl image create -f image.yaml\n \n the file can also contain multiple documents and perform a bulk operation.\n \t\n -h, --help help for create\n --id string ID of the image.\n -n, --name string Name of the image.\n --skip-security-prompts skips security prompt for bulk operations\n --timestamps when used with --file (bulk operation): prints timestamps in-between the operations\n --url string url of the image.","category":"page"},{"location":"external/metalctl/docs/metalctl_image_create/#Options-inherited-from-parent-commands","page":"metalctl image create","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_image_create/","page":"metalctl image create","title":"metalctl image create","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_image_create/#SEE-ALSO","page":"metalctl image create","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_image_create/","page":"metalctl image create","title":"metalctl image create","text":"metalctl image\t - manage image entities","category":"page"},{"location":"#Welcome-to-the-metal-stack-docs!","page":"Introduction","title":"Welcome to the metal-stack docs!","text":"","category":"section"},{"location":"","page":"Introduction","title":"Introduction","text":"metal-stack is an open source software that provides an API for provisioning and managing physical servers in the data center. To categorize this product, we use the terms Metal-as-a-Service (MaaS) or bare metal cloud.","category":"page"},{"location":"","page":"Introduction","title":"Introduction","text":"From the perspective of a user, the metal-stack does not feel any different from working with a conventional cloud provider. Users manage their resources (machines, networks and ip addresses, etc.) by themselves, which effectively turns your data center into an elastic cloud infrastructure.","category":"page"},{"location":"","page":"Introduction","title":"Introduction","text":"The major difference to other cloud providers is that compute power and data reside in your own data center.","category":"page"},{"location":"","page":"Introduction","title":"Introduction","text":"Pages = [\"index.md\"]\nDepth = 5","category":"page"},{"location":"#Why-metal-stack?","page":"Introduction","title":"Why metal-stack?","text":"","category":"section"},{"location":"","page":"Introduction","title":"Introduction","text":"Before we started with our mission to implement the metal-stack, we decided on a couple of key characteristics and constraints that we think are unique in the domain (otherwise we would definitely have chosen an existing solution).","category":"page"},{"location":"","page":"Introduction","title":"Introduction","text":"We hope that the following properties appeal to you as well.","category":"page"},{"location":"#On-Premise","page":"Introduction","title":"On-Premise","text":"","category":"section"},{"location":"","page":"Introduction","title":"Introduction","text":"Running on-premise gives you data sovereignty and usually a better price / performance ratio than with hyperscalers — especially the larger you grow your environment. Another benefit of running on-premise is an easier connectivity to existing company networks.","category":"page"},{"location":"#Fast-Provisioning","page":"Introduction","title":"Fast Provisioning","text":"","category":"section"},{"location":"","page":"Introduction","title":"Introduction","text":"Provisioning bare metal machines should not feel much different from virtual machines. metal-stack is capable of provisioning servers in less than a minute. The underlying network topology is based on BGP and allows announcing new routes to your host machines in a matter of seconds.","category":"page"},{"location":"#No-Ops","page":"Introduction","title":"No-Ops","text":"","category":"section"},{"location":"","page":"Introduction","title":"Introduction","text":"Part of the metal-stack runs on dedicated switches in your data center. This way, it is possible to automate server inventorization, permanently reconcile network configuration and automatically manage machine lifecycles. Manual configuration is neither required nor wanted.","category":"page"},{"location":"#Security","page":"Introduction","title":"Security","text":"","category":"section"},{"location":"","page":"Introduction","title":"Introduction","text":"Our networking approach was designed for highest standards on security. Also, we enforce firewalling on dedicated tenant firewalls before users can establish connections to other networks than their private tenant network. API authentication and authorization is done with the help of OIDC.","category":"page"},{"location":"#API-driven","page":"Introduction","title":"API driven","text":"","category":"section"},{"location":"","page":"Introduction","title":"Introduction","text":"The development of metal-stack is strictly API driven and offers self-service to end-users. This approach delivers the highest possible degree of automation, maintainability and performance.","category":"page"},{"location":"#Ready-for-Kubernetes","page":"Introduction","title":"Ready for Kubernetes","text":"","category":"section"},{"location":"","page":"Introduction","title":"Introduction","text":"Not only does the metal-stack run smoothly on Kubernetes (K8s). The major intent of metal-stack has always been to build a scalable machine infrastructure for Kubernetes as a Service (KaaS). In partnership with the open-source project Gardener, we can provision Kubernetes clusters on metal-stack at scale.","category":"page"},{"location":"","page":"Introduction","title":"Introduction","text":"From the perspective of the Gardener, the metal-stack is just another cloud provider. The time savings compared to providing machines and Kubernetes by hand are significant. We actually want to be able to compete with offers of public cloud providers, especially regarding speed and usability.","category":"page"},{"location":"","page":"Introduction","title":"Introduction","text":"Of course, you can use metal-stack only for machine provisioning as well and just put something else on top of your metal infrastructure.","category":"page"},{"location":"#Open-Source","page":"Introduction","title":"Open Source","text":"","category":"section"},{"location":"","page":"Introduction","title":"Introduction","text":"The metal-stack is open source and free of constraints regarding vendors and third-party products. The stack is completely built on open source products. We have a community actively working on the metal-stack, which can assist you delivering all reasonable features you are gonna need.","category":"page"},{"location":"#Why-Bare-Metal?","page":"Introduction","title":"Why Bare Metal?","text":"","category":"section"},{"location":"","page":"Introduction","title":"Introduction","text":"Bare metal has several advantages over virtual environments and overcomes several drawbacks of virtual machines. We also listed drawbacks of the bare metal approach. Bare in mind though that it is still possible to virtualize on bare metal environments when you have your stack up and running.","category":"page"},{"location":"#Virtual-Environment-Drawbacks","page":"Introduction","title":"Virtual Environment Drawbacks","text":"","category":"section"},{"location":"","page":"Introduction","title":"Introduction","text":"Spectre and Meltdown can only be mitigated with a \"cluster per tenant\" approach\nMissing isolation of multi-tenant change impacts\nLicensing restrictions\nNoisy-neighbors","category":"page"},{"location":"#Bare-Metal-Advantages","page":"Introduction","title":"Bare Metal Advantages","text":"","category":"section"},{"location":"","page":"Introduction","title":"Introduction","text":"Guaranteed and fastest possible performance (especially disk i/o)\nReduced stack depth (Host / VM / Application vs. Host / Container)\nReduced attack surface\nLower costs, higher performance\nNo VM live-migrations\nBigger hardware configurations possible (hypervisors have restrictions, e.g. it is not possible to assign all CPUs to a single VM)","category":"page"},{"location":"#Bare-Metal-Drawbacks","page":"Introduction","title":"Bare Metal Drawbacks","text":"","category":"section"},{"location":"","page":"Introduction","title":"Introduction","text":"Hardware defects have direct impact (should be considered by design) and can not be mitigated by live-migration as in virtual environments\nCapacity planning is more difficult (no resource overbooking possible)","category":"page"},{"location":"development/proposals/MEP2/README/#Two-Factor-Authentication","page":"Two Factor Authentication","title":"Two Factor Authentication","text":"","category":"section"},{"location":"development/proposals/MEP14/README/#Independence-from-external-sources","page":"Independence from external sources","title":"Independence from external sources","text":"","category":"section"},{"location":"development/proposals/MEP14/README/","page":"Independence from external sources","title":"Independence from external sources","text":"In certain situations some customers may need to operate and create machines without making use of external services like DNS or NTP through the internet. To make this possible, all metal-stack components reaching external services need to be configurable with custom endpoints.","category":"page"},{"location":"development/proposals/MEP14/README/","page":"Independence from external sources","title":"Independence from external sources","text":"So far, the following components have been identified as requiring changes:","category":"page"},{"location":"development/proposals/MEP14/README/","page":"Independence from external sources","title":"Independence from external sources","text":"pixiecore\nmetal-hammer\nmetal-images","category":"page"},{"location":"development/proposals/MEP14/README/","page":"Independence from external sources","title":"Independence from external sources","text":"More components are likely to be added to the list during processing.","category":"page"},{"location":"development/proposals/MEP14/README/#pixiecore","page":"Independence from external sources","title":"pixiecore","text":"","category":"section"},{"location":"development/proposals/MEP14/README/","page":"Independence from external sources","title":"Independence from external sources","text":"A NTP server endpoint need to be configured on the pixiecore. This can be achieved by providing it through environment variables on start up.","category":"page"},{"location":"development/proposals/MEP14/README/#metal-hammer","page":"Independence from external sources","title":"metal-hammer","text":"","category":"section"},{"location":"development/proposals/MEP14/README/","page":"Independence from external sources","title":"Independence from external sources","text":"If using a self-deployed NTP server, also the metal-hammer need to be configured with it. For backward compatibility, default values from pool.ntp.org and time.google.com are used.","category":"page"},{"location":"development/proposals/MEP14/README/#metal-images","page":"Independence from external sources","title":"metal-images","text":"","category":"section"},{"location":"development/proposals/MEP14/README/","page":"Independence from external sources","title":"Independence from external sources","text":"Configurations for the metal-images are different for machines and firewalls.","category":"page"},{"location":"development/proposals/MEP14/README/","page":"Independence from external sources","title":"Independence from external sources","text":"The implementation of this MEP will make metal-stack possible to create and maintain machines without requiring an internet connection.","category":"page"},{"location":"apidocs/apidocs/#API-Documentation","page":"API Documentation","title":"API Documentation","text":"","category":"section"},{"location":"apidocs/apidocs/","page":"API Documentation","title":"API Documentation","text":"In this section you will find links to the API documentation of metal-stack components.","category":"page"},{"location":"apidocs/apidocs/","page":"API Documentation","title":"API Documentation","text":"using Docs\n\nmetal_api_image = releaseVector()[\"docker-images\"][\"metal-stack\"][\"control-plane\"][\"metal-api\"][\"tag\"]\ncontent = redocTemplate(\"metal-api\", string(\"https://raw.githubusercontent.com/metal-stack/metal-api/\", metal_api_image, \"/spec/metal-api.json\"))\n\nf = open(string(@__DIR__, \"/metal-api/index.html\"), \"w\")\nwrite(f, content)\nclose(f);\n\nnothing","category":"page"},{"location":"apidocs/apidocs/","page":"API Documentation","title":"API Documentation","text":"metal-api","category":"page"},{"location":"external/metalctl/docs/metalctl_network_delete/#metalctl-network-delete","page":"metalctl network delete","title":"metalctl network delete","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_network_delete/","page":"metalctl network delete","title":"metalctl network delete","text":"deletes the network","category":"page"},{"location":"external/metalctl/docs/metalctl_network_delete/","page":"metalctl network delete","title":"metalctl network delete","text":"metalctl network delete [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_network_delete/#Options","page":"metalctl network delete","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_network_delete/","page":"metalctl network delete","title":"metalctl network delete","text":" --bulk-output when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.\n -f, --file string filename of the create or update request in yaml format, or - for stdin.\n \n Example:\n $ metalctl network describe network-1 -o yaml > network.yaml\n $ vi network.yaml\n $ # either via stdin\n $ cat network.yaml | metalctl network delete -f -\n $ # or via file\n $ metalctl network delete -f network.yaml\n \n the file can also contain multiple documents and perform a bulk operation.\n \t\n -h, --help help for delete\n --skip-security-prompts skips security prompt for bulk operations\n --timestamps when used with --file (bulk operation): prints timestamps in-between the operations","category":"page"},{"location":"external/metalctl/docs/metalctl_network_delete/#Options-inherited-from-parent-commands","page":"metalctl network delete","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_network_delete/","page":"metalctl network delete","title":"metalctl network delete","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_network_delete/#SEE-ALSO","page":"metalctl network delete","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_network_delete/","page":"metalctl network delete","title":"metalctl network delete","text":"metalctl network\t - manage network entities","category":"page"},{"location":"external/metalctl/docs/metalctl_switch_port_down/#metalctl-switch-port-down","page":"metalctl switch port down","title":"metalctl switch port down","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_switch_port_down/","page":"metalctl switch port down","title":"metalctl switch port down","text":"sets the given switch port state down","category":"page"},{"location":"external/metalctl/docs/metalctl_switch_port_down/#Synopsis","page":"metalctl switch port down","title":"Synopsis","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_switch_port_down/","page":"metalctl switch port down","title":"metalctl switch port down","text":"sets the port status to DOWN so the connected machine will not be able to connect to the switch.","category":"page"},{"location":"external/metalctl/docs/metalctl_switch_port_down/","page":"metalctl switch port down","title":"metalctl switch port down","text":"metalctl switch port down [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_switch_port_down/#Options","page":"metalctl switch port down","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_switch_port_down/","page":"metalctl switch port down","title":"metalctl switch port down","text":" -h, --help help for down","category":"page"},{"location":"external/metalctl/docs/metalctl_switch_port_down/#Options-inherited-from-parent-commands","page":"metalctl switch port down","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_switch_port_down/","page":"metalctl switch port down","title":"metalctl switch port down","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --port string the port to be changed.\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_switch_port_down/#SEE-ALSO","page":"metalctl switch port down","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_switch_port_down/","page":"metalctl switch port down","title":"metalctl switch port down","text":"metalctl switch port\t - sets the given switch port state up or down","category":"page"},{"location":"external/metalctl/docs/metalctl_switch_ssh/#metalctl-switch-ssh","page":"metalctl switch ssh","title":"metalctl switch ssh","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_switch_ssh/","page":"metalctl switch ssh","title":"metalctl switch ssh","text":"connect to the switch via ssh","category":"page"},{"location":"external/metalctl/docs/metalctl_switch_ssh/#Synopsis","page":"metalctl switch ssh","title":"Synopsis","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_switch_ssh/","page":"metalctl switch ssh","title":"metalctl switch ssh","text":"this requires a network connectivity to the management ip address of the switch.","category":"page"},{"location":"external/metalctl/docs/metalctl_switch_ssh/","page":"metalctl switch ssh","title":"metalctl switch ssh","text":"metalctl switch ssh [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_switch_ssh/#Options","page":"metalctl switch ssh","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_switch_ssh/","page":"metalctl switch ssh","title":"metalctl switch ssh","text":" -h, --help help for ssh","category":"page"},{"location":"external/metalctl/docs/metalctl_switch_ssh/#Options-inherited-from-parent-commands","page":"metalctl switch ssh","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_switch_ssh/","page":"metalctl switch ssh","title":"metalctl switch ssh","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_switch_ssh/#SEE-ALSO","page":"metalctl switch ssh","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_switch_ssh/","page":"metalctl switch ssh","title":"metalctl switch ssh","text":"metalctl switch\t - manage switch entities","category":"page"},{"location":"external/metalctl/docs/metalctl_firmware_upload_bmc/#metalctl-firmware-upload-bmc","page":"metalctl firmware upload bmc","title":"metalctl firmware upload bmc","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_firmware_upload_bmc/","page":"metalctl firmware upload bmc","title":"metalctl firmware upload bmc","text":"upload a BMC firmware","category":"page"},{"location":"external/metalctl/docs/metalctl_firmware_upload_bmc/#Synopsis","page":"metalctl firmware upload bmc","title":"Synopsis","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_firmware_upload_bmc/","page":"metalctl firmware upload bmc","title":"metalctl firmware upload bmc","text":"the given BMC firmware file will be uploaded and tagged as given revision.","category":"page"},{"location":"external/metalctl/docs/metalctl_firmware_upload_bmc/","page":"metalctl firmware upload bmc","title":"metalctl firmware upload bmc","text":"metalctl firmware upload bmc [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_firmware_upload_bmc/#Options","page":"metalctl firmware upload bmc","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_firmware_upload_bmc/","page":"metalctl firmware upload bmc","title":"metalctl firmware upload bmc","text":" --board string the board type (required)\n -h, --help help for bmc\n --revision string the BMC firmware revision (required)\n --vendor string the vendor (required)","category":"page"},{"location":"external/metalctl/docs/metalctl_firmware_upload_bmc/#Options-inherited-from-parent-commands","page":"metalctl firmware upload bmc","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_firmware_upload_bmc/","page":"metalctl firmware upload bmc","title":"metalctl firmware upload bmc","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_firmware_upload_bmc/#SEE-ALSO","page":"metalctl firmware upload bmc","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_firmware_upload_bmc/","page":"metalctl firmware upload bmc","title":"metalctl firmware upload bmc","text":"metalctl firmware upload\t - upload a firmware","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_list/#metalctl-machine-list","page":"metalctl machine list","title":"metalctl machine list","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_list/","page":"metalctl machine list","title":"metalctl machine list","text":"list all machines","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_list/#Synopsis","page":"metalctl machine list","title":"Synopsis","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_list/","page":"metalctl machine list","title":"metalctl machine list","text":"list all machines","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_list/","page":"metalctl machine list","title":"metalctl machine list","text":"Meaning of the emojis:","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_list/","page":"metalctl machine list","title":"metalctl machine list","text":"🚧 Machine is reserved. Reserved machines are not considered for random allocation until the reservation flag is removed. 🔒 Machine is locked. Locked machines can not be deleted until the lock is removed. 💀 Machine is dead. The metal-api does not receive any events from this machine. ❗ Machine has a last event error. The machine has recently encountered an error during the provisioning lifecycle. ❓ Machine is in unknown condition. The metal-api does not receive phoned home events anymore or has never booted successfully. ⭕ Machine is in a provisioning crash loop. Flag can be reset through an API-triggered reboot or when the machine reaches the phoned home state. 🚑 Machine reclaim has failed. The machine was deleted but it is not going back into the available machine pool. 🛡 Machine is connected to our VPN, ssh access only possible via this VPN.","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_list/","page":"metalctl machine list","title":"metalctl machine list","text":"metalctl machine list [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_list/#Options","page":"metalctl machine list","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_list/","page":"metalctl machine list","title":"metalctl machine list","text":" --bmc-address string bmc ipmi address (needs to include port) to filter [optional]\n --bmc-mac string bmc mac address to filter [optional]\n --board-part-number string fru board part number to filter [optional]\n -h, --help help for list\n --hostname string allocation hostname to filter [optional]\n --id string ID to filter [optional]\n --image string allocation image to filter [optional]\n --last-event-error-threshold duration the duration up to how long in the past a machine last event error will be counted as an issue [optional] (default 1h0m0s)\n --mac string mac to filter [optional]\n --manufacturer string fru manufacturer to filter [optional]\n --name string allocation name to filter [optional]\n --network-destination-prefixes string network destination prefixes to filter [optional]\n --network-ids string network ids to filter [optional]\n --network-ips string network ips to filter [optional]\n --partition string partition to filter [optional]\n --product-part-number string fru product part number to filter [optional]\n --product-serial string fru product serial to filter [optional]\n --project string allocation project to filter [optional]\n --rack string rack to filter [optional]\n --role string allocation role to filter [optional]\n --size string size to filter [optional]\n --sort-by strings sort by (comma separated) column(s), sort direction can be changed by appending :asc or :desc behind the column identifier. possible values: age|event|id|image|liveliness|partition|project|rack|size|when\n --state string state to filter [optional]\n --tags strings tags to filter, use it like: --tags \"tag1,tag2\" or --tags \"tag3\".","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_list/#Options-inherited-from-parent-commands","page":"metalctl machine list","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_list/","page":"metalctl machine list","title":"metalctl machine list","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_list/#SEE-ALSO","page":"metalctl machine list","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_list/","page":"metalctl machine list","title":"metalctl machine list","text":"metalctl machine\t - manage machine entities","category":"page"},{"location":"external/metalctl/docs/metalctl_firmware_list/#metalctl-firmware-list","page":"metalctl firmware list","title":"metalctl firmware list","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_firmware_list/","page":"metalctl firmware list","title":"metalctl firmware list","text":"list firmwares","category":"page"},{"location":"external/metalctl/docs/metalctl_firmware_list/#Synopsis","page":"metalctl firmware list","title":"Synopsis","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_firmware_list/","page":"metalctl firmware list","title":"metalctl firmware list","text":"lists all available firmwares matching the given criteria.","category":"page"},{"location":"external/metalctl/docs/metalctl_firmware_list/","page":"metalctl firmware list","title":"metalctl firmware list","text":"metalctl firmware list [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_firmware_list/#Options","page":"metalctl firmware list","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_firmware_list/","page":"metalctl firmware list","title":"metalctl firmware list","text":" --board string the board type\n -h, --help help for list\n --kind string the firmware kind [bmc|bios]\n --machineid string the machine id (ignores vendor and board flags)\n --vendor string the vendor","category":"page"},{"location":"external/metalctl/docs/metalctl_firmware_list/#Options-inherited-from-parent-commands","page":"metalctl firmware list","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_firmware_list/","page":"metalctl firmware list","title":"metalctl firmware list","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_firmware_list/#SEE-ALSO","page":"metalctl firmware list","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_firmware_list/","page":"metalctl firmware list","title":"metalctl firmware list","text":"metalctl firmware\t - manage firmwares","category":"page"},{"location":"external/metalctl/docs/metalctl_vpn/#metalctl-vpn","page":"metalctl vpn","title":"metalctl vpn","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_vpn/","page":"metalctl vpn","title":"metalctl vpn","text":"access VPN","category":"page"},{"location":"external/metalctl/docs/metalctl_vpn/#Synopsis","page":"metalctl vpn","title":"Synopsis","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_vpn/","page":"metalctl vpn","title":"metalctl vpn","text":"access VPN","category":"page"},{"location":"external/metalctl/docs/metalctl_vpn/#Options","page":"metalctl vpn","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_vpn/","page":"metalctl vpn","title":"metalctl vpn","text":" -h, --help help for vpn","category":"page"},{"location":"external/metalctl/docs/metalctl_vpn/#Options-inherited-from-parent-commands","page":"metalctl vpn","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_vpn/","page":"metalctl vpn","title":"metalctl vpn","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_vpn/#SEE-ALSO","page":"metalctl vpn","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_vpn/","page":"metalctl vpn","title":"metalctl vpn","text":"metalctl\t - a cli to manage entities in the metal-stack api\nmetalctl vpn key\t - create an auth key","category":"page"},{"location":"external/metalctl/docs/metalctl_firmware_upload_bios/#metalctl-firmware-upload-bios","page":"metalctl firmware upload bios","title":"metalctl firmware upload bios","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_firmware_upload_bios/","page":"metalctl firmware upload bios","title":"metalctl firmware upload bios","text":"upload a BIOS firmware","category":"page"},{"location":"external/metalctl/docs/metalctl_firmware_upload_bios/#Synopsis","page":"metalctl firmware upload bios","title":"Synopsis","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_firmware_upload_bios/","page":"metalctl firmware upload bios","title":"metalctl firmware upload bios","text":"the given BIOS firmware file will be uploaded and tagged as given revision.","category":"page"},{"location":"external/metalctl/docs/metalctl_firmware_upload_bios/","page":"metalctl firmware upload bios","title":"metalctl firmware upload bios","text":"metalctl firmware upload bios [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_firmware_upload_bios/#Options","page":"metalctl firmware upload bios","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_firmware_upload_bios/","page":"metalctl firmware upload bios","title":"metalctl firmware upload bios","text":" --board string the board type (required)\n -h, --help help for bios\n --revision string the BIOS firmware revision (required)\n --vendor string the vendor (required)","category":"page"},{"location":"external/metalctl/docs/metalctl_firmware_upload_bios/#Options-inherited-from-parent-commands","page":"metalctl firmware upload bios","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_firmware_upload_bios/","page":"metalctl firmware upload bios","title":"metalctl firmware upload bios","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_firmware_upload_bios/#SEE-ALSO","page":"metalctl firmware upload bios","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_firmware_upload_bios/","page":"metalctl firmware upload bios","title":"metalctl firmware upload bios","text":"metalctl firmware upload\t - upload a firmware","category":"page"},{"location":"external/metalctl/docs/metalctl_size_suggest/#metalctl-size-suggest","page":"metalctl size suggest","title":"metalctl size suggest","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_suggest/","page":"metalctl size suggest","title":"metalctl size suggest","text":"suggest size from a given machine id","category":"page"},{"location":"external/metalctl/docs/metalctl_size_suggest/","page":"metalctl size suggest","title":"metalctl size suggest","text":"metalctl size suggest [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_size_suggest/#Options","page":"metalctl size suggest","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_suggest/","page":"metalctl size suggest","title":"metalctl size suggest","text":" --description string The description of the suggested size (default \"a suggested size\")\n -h, --help help for suggest\n --labels strings labels to add to the size\n --machine-id string Machine id used to create the size suggestion. [required]\n --name string The name of the suggested size (default \"suggested-size\")","category":"page"},{"location":"external/metalctl/docs/metalctl_size_suggest/#Options-inherited-from-parent-commands","page":"metalctl size suggest","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_suggest/","page":"metalctl size suggest","title":"metalctl size suggest","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_size_suggest/#SEE-ALSO","page":"metalctl size suggest","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_suggest/","page":"metalctl size suggest","title":"metalctl size suggest","text":"metalctl size\t - manage size entities","category":"page"},{"location":"external/csi-driver-lvm/README/#csi-driver-lvm","page":"csi-driver-lvm","title":"csi-driver-lvm","text":"","category":"section"},{"location":"external/csi-driver-lvm/README/","page":"csi-driver-lvm","title":"csi-driver-lvm","text":"CSI DRIVER LVM utilizes local storage of Kubernetes nodes to provide persistent storage for pods.","category":"page"},{"location":"external/csi-driver-lvm/README/","page":"csi-driver-lvm","title":"csi-driver-lvm","text":"It automatically creates hostPath based persistent volumes on the nodes.","category":"page"},{"location":"external/csi-driver-lvm/README/","page":"csi-driver-lvm","title":"csi-driver-lvm","text":"Underneath it creates a LVM logical volume on the local disks. A comma-separated list of grok pattern, which disks to use must be specified.","category":"page"},{"location":"external/csi-driver-lvm/README/","page":"csi-driver-lvm","title":"csi-driver-lvm","text":"This CSI driver is derived from csi-driver-host-path and csi-lvm","category":"page"},{"location":"external/csi-driver-lvm/README/#Currently-it-can-create,-delete,-mount,-unmount-and-resize-block-and-filesystem-volumes-via-lvm","page":"csi-driver-lvm","title":"Currently it can create, delete, mount, unmount and resize block and filesystem volumes via lvm","text":"","category":"section"},{"location":"external/csi-driver-lvm/README/","page":"csi-driver-lvm","title":"csi-driver-lvm","text":"For the special case of block volumes, the filesystem-expansion has to be performed by the app using the block device","category":"page"},{"location":"external/csi-driver-lvm/README/#Installation","page":"csi-driver-lvm","title":"Installation","text":"","category":"section"},{"location":"external/csi-driver-lvm/README/","page":"csi-driver-lvm","title":"csi-driver-lvm","text":"Helm charts for installation are located in a separate repository called helm-charts. If you would like to contribute to the helm chart, please raise an issue or pull request there.","category":"page"},{"location":"external/csi-driver-lvm/README/","page":"csi-driver-lvm","title":"csi-driver-lvm","text":"You have to set the devicePattern for your hardware to specify which disks should be used to create the volume group.","category":"page"},{"location":"external/csi-driver-lvm/README/","page":"csi-driver-lvm","title":"csi-driver-lvm","text":"helm install --repo https://helm.metal-stack.io mytest csi-driver-lvm --set lvm.devicePattern='/dev/nvme[0-9]n[0-9]'","category":"page"},{"location":"external/csi-driver-lvm/README/","page":"csi-driver-lvm","title":"csi-driver-lvm","text":"Now you can use one of following storageClasses:","category":"page"},{"location":"external/csi-driver-lvm/README/","page":"csi-driver-lvm","title":"csi-driver-lvm","text":"csi-driver-lvm-linear\ncsi-driver-lvm-mirror\ncsi-driver-lvm-striped","category":"page"},{"location":"external/csi-driver-lvm/README/","page":"csi-driver-lvm","title":"csi-driver-lvm","text":"To get the previous old and now deprecated csi-lvm-sc-linear, ... storageclasses, set helm-chart value compat03x=true.","category":"page"},{"location":"external/csi-driver-lvm/README/#Migration","page":"csi-driver-lvm","title":"Migration","text":"","category":"section"},{"location":"external/csi-driver-lvm/README/","page":"csi-driver-lvm","title":"csi-driver-lvm","text":"If you want to migrate your existing PVC to / from csi-driver-lvm, you can use korb.","category":"page"},{"location":"external/csi-driver-lvm/README/#Todo","page":"csi-driver-lvm","title":"Todo","text":"","category":"section"},{"location":"external/csi-driver-lvm/README/","page":"csi-driver-lvm","title":"csi-driver-lvm","text":"implement CreateSnapshot(), ListSnapshots(), DeleteSnapshot()","category":"page"},{"location":"external/csi-driver-lvm/README/#Test","page":"csi-driver-lvm","title":"Test","text":"","category":"section"},{"location":"external/csi-driver-lvm/README/","page":"csi-driver-lvm","title":"csi-driver-lvm","text":"kubectl apply -f examples/csi-pvc-raw.yaml\nkubectl apply -f examples/csi-pod-raw.yaml\n\n\nkubectl apply -f examples/csi-pvc.yaml\nkubectl apply -f examples/csi-app.yaml\n\nkubectl delete -f examples/csi-pod-raw.yaml\nkubectl delete -f examples/csi-pvc-raw.yaml\n\nkubectl delete -f examples/csi-app.yaml\nkubectl delete -f examples/csi-pvc.yaml","category":"page"},{"location":"external/csi-driver-lvm/README/#Development","page":"csi-driver-lvm","title":"Development","text":"","category":"section"},{"location":"external/csi-driver-lvm/README/","page":"csi-driver-lvm","title":"csi-driver-lvm","text":"In order to run the integration tests locally, you need to create to loop devices on your host machine. Make sure the loop device mount paths are not used on your system (default path is /dev/loop10{0,1}).","category":"page"},{"location":"external/csi-driver-lvm/README/","page":"csi-driver-lvm","title":"csi-driver-lvm","text":"You can create these loop devices like this:","category":"page"},{"location":"external/csi-driver-lvm/README/","page":"csi-driver-lvm","title":"csi-driver-lvm","text":"for i in 100 101; do fallocate -l 1G loop${i}.img ; sudo losetup /dev/loop${i} loop${i}.img; done\nsudo losetup -a\n# use this for recreation or cleanup\n# for i in 100 101; do sudo losetup -d /dev/loop${i}; rm -f loop${i}.img; done","category":"page"},{"location":"external/csi-driver-lvm/README/","page":"csi-driver-lvm","title":"csi-driver-lvm","text":"You can then run the tests against a kind cluster, running:","category":"page"},{"location":"external/csi-driver-lvm/README/","page":"csi-driver-lvm","title":"csi-driver-lvm","text":"make test","category":"page"},{"location":"external/csi-driver-lvm/README/","page":"csi-driver-lvm","title":"csi-driver-lvm","text":"To recreate or cleanup the kind cluster:","category":"page"},{"location":"external/csi-driver-lvm/README/","page":"csi-driver-lvm","title":"csi-driver-lvm","text":"make test-cleanup","category":"page"},{"location":"external/csi-driver-lvm/README/#Page-Tree","page":"csi-driver-lvm","title":"Page Tree","text":"","category":"section"},{"location":"external/csi-driver-lvm/README/","page":"csi-driver-lvm","title":"csi-driver-lvm","text":"Pages = vcat([[joinpath(root, file)[length(@__DIR__)+2:end] for file in files] for (root, dirs, files) in walkdir(@__DIR__)]...)","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_apply/#metalctl-machine-apply","page":"metalctl machine apply","title":"metalctl machine apply","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_apply/","page":"metalctl machine apply","title":"metalctl machine apply","text":"applies one or more machines from a given file","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_apply/","page":"metalctl machine apply","title":"metalctl machine apply","text":"metalctl machine apply [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_apply/#Options","page":"metalctl machine apply","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_apply/","page":"metalctl machine apply","title":"metalctl machine apply","text":" --bulk-output when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.\n -f, --file string filename of the create or update request in yaml format, or - for stdin.\n \n Example:\n $ metalctl machine describe machine-1 -o yaml > machine.yaml\n $ vi machine.yaml\n $ # either via stdin\n $ cat machine.yaml | metalctl machine apply -f -\n $ # or via file\n $ metalctl machine apply -f machine.yaml\n \n the file can also contain multiple documents and perform a bulk operation.\n \t\n -h, --help help for apply\n --skip-security-prompts skips security prompt for bulk operations\n --timestamps when used with --file (bulk operation): prints timestamps in-between the operations","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_apply/#Options-inherited-from-parent-commands","page":"metalctl machine apply","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_apply/","page":"metalctl machine apply","title":"metalctl machine apply","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_apply/#SEE-ALSO","page":"metalctl machine apply","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_apply/","page":"metalctl machine apply","title":"metalctl machine apply","text":"metalctl machine\t - manage machine entities","category":"page"},{"location":"external/metalctl/docs/metalctl_image_update/#metalctl-image-update","page":"metalctl image update","title":"metalctl image update","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_image_update/","page":"metalctl image update","title":"metalctl image update","text":"updates the image","category":"page"},{"location":"external/metalctl/docs/metalctl_image_update/","page":"metalctl image update","title":"metalctl image update","text":"metalctl image update [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_image_update/#Options","page":"metalctl image update","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_image_update/","page":"metalctl image update","title":"metalctl image update","text":" --bulk-output when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.\n -f, --file string filename of the create or update request in yaml format, or - for stdin.\n \n Example:\n $ metalctl image describe image-1 -o yaml > image.yaml\n $ vi image.yaml\n $ # either via stdin\n $ cat image.yaml | metalctl image update -f -\n $ # or via file\n $ metalctl image update -f image.yaml\n \n the file can also contain multiple documents and perform a bulk operation.\n \t\n -h, --help help for update\n --skip-security-prompts skips security prompt for bulk operations\n --timestamps when used with --file (bulk operation): prints timestamps in-between the operations","category":"page"},{"location":"external/metalctl/docs/metalctl_image_update/#Options-inherited-from-parent-commands","page":"metalctl image update","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_image_update/","page":"metalctl image update","title":"metalctl image update","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_image_update/#SEE-ALSO","page":"metalctl image update","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_image_update/","page":"metalctl image update","title":"metalctl image update","text":"metalctl image\t - manage image entities","category":"page"},{"location":"external/metalctl/docs/metalctl_login/#metalctl-login","page":"metalctl login","title":"metalctl login","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_login/","page":"metalctl login","title":"metalctl login","text":"login user and receive token","category":"page"},{"location":"external/metalctl/docs/metalctl_login/#Synopsis","page":"metalctl login","title":"Synopsis","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_login/","page":"metalctl login","title":"metalctl login","text":"login and receive token that will be used to authenticate commands.","category":"page"},{"location":"external/metalctl/docs/metalctl_login/","page":"metalctl login","title":"metalctl login","text":"metalctl login [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_login/#Options","page":"metalctl login","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_login/","page":"metalctl login","title":"metalctl login","text":" -h, --help help for login\n --print-only If true, the token is printed to stdout","category":"page"},{"location":"external/metalctl/docs/metalctl_login/#Options-inherited-from-parent-commands","page":"metalctl login","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_login/","page":"metalctl login","title":"metalctl login","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_login/#SEE-ALSO","page":"metalctl login","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_login/","page":"metalctl login","title":"metalctl login","text":"metalctl\t - a cli to manage entities in the metal-stack api","category":"page"},{"location":"external/metalctl/docs/metalctl_switch_port_up/#metalctl-switch-port-up","page":"metalctl switch port up","title":"metalctl switch port up","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_switch_port_up/","page":"metalctl switch port up","title":"metalctl switch port up","text":"sets the given switch port state up","category":"page"},{"location":"external/metalctl/docs/metalctl_switch_port_up/#Synopsis","page":"metalctl switch port up","title":"Synopsis","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_switch_port_up/","page":"metalctl switch port up","title":"metalctl switch port up","text":"sets the port status to UP so the connected machine will be able to connect to the switch.","category":"page"},{"location":"external/metalctl/docs/metalctl_switch_port_up/","page":"metalctl switch port up","title":"metalctl switch port up","text":"metalctl switch port up [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_switch_port_up/#Options","page":"metalctl switch port up","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_switch_port_up/","page":"metalctl switch port up","title":"metalctl switch port up","text":" -h, --help help for up","category":"page"},{"location":"external/metalctl/docs/metalctl_switch_port_up/#Options-inherited-from-parent-commands","page":"metalctl switch port up","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_switch_port_up/","page":"metalctl switch port up","title":"metalctl switch port up","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --port string the port to be changed.\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_switch_port_up/#SEE-ALSO","page":"metalctl switch port up","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_switch_port_up/","page":"metalctl switch port up","title":"metalctl switch port up","text":"metalctl switch port\t - sets the given switch port state up or down","category":"page"},{"location":"external/mini-lab/README/#mini-lab","page":"mini-lab","title":"mini-lab","text":"","category":"section"},{"location":"external/mini-lab/README/","page":"mini-lab","title":"mini-lab","text":"The mini-lab is a small, virtual setup to locally run the metal-stack. It deploys the metal control plane and a metal-stack partition with two simulated leaf switches. The lab can be used for trying out metal-stack, demonstration purposes or development.","category":"page"},{"location":"external/mini-lab/README/","page":"mini-lab","title":"mini-lab","text":"(Image: overview components)","category":"page"},{"location":"external/mini-lab/README/","page":"mini-lab","title":"mini-lab","text":"ℹ This project can also be used as a template for writing your own metal-stack deployments.","category":"page"},{"location":"external/mini-lab/README/","page":"mini-lab","title":"mini-lab","text":"","category":"page"},{"location":"external/mini-lab/README/","page":"mini-lab","title":"mini-lab","text":"Requirements\nKnown Limitations\nTry it out\nReinstall machine\nFree machine\nFlavors","category":"page"},{"location":"external/mini-lab/README/","page":"mini-lab","title":"mini-lab","text":"","category":"page"},{"location":"external/mini-lab/README/#Requirements","page":"mini-lab","title":"Requirements","text":"","category":"section"},{"location":"external/mini-lab/README/","page":"mini-lab","title":"mini-lab","text":"Linux machine with hardware virtualization support\nkvm as hypervisor for the VMs (you can check through the kvm-ok command)\ndocker >= 24.x.y (for using kind and our deployment base image)\nkind == v0.23.0 (for hosting the metal control plane)\ncontainerlab >= v0.56.0\nthe lab creates a docker network on your host machine with the address block 203.0.113.0/24, designated as TEST-NET-3 for documentation and examples.\n(recommended) haveged to have enough random entropy (only needed if the PXE process does not work)","category":"page"},{"location":"external/mini-lab/README/","page":"mini-lab","title":"mini-lab","text":"Here is some code that should help you to set up most of the requirements:","category":"page"},{"location":"external/mini-lab/README/","page":"mini-lab","title":"mini-lab","text":"# If UFW enabled.\n# Disable the firewall or allow traffic through Docker network IP range.\nsudo ufw status\nsudo ufw allow from 172.17.0.0/16\n\n# Install kvm\nsudo apt install -y git curl qemu qemu-kvm haveged\n\n# Install Docker\ncurl -fsSL https://get.docker.com | sh\n# if you want to be on the safe side, follow the original installation\n# instructions at https://docs.docker.com/engine/install/ubuntu/\n\n# Ensure that your user is member of the group \"docker\"\n# you need to login again in order to make this change take effect\nsudo usermod -G docker -a ${USER}\n\n# Install containerlab\nbash -c \"$(curl -sL https://get.containerlab.dev)\"\n\n# Install kind (kubernetes in docker), for more details see https://kind.sigs.k8s.io/docs/user/quick-start/#installation\nsudo curl -Lo /usr/local/bin/kind \"https://kind.sigs.k8s.io/dl/v0.20.0/kind-linux-amd64\"\nsudo chmod +x /usr/local/bin/kind","category":"page"},{"location":"external/mini-lab/README/","page":"mini-lab","title":"mini-lab","text":"The following ports are used statically on your host machine:","category":"page"},{"location":"external/mini-lab/README/","page":"mini-lab","title":"mini-lab","text":"Port Bind Address Description\n6443 0.0.0.0 kube-apiserver of the kind cluster\n4443 0.0.0.0 HTTPS ingress\n4150 0.0.0.0 nsqd\n8080 0.0.0.0 HTTP ingress","category":"page"},{"location":"external/mini-lab/README/#Known-Limitations","page":"mini-lab","title":"Known Limitations","text":"","category":"section"},{"location":"external/mini-lab/README/","page":"mini-lab","title":"mini-lab","text":"to keep the demo small there is no EVPN\nmachine restart and destroy does not work because we cannot change the boot order via IPMI in the lab easily (virtual-bmc could, but it's buggy)\nlogin to the machines is possible with virsh console, login to the firewall is possible with SSH from your local machine","category":"page"},{"location":"external/mini-lab/README/#Try-it-out","page":"mini-lab","title":"Try it out","text":"","category":"section"},{"location":"external/mini-lab/README/","page":"mini-lab","title":"mini-lab","text":"git clone https://github.com/metal-stack/mini-lab.git\ncd mini-lab","category":"page"},{"location":"external/mini-lab/README/","page":"mini-lab","title":"mini-lab","text":"Start the mini-lab with a kind cluster, a metal-api instance as well as two containers wrapping leaf switches and another container that hosts two user-allocatable machines:","category":"page"},{"location":"external/mini-lab/README/","page":"mini-lab","title":"mini-lab","text":"make\n# containerlab will ask you for root permissions (https://github.com/srl-labs/containerlab/issues/669)","category":"page"},{"location":"external/mini-lab/README/","page":"mini-lab","title":"mini-lab","text":"After the deployment and waiting for a short amount of time, two machines in status PXE booting become visible through metalctl machine ls:","category":"page"},{"location":"external/mini-lab/README/","page":"mini-lab","title":"mini-lab","text":"docker compose run --rm metalctl machine ls\n\nID LAST EVENT WHEN AGE HOSTNAME PROJECT SIZE IMAGE PARTITION\ne0ab02d2-27cd-5a5e-8efc-080ba80cf258   PXE Booting 3s\n2294c949-88f6-5390-8154-fa53d93a3313 PXE Booting 5s","category":"page"},{"location":"external/mini-lab/README/","page":"mini-lab","title":"mini-lab","text":"Wait until the machines reach the waiting state:","category":"page"},{"location":"external/mini-lab/README/","page":"mini-lab","title":"mini-lab","text":"docker compose run --rm metalctl machine ls\n\nID LAST EVENT WHEN AGE HOSTNAME PROJECT SIZE IMAGE PARTITION\ne0ab02d2-27cd-5a5e-8efc-080ba80cf258   Waiting 8s v1-small-x86 mini-lab\n2294c949-88f6-5390-8154-fa53d93a3313   Waiting 8s v1-small-x86 mini-lab","category":"page"},{"location":"external/mini-lab/README/","page":"mini-lab","title":"mini-lab","text":"Create a firewall and a machine with:","category":"page"},{"location":"external/mini-lab/README/","page":"mini-lab","title":"mini-lab","text":"make firewall\nmake machine","category":"page"},{"location":"external/mini-lab/README/","page":"mini-lab","title":"mini-lab","text":"Alternatively, you may want to issue the metalctl commands on your own:","category":"page"},{"location":"external/mini-lab/README/","page":"mini-lab","title":"mini-lab","text":"docker compose run --rm metalctl network allocate \\\n --partition mini-lab \\\n --project 00000000-0000-0000-0000-000000000000 \\\n --name user-private-network\n\n# lookup the network ID and create a machine\ndocker compose run --rm metalctl machine create \\\n --description test \\\n --name machine \\\n --hostname machine \\\n --project 00000000-0000-0000-0000-000000000000 \\\n --partition mini-lab \\\n --image ubuntu-20.04 \\\n --size v1-small-x86 \\\n --networks \n\n# create a firewall that is also connected to the virtual internet-mini-lab network\ndocker compose run --rm metalctl machine create \\\n --description fw \\\n --name fw \\\n --hostname fw \\\n --project 00000000-0000-0000-0000-000000000000 \\\n --partition mini-lab \\\n --image firewall-ubuntu-2.0 \\\n --size v1-small-x86 \\\n --networks internet-mini-lab,$(privatenet)","category":"page"},{"location":"external/mini-lab/README/","page":"mini-lab","title":"mini-lab","text":"See the installation process in action","category":"page"},{"location":"external/mini-lab/README/","page":"mini-lab","title":"mini-lab","text":"make console-machine01/02\n...\nUbuntu 20.04 machine ttyS0\n\nmachine login:","category":"page"},{"location":"external/mini-lab/README/","page":"mini-lab","title":"mini-lab","text":"Two machines are now installed and have status \"Phoned Home\"","category":"page"},{"location":"external/mini-lab/README/","page":"mini-lab","title":"mini-lab","text":"docker compose run --rm metalctl machine ls\nID LAST EVENT WHEN AGE HOSTNAME PROJECT SIZE IMAGE PARTITION\ne0ab02d2-27cd-5a5e-8efc-080ba80cf258   Phoned Home 2s 21s machine 00000000-0000-0000-0000-000000000000 v1-small-x86 Ubuntu 20.04 20200331 mini-lab\n2294c949-88f6-5390-8154-fa53d93a3313   Phoned Home 8s 18s fw 00000000-0000-0000-0000-000000000000 v1-small-x86 Firewall 2 Ubuntu 20200730 mini-lab","category":"page"},{"location":"external/mini-lab/README/","page":"mini-lab","title":"mini-lab","text":"Login with user name metal and the console password from","category":"page"},{"location":"external/mini-lab/README/","page":"mini-lab","title":"mini-lab","text":"docker compose run --rm metalctl machine consolepassword e0ab02d2-27cd-5a5e-8efc-080ba80cf258","category":"page"},{"location":"external/mini-lab/README/","page":"mini-lab","title":"mini-lab","text":"To remove the kind cluster, the switches and machines, run:","category":"page"},{"location":"external/mini-lab/README/","page":"mini-lab","title":"mini-lab","text":"make cleanup","category":"page"},{"location":"external/mini-lab/README/#Reinstall-machine","page":"mini-lab","title":"Reinstall machine","text":"","category":"section"},{"location":"external/mini-lab/README/","page":"mini-lab","title":"mini-lab","text":"Reinstall a machine with","category":"page"},{"location":"external/mini-lab/README/","page":"mini-lab","title":"mini-lab","text":"docker compose run --rm metalctl machine reinstall \\\n --image ubuntu-20.04 \\\n e0ab02d2-27cd-5a5e-8efc-080ba80cf258","category":"page"},{"location":"external/mini-lab/README/#Free-machine","page":"mini-lab","title":"Free machine","text":"","category":"section"},{"location":"external/mini-lab/README/","page":"mini-lab","title":"mini-lab","text":"Free a machine with make free-machine01 or","category":"page"},{"location":"external/mini-lab/README/","page":"mini-lab","title":"mini-lab","text":"docker compose run --rm metalctl machine rm e0ab02d2-27cd-5a5e-8efc-080ba80cf258","category":"page"},{"location":"external/mini-lab/README/#Flavors","page":"mini-lab","title":"Flavors","text":"","category":"section"},{"location":"external/mini-lab/README/","page":"mini-lab","title":"mini-lab","text":"There's few versions of mini-lab environment that you can run. We call them flavors. There's 2 flavors at the moment:","category":"page"},{"location":"external/mini-lab/README/","page":"mini-lab","title":"mini-lab","text":"default – runs 2 machines.\ncluster-api – runs 3 machines. Useful for testing Control plane and worker node deployment with Cluster API provider.\nsonic – use SONiC as network operating system for the leaves","category":"page"},{"location":"external/mini-lab/README/","page":"mini-lab","title":"mini-lab","text":"In order to start specific flavor, you can define the flavor as follows:","category":"page"},{"location":"external/mini-lab/README/","page":"mini-lab","title":"mini-lab","text":"export MINI_LAB_FLAVOR=cluster-api\nmake","category":"page"},{"location":"external/mini-lab/README/#Page-Tree","page":"mini-lab","title":"Page Tree","text":"","category":"section"},{"location":"external/mini-lab/README/","page":"mini-lab","title":"mini-lab","text":"Pages = vcat([[joinpath(root, file)[length(@__DIR__)+2:end] for file in files] for (root, dirs, files) in walkdir(@__DIR__)]...)","category":"page"},{"location":"external/metalctl/docs/metalctl_completion_zsh/#metalctl-completion-zsh","page":"metalctl completion zsh","title":"metalctl completion zsh","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_completion_zsh/","page":"metalctl completion zsh","title":"metalctl completion zsh","text":"Generate the autocompletion script for zsh","category":"page"},{"location":"external/metalctl/docs/metalctl_completion_zsh/#Synopsis","page":"metalctl completion zsh","title":"Synopsis","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_completion_zsh/","page":"metalctl completion zsh","title":"metalctl completion zsh","text":"Generate the autocompletion script for the zsh shell.","category":"page"},{"location":"external/metalctl/docs/metalctl_completion_zsh/","page":"metalctl completion zsh","title":"metalctl completion zsh","text":"If shell completion is not already enabled in your environment you will need to enable it. You can execute the following once:","category":"page"},{"location":"external/metalctl/docs/metalctl_completion_zsh/","page":"metalctl completion zsh","title":"metalctl completion zsh","text":"echo \"autoload -U compinit; compinit\" >> ~/.zshrc","category":"page"},{"location":"external/metalctl/docs/metalctl_completion_zsh/","page":"metalctl completion zsh","title":"metalctl completion zsh","text":"To load completions in your current shell session:","category":"page"},{"location":"external/metalctl/docs/metalctl_completion_zsh/","page":"metalctl completion zsh","title":"metalctl completion zsh","text":"source <(metalctl completion zsh)","category":"page"},{"location":"external/metalctl/docs/metalctl_completion_zsh/","page":"metalctl completion zsh","title":"metalctl completion zsh","text":"To load completions for every new session, execute once:","category":"page"},{"location":"external/metalctl/docs/metalctl_completion_zsh/#Linux:","page":"metalctl completion zsh","title":"Linux:","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_completion_zsh/","page":"metalctl completion zsh","title":"metalctl completion zsh","text":"metalctl completion zsh > \"${fpath[1]}/_metalctl\"","category":"page"},{"location":"external/metalctl/docs/metalctl_completion_zsh/#macOS:","page":"metalctl completion zsh","title":"macOS:","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_completion_zsh/","page":"metalctl completion zsh","title":"metalctl completion zsh","text":"metalctl completion zsh > $(brew --prefix)/share/zsh/site-functions/_metalctl","category":"page"},{"location":"external/metalctl/docs/metalctl_completion_zsh/","page":"metalctl completion zsh","title":"metalctl completion zsh","text":"You will need to start a new shell for this setup to take effect.","category":"page"},{"location":"external/metalctl/docs/metalctl_completion_zsh/","page":"metalctl completion zsh","title":"metalctl completion zsh","text":"metalctl completion zsh [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_completion_zsh/#Options","page":"metalctl completion zsh","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_completion_zsh/","page":"metalctl completion zsh","title":"metalctl completion zsh","text":" -h, --help help for zsh\n --no-descriptions disable completion descriptions","category":"page"},{"location":"external/metalctl/docs/metalctl_completion_zsh/#Options-inherited-from-parent-commands","page":"metalctl completion zsh","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_completion_zsh/","page":"metalctl completion zsh","title":"metalctl completion zsh","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_completion_zsh/#SEE-ALSO","page":"metalctl completion zsh","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_completion_zsh/","page":"metalctl completion zsh","title":"metalctl completion zsh","text":"metalctl completion\t - Generate the autocompletion script for the specified shell","category":"page"},{"location":"external/metalctl/docs/metalctl_switch_describe/#metalctl-switch-describe","page":"metalctl switch describe","title":"metalctl switch describe","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_switch_describe/","page":"metalctl switch describe","title":"metalctl switch describe","text":"describes the switch","category":"page"},{"location":"external/metalctl/docs/metalctl_switch_describe/","page":"metalctl switch describe","title":"metalctl switch describe","text":"metalctl switch describe [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_switch_describe/#Options","page":"metalctl switch describe","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_switch_describe/","page":"metalctl switch describe","title":"metalctl switch describe","text":" -h, --help help for describe","category":"page"},{"location":"external/metalctl/docs/metalctl_switch_describe/#Options-inherited-from-parent-commands","page":"metalctl switch describe","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_switch_describe/","page":"metalctl switch describe","title":"metalctl switch describe","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_switch_describe/#SEE-ALSO","page":"metalctl switch describe","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_switch_describe/","page":"metalctl switch describe","title":"metalctl switch describe","text":"metalctl switch\t - manage switch entities","category":"page"},{"location":"external/metalctl/docs/metalctl_context_short/#metalctl-context-short","page":"metalctl context short","title":"metalctl context short","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_context_short/","page":"metalctl context short","title":"metalctl context short","text":"only show the default context name","category":"page"},{"location":"external/metalctl/docs/metalctl_context_short/","page":"metalctl context short","title":"metalctl context short","text":"metalctl context short [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_context_short/#Options","page":"metalctl context short","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_context_short/","page":"metalctl context short","title":"metalctl context short","text":" -h, --help help for short","category":"page"},{"location":"external/metalctl/docs/metalctl_context_short/#Options-inherited-from-parent-commands","page":"metalctl context short","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_context_short/","page":"metalctl context short","title":"metalctl context short","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_context_short/#SEE-ALSO","page":"metalctl context short","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_context_short/","page":"metalctl context short","title":"metalctl context short","text":"metalctl context\t - manage metalctl context","category":"page"},{"location":"development/proposals/MEP4/README/#Multi-Tenancy-for-the-metal-api","page":"Multi-Tenancy for the metal-api","title":"Multi-Tenancy for the metal-api","text":"","category":"section"},{"location":"development/proposals/MEP4/README/","page":"Multi-Tenancy for the metal-api","title":"Multi-Tenancy for the metal-api","text":"info: Info\nThis document is work in progress.","category":"page"},{"location":"development/proposals/MEP4/README/","page":"Multi-Tenancy for the metal-api","title":"Multi-Tenancy for the metal-api","text":"In the past we decided to treat the metal-api as a \"low-level API\", i.e. the API does not specifically deal with projects and tenants. A user with editor access can for example assign machines to every project he desires, he can see all the machines available and can control them. We tried to keep the metal-api code base as small as possible and we added resource scoping to a \"higher-level APIs\". From there, a user would be able to only see his own clusters and IP addresses.","category":"page"},{"location":"development/proposals/MEP4/README/","page":"Multi-Tenancy for the metal-api","title":"Multi-Tenancy for the metal-api","text":"As time passed metal-stack has become an open-source project and people are willing to adopt. Adopters who want to put their own technologies on top of the metal-stack infrastructure don't have those \"higher-level APIs\" that we implemented closed-source for our user base. So, external adopters most likely need to implement resource scoping on their own.","category":"page"},{"location":"development/proposals/MEP4/README/","page":"Multi-Tenancy for the metal-api","title":"Multi-Tenancy for the metal-api","text":"Introducing multi-tenancy to the metal-api is a serious chance of making our product better and more successful as it opens the door for:","category":"page"},{"location":"development/proposals/MEP4/README/","page":"Multi-Tenancy for the metal-api","title":"Multi-Tenancy for the metal-api","text":"Becoming a \"fully-featured\" API\nNarrowing down attack surfaces and possibility of unintended resource modification produced by bugs or human errors\nDiscouraging people to implement their own scoping layers in front of the metal-stack\nGaining performance through resource scopes\nLetting untrusted / third-parties work with the API","category":"page"},{"location":"development/proposals/MEP4/README/#Table-of-Contents","page":"Multi-Tenancy for the metal-api","title":"Table of Contents","text":"","category":"section"},{"location":"development/proposals/MEP4/README/","page":"Multi-Tenancy for the metal-api","title":"Multi-Tenancy for the metal-api","text":"Pages = [\"README.md\"]\nDepth = 5","category":"page"},{"location":"development/proposals/MEP4/README/#Requirements","page":"Multi-Tenancy for the metal-api","title":"Requirements","text":"","category":"section"},{"location":"development/proposals/MEP4/README/","page":"Multi-Tenancy for the metal-api","title":"Multi-Tenancy for the metal-api","text":"These are some general requirements / higher objectives that MEP-4 has to fulfill.","category":"page"},{"location":"development/proposals/MEP4/README/","page":"Multi-Tenancy for the metal-api","title":"Multi-Tenancy for the metal-api","text":"Should be able to run with mini-lab without requiring to setup complex auth backends (dex, LDAP, keycloak, ...)\nSimple to start with, more complex options for production setups\nShould utilize auth mechanisms that we have already in place to best possible degree\nFine-grained access permissions (every endpoint maps to a permission)\nTenant scoping (disallow resource access to resources of other tenants)\nProject scoping (disallow resource access to resources of other projects)\nAccess tokens in self-service for technical user access","category":"page"},{"location":"development/proposals/MEP4/README/#Implementation","page":"Multi-Tenancy for the metal-api","title":"Implementation","text":"","category":"section"},{"location":"development/proposals/MEP4/README/","page":"Multi-Tenancy for the metal-api","title":"Multi-Tenancy for the metal-api","text":"We gathered a lot of knowledge while implementing a multi-tenancy-capable backend for metalstack.cloud. The goal is now to use the same technology and adopt that to the metal-api, this includes:","category":"page"},{"location":"development/proposals/MEP4/README/","page":"Multi-Tenancy for the metal-api","title":"Multi-Tenancy for the metal-api","text":"gRPC in combination with connectrpc\nOPA for making auth decisions\nREST HTTP only for OIDC login flows","category":"page"},{"location":"development/proposals/MEP4/README/#API-Definitions","page":"Multi-Tenancy for the metal-api","title":"API Definitions","text":"","category":"section"},{"location":"development/proposals/MEP4/README/","page":"Multi-Tenancy for the metal-api","title":"Multi-Tenancy for the metal-api","text":"The API definitions should be located on a separate Github repository separate from the server implementation. The proposed repository location is: https://github.com/metal-stack/api.","category":"page"},{"location":"development/proposals/MEP4/README/","page":"Multi-Tenancy for the metal-api","title":"Multi-Tenancy for the metal-api","text":"This repository contains the proto3 specification of the exposed metal-stack api. This includes the messages, simple validations, services and the access permission to these services. The input parameters for the authorization in the backend are generated from the proto3 annotations.","category":"page"},{"location":"development/proposals/MEP4/README/","page":"Multi-Tenancy for the metal-api","title":"Multi-Tenancy for the metal-api","text":"Client implementations for the most relevant languages (go, python) are generated automatically.","category":"page"},{"location":"development/proposals/MEP4/README/","page":"Multi-Tenancy for the metal-api","title":"Multi-Tenancy for the metal-api","text":"This api is divided into end-user and admin access at the top level. The proposed APIs are:","category":"page"},{"location":"development/proposals/MEP4/README/","page":"Multi-Tenancy for the metal-api","title":"Multi-Tenancy for the metal-api","text":"api.v2: For end-user facing services\nadmin.v2: For operators and controllers which need access to unscoped entities","category":"page"},{"location":"development/proposals/MEP4/README/","page":"Multi-Tenancy for the metal-api","title":"Multi-Tenancy for the metal-api","text":"The methods of the API can have different role scopes (and can be narrowed down further with fine-grained method permissions):","category":"page"},{"location":"development/proposals/MEP4/README/","page":"Multi-Tenancy for the metal-api","title":"Multi-Tenancy for the metal-api","text":"tenant: Tenant-scoped methods, e.g. project creation (tenant needs to be provided in the request payload)\nAvailable roles: VIEWER, EDITOR, OWNER\nproject: Project-scoped methods, e.g. machine creation (tenant needs to be provided in the request payload)\nAvailable roles: VIEWER, EDITOR, OWNER\nadmin Admin-scoped methods, e.g. unscoped tenant list or switch register\nAvailable roles: VIEWER, EDITOR","category":"page"},{"location":"development/proposals/MEP4/README/","page":"Multi-Tenancy for the metal-api","title":"Multi-Tenancy for the metal-api","text":"And has methods with different visibility scopes:","category":"page"},{"location":"development/proposals/MEP4/README/","page":"Multi-Tenancy for the metal-api","title":"Multi-Tenancy for the metal-api","text":"self: Methods that only the logged in user can access, e.g. show permissions with the presented token\npublic: Methods that do not require any specific authorization\nprivate: Methods that are not exposed","category":"page"},{"location":"development/proposals/MEP4/README/#API","page":"Multi-Tenancy for the metal-api","title":"API","text":"","category":"section"},{"location":"development/proposals/MEP4/README/","page":"Multi-Tenancy for the metal-api","title":"Multi-Tenancy for the metal-api","text":"The API server implements the services defined in the API and validates access to a method using OPA with the JWT tokens passed in the requests. The server is implemented using the connectrpc.com framework.","category":"page"},{"location":"development/proposals/MEP4/README/","page":"Multi-Tenancy for the metal-api","title":"Multi-Tenancy for the metal-api","text":"The API server implements the login flow through OIDC. After successful authentication, the API server derives user permissions from the OIDC provider and issues a new JWT token which is passed on to the user. The tokens including the permissions are stored in a redis compatible backend.","category":"page"},{"location":"development/proposals/MEP4/README/","page":"Multi-Tenancy for the metal-api","title":"Multi-Tenancy for the metal-api","text":"With these tokens, users can create Access Tokens for CI/CD or other use cases.","category":"page"},{"location":"development/proposals/MEP4/README/","page":"Multi-Tenancy for the metal-api","title":"Multi-Tenancy for the metal-api","text":"JWT Tokens can be revoked by admins and the user itself.","category":"page"},{"location":"development/proposals/MEP4/README/#API-Server","page":"Multi-Tenancy for the metal-api","title":"API Server","text":"","category":"section"},{"location":"development/proposals/MEP4/README/","page":"Multi-Tenancy for the metal-api","title":"Multi-Tenancy for the metal-api","text":"Is put into a new github repo which implements the services defined in the api repository. It opens a https endpoints where the grpc (via connectrpc.com) and oidc servives are exposed.","category":"page"},{"location":"development/proposals/MEP4/README/#Migration-of-the-Consumers","page":"Multi-Tenancy for the metal-api","title":"Migration of the Consumers","text":"","category":"section"},{"location":"development/proposals/MEP4/README/","page":"Multi-Tenancy for the metal-api","title":"Multi-Tenancy for the metal-api","text":"To allow consumers to migrate to the v2 API gradually, both apis, the new and the old, are deployed in parallel. In the control-plane both apis are deployed side-by-side behind the ingress. api.example.com is forwarded to metal-api and metal.example.com is forwarded to the new api-server.","category":"page"},{"location":"development/proposals/MEP4/README/","page":"Multi-Tenancy for the metal-api","title":"Multi-Tenancy for the metal-api","text":"The api-server will talk to the existing metal-api during the process of migration services away to the new grpc api.","category":"page"},{"location":"development/proposals/MEP4/README/","page":"Multi-Tenancy for the metal-api","title":"Multi-Tenancy for the metal-api","text":"The migration process can be done in the following manner:","category":"page"},{"location":"development/proposals/MEP4/README/","page":"Multi-Tenancy for the metal-api","title":"Multi-Tenancy for the metal-api","text":"for each resource in the metal-api:","category":"page"},{"location":"development/proposals/MEP4/README/","page":"Multi-Tenancy for the metal-api","title":"Multi-Tenancy for the metal-api","text":"create a new proto3 based definition in the api repo.\nimplement at least a small wrapper service in the api-server which asks the metal-api for this resource an maps the response back the caller in the grpc format.\nidentify all consumers of this resource and replace them to use the grpc instead of the rest api\nmove the business logic incl. the backend calls to ipam, metal-db, masterdata-ap, nsq for this resource from the metal-api to the api-server","category":"page"},{"location":"development/proposals/MEP4/README/","page":"Multi-Tenancy for the metal-api","title":"Multi-Tenancy for the metal-api","text":"We will try to migrate the rethinkdb backend implementation to a generic approach during this effort.","category":"page"},{"location":"development/proposals/MEP4/README/","page":"Multi-Tenancy for the metal-api","title":"Multi-Tenancy for the metal-api","text":"There are a lot of consumers of metal-api, which need to be migrated:","category":"page"},{"location":"development/proposals/MEP4/README/","page":"Multi-Tenancy for the metal-api","title":"Multi-Tenancy for the metal-api","text":"ansible\nfirewall-controller\nfirewall-controller-manager\ngardener-extension-auth\ngardener-extension-provider-metal\nDo not point the secret bindings to a the shared provider secret in the seed anymore. Instead, use individual provider-secret containing project-scoped API access tokens in the Gardener project namespaces.\nmachine-controller-manager-provider-metal\nmetal-ccm\nmetal-console\nmetal-bmc\nmetal-core\nmetal-hammer\nmetal-image-cache-sync\nmetal-images\nmetal-metrics-exporter\nmetal-networker\nmetalctl\npixie","category":"page"},{"location":"development/proposals/MEP4/README/#User-Scenarios","page":"Multi-Tenancy for the metal-api","title":"User Scenarios","text":"","category":"section"},{"location":"development/proposals/MEP4/README/","page":"Multi-Tenancy for the metal-api","title":"Multi-Tenancy for the metal-api","text":"This section gathers a collection of workflows from the perspective of a user that we want to provide with the implementation of this proposal.","category":"page"},{"location":"development/proposals/MEP4/README/#Machine-Creation","page":"Multi-Tenancy for the metal-api","title":"Machine Creation","text":"","category":"section"},{"location":"development/proposals/MEP4/README/","page":"Multi-Tenancy for the metal-api","title":"Multi-Tenancy for the metal-api","text":"A regular user wants to create a machine resource.","category":"page"},{"location":"development/proposals/MEP4/README/","page":"Multi-Tenancy for the metal-api","title":"Multi-Tenancy for the metal-api","text":"Requirements: Project was created, permissions are present","category":"page"},{"location":"development/proposals/MEP4/README/","page":"Multi-Tenancy for the metal-api","title":"Multi-Tenancy for the metal-api","text":"The user can see networks that were provided by the admin.\n$ metalctl network ls\nID NAME PROJECT PARTITION NAT SHARED PREFIXES IPS\ninternet Internet Network true false 212.34.83.0/27  ●\ntenant-super-network-fra-equ01 Project Super Network fra-equ01 false false 10.128.0.0/14  ●\nunderlay-fra-equ01 Underlay Network fra-equ01 false false 10.0.0.0/16  ●\nThe user has to set the project scope first or provide --project flags for all commands.\n$ metalctl project set 793bb6cd-8b46-479d-9209-0fedca428fe1\nYou are now acting on project 793bb6cd-8b46-479d-9209-0fedca428fe1.\nThe user can create the child network required for machine allocation.\n$ metalctl network allocate --partition fra-equ01 --name test\nNow, the user sees his own child network.\n$ metalctl network ls\nID NAME PROJECT PARTITION NAT SHARED PREFIXES IPS\ninternet Internet Network true false 212.34.83.0/27  ●\ntenant-super-network-fra-equ01 Project Super Network fra-equ01 false false 10.128.0.0/14  ●\n└─╴08b9114b-ec47-4697-b402-a11421788dc6 test 793bb6cd-8b46-479d-9209-0fedca428fe1 fra-equ01 false false 10.128.64.0/22  ●\nunderlay-fra-equ01 Underlay Network fra-equ01 false false 10.0.0.0/16  ●\nThe user does not see any machines yet.\n$ metalctl machine ls\nThe user can create a machine.\n$ metalctl machine create --networks internet,08b9114b-ec47-4697-b402-a11421788dc6 --name test --hostname test --image ubuntu-20.04 --partition fra-equ01 --size c1-xlarge-x86`\nThe machine will now be provisioned.\n$ metalctl machine ls\nID LAST EVENT WHEN AGE HOSTNAME PROJECT SIZE IMAGE PARTITION\n00000000-0000-0000-0000-ac1f6b7befb2 Phoned Home 20s 50d 4h test 793bb6cd-8b46-479d-9209-0fedca428fe1 c1-xlarge-x86 Ubuntu 20.04 20210415 fra-equ01","category":"page"},{"location":"development/proposals/MEP4/README/","page":"Multi-Tenancy for the metal-api","title":"Multi-Tenancy for the metal-api","text":"warning: Warning\nA user cannot list all allocated machines for all projects. The user must always switch project context first and can only view the machines inside this project. Only admins can see all machines at once.","category":"page"},{"location":"development/proposals/MEP4/README/#Scopes-for-Resources","page":"Multi-Tenancy for the metal-api","title":"Scopes for Resources","text":"","category":"section"},{"location":"development/proposals/MEP4/README/","page":"Multi-Tenancy for the metal-api","title":"Multi-Tenancy for the metal-api","text":"The admins / operators of the metal-stack should be able to provide global resources that users are able to use along with their own resources. In particular, users can view and use global resources, but they are not allowed to create, modify or delete them.","category":"page"},{"location":"development/proposals/MEP4/README/","page":"Multi-Tenancy for the metal-api","title":"Multi-Tenancy for the metal-api","text":"info: Info\nWhen a project ID field is empty on a resource, the resource is considered global.","category":"page"},{"location":"development/proposals/MEP4/README/","page":"Multi-Tenancy for the metal-api","title":"Multi-Tenancy for the metal-api","text":"Where possible, users should be capable of creating their own resource entities.","category":"page"},{"location":"development/proposals/MEP4/README/","page":"Multi-Tenancy for the metal-api","title":"Multi-Tenancy for the metal-api","text":"Resource User Global\nFile System Layout yes yes\nFirewall yes \nFirmware yes\nOS Image yes\nMachine yes \nNetwork (Base) yes\nNetwork (Children) yes \nIP yes \nPartition yes\nProject yes \nProject Token yes \nSize yes\nSwitch \nTenant yes","category":"page"},{"location":"development/proposals/MEP4/README/","page":"Multi-Tenancy for the metal-api","title":"Multi-Tenancy for the metal-api","text":"info: Info\nExample: A user can make use of the file system layouts provided by the admins, but can also create own layouts. Same applies for images. As soon as a user creates own resources, the user takes over the responsibility for the machine provisioning to succeed.","category":"page"},{"location":"external/metalctl/docs/metalctl_size_reservation_list/#metalctl-size-reservation-list","page":"metalctl size reservation list","title":"metalctl size reservation list","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_reservation_list/","page":"metalctl size reservation list","title":"metalctl size reservation list","text":"list all reservations","category":"page"},{"location":"external/metalctl/docs/metalctl_size_reservation_list/","page":"metalctl size reservation list","title":"metalctl size reservation list","text":"metalctl size reservation list [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_size_reservation_list/#Options","page":"metalctl size reservation list","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_reservation_list/","page":"metalctl size reservation list","title":"metalctl size reservation list","text":" -h, --help help for list\n --id string the id to filter\n --partition string the partition id to filter\n --project string the project id to filter\n --size string the size id to filter\n --sort-by strings sort by (comma separated) column(s), sort direction can be changed by appending :asc or :desc behind the column identifier. possible values: amount|id|partition|project|size","category":"page"},{"location":"external/metalctl/docs/metalctl_size_reservation_list/#Options-inherited-from-parent-commands","page":"metalctl size reservation list","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_reservation_list/","page":"metalctl size reservation list","title":"metalctl size reservation list","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_size_reservation_list/#SEE-ALSO","page":"metalctl size reservation list","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_reservation_list/","page":"metalctl size reservation list","title":"metalctl size reservation list","text":"metalctl size reservation\t - manage reservation entities","category":"page"},{"location":"external/metalctl/docs/metalctl_size_reservation/#metalctl-size-reservation","page":"metalctl size reservation","title":"metalctl size reservation","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_reservation/","page":"metalctl size reservation","title":"metalctl size reservation","text":"manage reservation entities","category":"page"},{"location":"external/metalctl/docs/metalctl_size_reservation/#Synopsis","page":"metalctl size reservation","title":"Synopsis","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_reservation/","page":"metalctl size reservation","title":"metalctl size reservation","text":"manage size reservations","category":"page"},{"location":"external/metalctl/docs/metalctl_size_reservation/#Options","page":"metalctl size reservation","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_reservation/","page":"metalctl size reservation","title":"metalctl size reservation","text":" -h, --help help for reservation","category":"page"},{"location":"external/metalctl/docs/metalctl_size_reservation/#Options-inherited-from-parent-commands","page":"metalctl size reservation","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_reservation/","page":"metalctl size reservation","title":"metalctl size reservation","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_size_reservation/#SEE-ALSO","page":"metalctl size reservation","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_reservation/","page":"metalctl size reservation","title":"metalctl size reservation","text":"metalctl size\t - manage size entities\nmetalctl size reservation apply\t - applies one or more reservations from a given file\nmetalctl size reservation create\t - creates the reservation\nmetalctl size reservation delete\t - deletes the reservation\nmetalctl size reservation describe\t - describes the reservation\nmetalctl size reservation edit\t - edit the reservation through an editor and update\nmetalctl size reservation list\t - list all reservations\nmetalctl size reservation update\t - updates the reservation\nmetalctl size reservation usage\t - see current usage of size reservations","category":"page"},{"location":"external/metalctl/docs/metalctl_network_describe/#metalctl-network-describe","page":"metalctl network describe","title":"metalctl network describe","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_network_describe/","page":"metalctl network describe","title":"metalctl network describe","text":"describes the network","category":"page"},{"location":"external/metalctl/docs/metalctl_network_describe/","page":"metalctl network describe","title":"metalctl network describe","text":"metalctl network describe [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_network_describe/#Options","page":"metalctl network describe","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_network_describe/","page":"metalctl network describe","title":"metalctl network describe","text":" -h, --help help for describe","category":"page"},{"location":"external/metalctl/docs/metalctl_network_describe/#Options-inherited-from-parent-commands","page":"metalctl network describe","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_network_describe/","page":"metalctl network describe","title":"metalctl network describe","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_network_describe/#SEE-ALSO","page":"metalctl network describe","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_network_describe/","page":"metalctl network describe","title":"metalctl network describe","text":"metalctl network\t - manage network entities","category":"page"},{"location":"external/metalctl/docs/metalctl_project_update/#metalctl-project-update","page":"metalctl project update","title":"metalctl project update","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_project_update/","page":"metalctl project update","title":"metalctl project update","text":"updates the project","category":"page"},{"location":"external/metalctl/docs/metalctl_project_update/","page":"metalctl project update","title":"metalctl project update","text":"metalctl project update [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_project_update/#Options","page":"metalctl project update","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_project_update/","page":"metalctl project update","title":"metalctl project update","text":" --bulk-output when used with --file (bulk operation): prints results at the end as a list. default is printing results intermediately during the operation, which causes single entities to be printed in a row.\n -f, --file string filename of the create or update request in yaml format, or - for stdin.\n \n Example:\n $ metalctl project describe project-1 -o yaml > project.yaml\n $ vi project.yaml\n $ # either via stdin\n $ cat project.yaml | metalctl project update -f -\n $ # or via file\n $ metalctl project update -f project.yaml\n \n the file can also contain multiple documents and perform a bulk operation.\n \t\n -h, --help help for update\n --skip-security-prompts skips security prompt for bulk operations\n --timestamps when used with --file (bulk operation): prints timestamps in-between the operations","category":"page"},{"location":"external/metalctl/docs/metalctl_project_update/#Options-inherited-from-parent-commands","page":"metalctl project update","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_project_update/","page":"metalctl project update","title":"metalctl project update","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_project_update/#SEE-ALSO","page":"metalctl project update","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_project_update/","page":"metalctl project update","title":"metalctl project update","text":"metalctl project\t - manage project entities","category":"page"},{"location":"development/proposals/MEP6/README/#DMZ-Networks","page":"DMZ Networks","title":"DMZ Networks","text":"","category":"section"},{"location":"development/proposals/MEP6/README/#Reasoning","page":"DMZ Networks","title":"Reasoning","text":"","category":"section"},{"location":"development/proposals/MEP6/README/","page":"DMZ Networks","title":"DMZ Networks","text":"To fulfill higher levels of security measures the standard metal-stack approach with a single firewall in front of a set of machines might be insufficient. There are cases where two physically distinct firewalls in front of application workload are mandatory. In traditional network terms this is known as DMZ approach.","category":"page"},{"location":"development/proposals/MEP6/README/","page":"DMZ Networks","title":"DMZ Networks","text":"For Kubernetes workloads it makes sense to use the front cluster for ingress, WAF purposes and as outgoing proxy. The clusters may be used for application workload.","category":"page"},{"location":"development/proposals/MEP6/README/#DMZ-network","page":"DMZ Networks","title":"DMZ network","text":"","category":"section"},{"location":"development/proposals/MEP6/README/","page":"DMZ Networks","title":"DMZ Networks","text":"Use a separate DMZ network prefix for every tenant\nThis is used as intermediate network btw. private networks of a tenant and the internet\nFor every partition a distinct DMZ firewall/cluster is needed for a tenant\nFor Gardener orchestrated Kubernetes clusters this network must be a publicly reachable internet prefix because shoot clusters need a vpn service that is used for instrumentation from the seed cluster - this will be a requirement as long as the inverse vpn tunnel feature Konnectivity is not available to us.","category":"page"},{"location":"development/proposals/MEP6/README/#Approach-1:-DMZ-with-publicly-reachable-internet-prefix","page":"DMZ Networks","title":"Approach 1: DMZ with publicly reachable internet prefix","text":"","category":"section"},{"location":"development/proposals/MEP6/README/","page":"DMZ Networks","title":"DMZ Networks","text":"(Image: DMZ Internet)","category":"page"},{"location":"development/proposals/MEP6/README/","page":"DMZ Networks","title":"DMZ Networks","text":"A DMZ network with publicly reachable internet prefix will look like this in the metal-api:","category":"page"},{"location":"development/proposals/MEP6/README/","page":"DMZ Networks","title":"DMZ Networks","text":"---\ndescription: DMZ-Network\ndestinationprefixes:\n- 0.0.0.0/0\nid: dmz\nlabels:\n network.metal-stack.io/default-external: \"\"\nname: DMZ-Network\nparentnetworkid: null\npartitionid: \"\"\nprefixes:\n- 212.90.30.128/25\nprivatesuper: false\nprojectid: \"\"\nvrf: 104007\nvrfshared: false\nnat: true\nshared: false\nunderlay: false","category":"page"},{"location":"development/proposals/MEP6/README/#DMZ-firewall","page":"DMZ Networks","title":"DMZ firewall","text":"","category":"section"},{"location":"development/proposals/MEP6/README/","page":"DMZ Networks","title":"DMZ Networks","text":"The firewall of the DMZ will intersect its private network for attached machines, the DMZ network and the public internet.","category":"page"},{"location":"development/proposals/MEP6/README/","page":"DMZ Networks","title":"DMZ Networks","text":"The private network of the project needs to import\nthe default route from the internet network\nthe DMZ network\nThe internet network must import the DMZ network\nThe DMZ network provides the default route for tenant's clusters in a partition. It imports the default route from the internet network","category":"page"},{"location":"development/proposals/MEP6/README/#Application-Firewall","page":"DMZ Networks","title":"Application Firewall","text":"","category":"section"},{"location":"development/proposals/MEP6/README/","page":"DMZ Networks","title":"DMZ Networks","text":"The firewall of application workloads intersects its private network for attached machines and the DMZ network.","category":"page"},{"location":"development/proposals/MEP6/README/","page":"DMZ Networks","title":"DMZ Networks","text":"This is currently supported by the metal-networker and needs no further changes!","category":"page"},{"location":"development/proposals/MEP6/README/#Approach-2:-DMZ-with-private-IPs","page":"DMZ Networks","title":"Approach 2: DMZ with private IPs","text":"","category":"section"},{"location":"development/proposals/MEP6/README/","page":"DMZ Networks","title":"DMZ Networks","text":"(Image: DMZ Internet)","category":"page"},{"location":"development/proposals/MEP6/README/","page":"DMZ Networks","title":"DMZ Networks","text":"A DMZ network with private IPs will look like this in the metal-api:","category":"page"},{"location":"development/proposals/MEP6/README/","page":"DMZ Networks","title":"DMZ Networks","text":"---\ndescription: DMZ-Network\ndestinationprefixes:\n- 0.0.0.0/0\nid: dmz\nlabels:\n network.metal-stack.io/default-external: \"\"\nname: DMZ-Network\nparentnetworkid: tenant-super-network-fra-equ01\npartitionid: fra-equ01\nprefixes:\n- 10.90.30.128/25\nprivatesuper: false\nprojectid: \"\"\nvrf: 4711\nvrfshared: false\nnat: true\nshared: true # it's usable from multiple projects\nunderlay: false","category":"page"},{"location":"development/proposals/MEP6/README/#DMZ-firewall-2","page":"DMZ Networks","title":"DMZ firewall","text":"","category":"section"},{"location":"development/proposals/MEP6/README/","page":"DMZ Networks","title":"DMZ Networks","text":"The firewall of the DMZ will intersect its private network for attached machines, the DMZ network and the public internet.","category":"page"},{"location":"development/proposals/MEP6/README/","page":"DMZ Networks","title":"DMZ Networks","text":"The private network of the project needs to import\nthe default route from the internet network\nthe DMZ network\nThe internet network must import the DMZ network (only locally, no-export)\nThe DMZ network provides the default route for tenant's clusters in a partition. It imports the default route from the internet network","category":"page"},{"location":"development/proposals/MEP6/README/#Application-Firewall-2","page":"DMZ Networks","title":"Application Firewall","text":"","category":"section"},{"location":"development/proposals/MEP6/README/","page":"DMZ Networks","title":"DMZ Networks","text":"The firewall of application workloads intersects its private network for attached machines and the DMZ network. ","category":"page"},{"location":"development/proposals/MEP6/README/#Code-Changes-/-Implications","page":"DMZ Networks","title":"Code Changes / Implications","text":"","category":"section"},{"location":"development/proposals/MEP6/README/","page":"DMZ Networks","title":"DMZ Networks","text":"metal-networker and metal-ccm assume that there is only one network providing the default-route\nmetal-networker needs to\nimport the default route from the internet network to the dmz network (DMZ Firewall)\nimport the DMZ network to the internet network and adjusting NAT rules (DMZ Firewall)\nimport destination prefixes of the DMZ network to the private primary network (DMZ Firewall, Application Firewall)\nimport DMZ-IPs of the private primary network to the DMZ network (DMZ Firewall, Application Firewall)\nmetal-api: destination prefixes of private networks need to be configurable (allocateNetwork)\ngardener-extension-provider-metal: needs to be able to delete DMZ clusters (but skip the network deletion part)\nthe application firewall is not publicly reachable - for debugging purposes a hop over the DMZ firewall is needed","category":"page"},{"location":"development/proposals/MEP6/README/#Decision","page":"DMZ Networks","title":"Decision","text":"","category":"section"},{"location":"development/proposals/MEP6/README/","page":"DMZ Networks","title":"DMZ Networks","text":"We decided to follow the second approach with private DMZ networks.","category":"page"},{"location":"external/metalctl/docs/metalctl_size_reservation_describe/#metalctl-size-reservation-describe","page":"metalctl size reservation describe","title":"metalctl size reservation describe","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_reservation_describe/","page":"metalctl size reservation describe","title":"metalctl size reservation describe","text":"describes the reservation","category":"page"},{"location":"external/metalctl/docs/metalctl_size_reservation_describe/","page":"metalctl size reservation describe","title":"metalctl size reservation describe","text":"metalctl size reservation describe [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_size_reservation_describe/#Options","page":"metalctl size reservation describe","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_reservation_describe/","page":"metalctl size reservation describe","title":"metalctl size reservation describe","text":" -h, --help help for describe","category":"page"},{"location":"external/metalctl/docs/metalctl_size_reservation_describe/#Options-inherited-from-parent-commands","page":"metalctl size reservation describe","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_reservation_describe/","page":"metalctl size reservation describe","title":"metalctl size reservation describe","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_size_reservation_describe/#SEE-ALSO","page":"metalctl size reservation describe","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_reservation_describe/","page":"metalctl size reservation describe","title":"metalctl size reservation describe","text":"metalctl size reservation\t - manage reservation entities","category":"page"},{"location":"quickstart/#Getting-Started","page":"Quickstart","title":"Getting Started","text":"","category":"section"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"Before starting to buy any hardware, you should try out the metal-stack on your notebook and familiarize with the software.","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"For this, we made the mini-lab.","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"The mini-lab is a fully virtual setup of metal-stack and is supposed to be run locally on a single machine. For this reason, the setup was slightly simplified in comparison to full-blown setups on real hardware. However, the lab should help to understand all ideas behind the metal-stack.","category":"page"},{"location":"quickstart/","page":"Quickstart","title":"Quickstart","text":"Get your hands dirty and follow the guide on how to get on with the mini-lab here.","category":"page"},{"location":"overview/networking/#Networking","page":"Networking","title":"Networking","text":"","category":"section"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"We spent a lot of time on trying to provide state-of-the-art networking in the data center. This document describes the requirements, ideas and implementation details of the network topology that hosts the metal-stack.","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"The document is separated into three main sections describing the constraints, theoretical ideas and implementation details.","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"Pages = [\"networking.md\"]\nDepth = 5","category":"page"},{"location":"overview/networking/#Requirements","page":"Networking","title":"Requirements","text":"","category":"section"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"Finding the requirements for this greenfield project was kicked off with a handful of design parameters that included:","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"Investigation of the idea of a layer-3 based infrastructure to overcome the drawbacks of traditional layer-2 architectures.\nApplication of a routing technology that involves a single stand-alone protocol BGP for operational simplicity.\nUtilization of the overlay virtual network technology EVPN to support cost-effective scaling, efficient network information exchange and a manageable amount of administration effort.\nApplying the routing topology on top of a completely new physical infrastructure that is designed as a CLOS network topology.","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"Evaluation of those parameters led to more specific requirements:","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"Physical Wiring:\nThe data center is made of a leaf-spine CLOS topology containing:\nleaf switches\nspine switches\nexit switches\nmanagement server\nmanagement switch\ntenant servers\ntenant firewalls.\nBare metal servers are dual-attached to leaf switches. The bare metal servers either become tenant servers or firewalls for a group of tenant servers.\nAll network switches are connected to a management switch. A management server provides access to this management network.\nNetwork Operation Characteristics:\nIPv4 based network.\nNo IPv6 deployment.\nUtilization of external BGP.\nNumbered BGP only for peerings at exit switches with third parties (Internet Service Provider).\nOverall BGP unnumbered.\n4-byte private ASN instead of default 2-byte ASN for BGP.\nNetwork operation relies on SONiC Linux.\nBleeding edge Routing-to-the-Host/EVPN-to-the-Host with ordinary Linux distributions.\nLayer-3 routing using BGP and VXLAN/EVPN.\nEvery VTEP acts as a layer-3 gateway and does routing. Routing is done on both the ingress and the egress VTEP (aka distributed symmetric routing).\nTenant isolation is realized with VRF.\nInternet Access is implemented with route leak on the firewall servers and during the PXE-Process with route leak on the exit switches.\nMTU 9216 is used for VXLAN-facing interfaces, otherwise MTU 9000 is used.","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"Furthermore, requirements such as operational simplicity and network stability that a small group of people can effectively support have been identified being a primary focus for building metal-stack.","category":"page"},{"location":"overview/networking/#Concept","page":"Networking","title":"Concept","text":"","category":"section"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"The theoretical concept targets the aforementioned requirements. New technologies have been evaluated to apply the best solutions. The process was heavily inspired by the work of Dinesh G. Dutt regarding BGP (bgp-ebook) and EVPN (evpn-ebook).","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"External BGP together with network overlay concepts as EVPN can address the essential demands. These revolutionary concepts are part of the next evolutionary step in data center design. It overcomes common issues of traditional layer 2 architectures (e.g. VLAN limitations, network visibility for operations, firewall requirements) by introducing a layer 3 based network topology.","category":"page"},{"location":"overview/networking/#CLOS","page":"Networking","title":"CLOS","text":"","category":"section"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"A CLOS topology is named after the pioneer Charles Clos (short: CLOS) who first formalized this approach. CLOS defines a multistage network topology that is used today to improve performance and resilience while enabling a cost effective scalability. A CLOS topology comprises network switches aggregated into spine and leaf layers. Each leaf switch (short: leaf) is connected to all spine switches (short: spine) but there is no direct leaf-to-leaf or spine-to-spine connection (See: picture 1).","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"(Image: 2 Layer CLOS Topology)","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"Picture 1: Fragment of CLOS to show leaf-spine layer.","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"This data center network architecture, based on a leaf-spine architecture, is also know as \"two-tier\" CLOS topology.","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"(Image: 3 Layer CLOS Topology)","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"Picture 2: Fragment to show a 3-stage, 2-layer CLOS topology.","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"Tenant servers are dual-attached to the leaf layer in order to have redundancy and load balancing capability (Picture 2). The set of leaves, spine switches and tenant servers define stages. From top down each server is reachable with 3 hops (spine -> leaf -> server). This is why that CLOS design is called a 3-stage CLOS. Consistent latency throughout the data center are an outcome of this design.","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"It is not only important to have a scalable and resilient infrastructure but also to support planning and operation teams. Visibility within the network is of significant meaning for them. Consequently layer-3 routing in favor of layer-2 bridging provides this kind of tooling.","category":"page"},{"location":"overview/networking/#BGP","page":"Networking","title":"BGP","text":"","category":"section"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"For routing the Border Gateway Protocol (BGP), more specific: External BGP was selected. Extensive testing and operational experiences have shown that External BGP is well suited as a stand-alone routing protocol (see: RFC7938).","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"Not all tenant servers are connected to the same leaf. Instead they can be distributed among any of the leaves of the data center. To not let this detail restrict the intra-tenant communication it is required to interconnect those layer-2 domains. In the context of BGP there is a concept of overlay networking with VXLAN/ EVPN that was evaluated to satisfy the needs of the metal-stack.","category":"page"},{"location":"overview/networking/#BGP-Unnumbered","page":"Networking","title":"BGP Unnumbered","text":"","category":"section"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"In BGP traditionally each BGP peer-facing interface requires a separate IPv4 address. This consumes a lot of IP addresses. RFC 5549 defines the BGP unnumbered standard. It allows to use interface's IPv6 link local address (LLA) to set up a BGP session with a peer. With BGP unnumbered the IPv6 LLA of the remote is automatically discovered via Router Advertisement (RA) protocol. Important: This does not (!) mean that IPv6 must be deployed in the network. BGP uses RFC 5549 to encode IPv4 routes as reachable over IPv6 next-hop using the LLA. Having unnumbered interfaces does not mean no IPv4 address may be in place. It is a good practice to configure an IP address to the never failing and always present local loopback interface (lo). This lo address is reachable over BGP from other peers because the RFC 5549 standard provides an encoding scheme to allow a router to advertise IPv4 routes with an IPv6 next-hop. BGP unnumbered also has an advantage from security perspective. It removes IPv4 and global IPv6 addresses from router interfaces, thus reducing the attack vector.","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"To sum it up:","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"BGP unnumbered uses IPv6 next-hops to announce IPv4 routes.\nThere is no IPv6 deployment in the network required.\nIPv6 just has to be enabled on the BGP peers to provide LLA and RA.","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"In BGP, ASN is how BGP peers know each other.","category":"page"},{"location":"overview/networking/#ASN-Numbering","page":"Networking","title":"ASN Numbering","text":"","category":"section"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"Within the data center each BGP router is identified by a private autonomous system number (ASN). This ASN is used for internal communication. The default is to have 2-byte ASN. To avoid having to find workarounds in case the ASN address space is exhausted, a 4-byte ASN that supports up to 95 million ASNs (4200000000–4294967294) is used from the beginning.","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"ASN numbering in a CLOS topology should follow a model to avoid routing problems (path hunting) due to it's redundant nature. Within a CLOS topology the following ASN numbering model is suggested to solve path hunting problems:","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"Leaves have unique ASN\nSpines share an ASN\nExit switches share an ASN","category":"page"},{"location":"overview/networking/#Address-Families","page":"Networking","title":"Address-Families","text":"","category":"section"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"As stated, BGP is a multi-protocol routing protocol. Since it is planned to use IPv4 and overlay networks using EVPN/VXLAN several address-families have to be activated for the BGP sessions to use:","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"IPv4 unicast address-family\nL2 EVPN address-family","category":"page"},{"location":"overview/networking/#EVPN","page":"Networking","title":"EVPN","text":"","category":"section"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"Ethernet VPN (EVPN) is an overlay virtual network that connects layer-2 segments over layer-3 infrastructure. EVPN is an answer to common problems of entire layer-2 data centers.","category":"page"},{"location":"overview/networking/#Why-do-we-need-EVPN","page":"Networking","title":"Why do we need EVPN","text":"","category":"section"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"Challenges such as large failure domains, spanning tree complexities, difficult troubleshooting and scaling issues are addressed by EVPN:","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"administration: less routers are involved in configuration (with VLAN every switch on routing-paths needs VLAN awareness). The configuration is less error prone due to the nature of EVPN and the good support in FRR.\nscaling: EVPN overcomes scaling issues with traditional VLANs (max. 4094 VLANs).\ncost-effectiveness: EVPN is an overlay virtual network. Not every switch on the routing path needs EVPN awareness. This enables the use of standard routers (in contrast to traditional VLAN); e.g.: spine switches act only as evpn information replicator and do not need to have knowledge of specific virtual networks.\nefficiency: EVPN information is exclusively exchanged via BGP (Multiprotocol BGP). Only a single eBGP session is needed to advertise layer-2 reachability. No other protocols beneath BGP are involved and flood traffic is reduced to a minimum (no \"flood-and-learn\", no BUM traffic).","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"Virtual routing permits multiple network paths without the need of multiple switches. Hence the servers are logically isolated by assigning their networks to dedicated virtual routers using virtual routing and forwarding (short: VRF).","category":"page"},{"location":"overview/networking/#How-do-we-use-EVPN","page":"Networking","title":"How do we use EVPN","text":"","category":"section"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"EVPN (technology) is based on BGP as control plane protocol (underlay) and VXLAN as data plane protocol (overlay).","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"As EVPN is an overlay network, only the VXLAN Tunnel End Points (VTEPs) must be configured. In the case of two-tier CLOS networks leaf switches are tunnel endpoints.","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"In EVPN routing is assumed to occur in the context of a VRF. VRF enables true multitenancy. Therewith, VRF is the first step for EVPN configuration and there is a 1:1 relationship between tenant and VRF.","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"To enable layer-2 connectivity, we need a special interface to route between layer-2 networks. This interface is called Switched VLAN Interface (SVI). The SVI is realized with a VLAN. It is part of a VRF (layer-3).","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"The VTEP configuration requires the setup of a VXLAN interface. A VLAN aware bridge interconnects the VXLAN interface and the SVI.","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"Required Interfaces to establish the EVPN control plane:","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"VRF: because routing happens in the context of this interface.\nSVI: because remote host routes for symmetric routing are installed over this interface.\nVLAN-aware bridge: because router MAC addresses of remote VTEPs are installed over this interface.\nVXLAN Interface / VXLAN Tunnel Endpoint: because the VRF to layer-3 VNI mapping has to be consistent across all VTEPs)","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"(Image: EVPN VTEP)","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"Picture 3: Required interfaces on the switch to wire up the vrf to swp 1 connectivity with a given vxlan","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"Integrated routing and bridging (IRB) is the most complex part of EVPN. You could choose between centralized or distributed routing, and between asymmetrical (routing on ingress) or symmetrical (routing on ingress and egress) routing. We expect a lot of traffic within the data center itself which implies the need to avoid zigzag routing. This is why we go with distributed routing model. Further it is recommended to use the symmetric model since it makes the cut in most cases and has advantages in scalability (see \"EVPN in the Data Center\", Dinesh G. Dutt).","category":"page"},{"location":"overview/networking/#MTU","page":"Networking","title":"MTU","text":"","category":"section"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"In a layer-3 network it is important to associate each interface with a proper Maximum Transmission Unit (MTU) to avoid fragmentation of IP packets. Typical modern networks do not fragment IP packets and the introduction of VXLAN adds another additional header to the packets that must not exceed the MTU. If the MTU is exceeded, VXLAN might just fail without error. This already represents a difficult-to-diagnose connectivity issue that has to be avoided.","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"It is common practice to set the MTU for VXLAN facing interfaces (e.g. inter-switch links) to a value of 9216 to compensate the additional VXLAN overhead and an MTU of 9000 as a default to other interfaces (e.g. server facing ports). The common MTU of 1500 is not sufficient for traffic inside a data center!","category":"page"},{"location":"overview/networking/#VRF","page":"Networking","title":"VRF","text":"","category":"section"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"Routing is needed for communication between VXLAN tunnels or between a VXLAN tunnel and an external networks. VXLAN routing supports layer-3 multi-tenancy. All routing occurs in the context of a VRF. There is a 1:1 relation of a VRF to a tenant. Picture 3 illustrates this. Servers A and B belong to the same vrf VRF1. Server C is enslaved into VRF2. There is no communication possible between members of VRF1 and those of VRF2.","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"(Image: Two routing tables)","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"Picture 4: Illustration of two distinct routing tables of VRF1 (enslaved: servers A and B) and VRF2 (enslaved: server C)","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"To leaverage the potential and power of BGP, VRF, EVPN/VXLAN without a vendor lock-in the implementation relies on hardware that is supported by open network operating system: SONiC.","category":"page"},{"location":"overview/networking/#Implementation","page":"Networking","title":"Implementation","text":"","category":"section"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"Implementation of the network operation requires the data center infrastructure to be in place. To implement a functional meaning for the parts of the CLOS network, all members must be wired accordingly.","category":"page"},{"location":"overview/networking/#Physical-Wiring","page":"Networking","title":"Physical Wiring","text":"","category":"section"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"Reference: See the CLOS overview picture in ./README.md.","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"Name Wiring\nTenant server (aka Machine) Bare metal server that is associated to a tenant. Dual-connected to leafs.\nTenant firewall Bare metal server that is associated to a tenant. Dual-connected to leafs.\nLeaf Network Switch that interconnects tenant servers and firewalls. Connected to spines.\nSpine Network switch that interconnects leafs and exit switches.\nExit Network switch that connects to spines and interconnects to external networks.\nManagement Server Jump-host to access all network switches within the CLOS topology for administrative purpose.\nManagement Switch Connected to the management port of each of the network switches.","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"Tenant servers are organized into a layer called projects. In case those tenant servers require access to or from external networks, a new tenant server to function as a firewall is created. Leaf and spine switches form the fundament of the CLOS network to facilitate redundancy, resilience and scalability. Exit switches establish connectivity to or from external networks. Management Switch and Management Server are mandatory parts that build a management network to access the network switches for administration.","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"To operate the CLOS topology, software defined configuration to enable BGP, VRF, EVPN and VXLAN must be set up.","category":"page"},{"location":"overview/networking/#Network-Operating-Systems","page":"Networking","title":"Network Operating Systems","text":"","category":"section"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"SONiC as the network operating system will be installed on all network switches (leaves, spines, exit switches) within the CLOS topology. SONiC cannot be installed on bare metal servers that require BGP/EVPN but does not have a switching silicon.","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"Components without a switching silicon are:","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"tenant servers\ntenant firewalls\nmanagement server","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"There exist two paradigms to use BGP and/or VXLAN/EVPN on non switching bare metal servers: BGP-to-the-host and EVPN-to-the-host. Both describe a setup of Free Range Routing Framework (see frrouting.org) and its configuration. FRR seamlessly integrates with the native Linux IP networking stacks.","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"Starting with an explanation of the tenant server's BGP-to-the-Host helps to get an insight into the setup of the CLOS network from a bottom-up perspective.","category":"page"},{"location":"overview/networking/#Tenant-Servers:-BGP-to-the-Host","page":"Networking","title":"Tenant Servers: BGP-to-the-Host","text":"","category":"section"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"Tenant servers are dual-connected to leaf switches. To communicate with other servers or reach out to external networks they must join a BGP session with each of the leaf switches. Thus, it is required to bring BGP to those hosts (aka BGP-to-the-Host). Each tenant server becomes a BGP router (aka BGP speaker).","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"BGP-to-the-Host is established by installing and configuring FRR. The required FRR configuration for tenant servers is limited to a basic setup to peer with BGP next-hops:","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"# /etc/network/interfaces\n\nauto lo\niface lo inet static\n address 10.0.0.1/32\n\nauto lan0\niface lan0 inet6 auto\n mtu 9000\n\nauto lan1\niface lan1 inet6 auto\n mtu 9000","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"Listing 1: Network interfaces of a tenant server.","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"Listing 1 shows the local interfaces configuration. lan0 and lan1 connect to the leaves. As described, there is no IPv4 address assigned to them (BGP unnumbered). The local loopback has an IPv4 address assigned that is announced by BGP.","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"The required BGP configuration:","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"# /etc/frr/frr.conf\n\nfrr version 7.0\nfrr defaults datacenter\nlog syslog debugging\nservice integrated-vtysh-config\n!\ninterface lan0\n ipv6 nd ra-interval 6\n no ipv6 nd suppress-ra\n!\ninterface lan1\n ipv6 nd ra-interval 6\n no ipv6 nd suppress-ra\n!\nrouter bgp 4200000001\n bgp router-id 10.0.0.1\n bgp bestpath as-path multipath-relax\n neighbor TOR peer-group\n neighbor TOR remote-as external\n neighbor TOR timers 1 3\n neighbor lan0 interface peer-group TOR\n neighbor lan1 interface peer-group TOR\n neighbor LOCAL peer-group\n neighbor LOCAL remote-as internal\n neighbor LOCAL timers 1 3\n neighbor LOCAL route-map local-in in\n bgp listen range 10.244.0.0/16 peer-group LOCAL\n address-family ipv4 unicast\n redistribute connected\n neighbor TOR route-map only-self-out out\n exit-address-family\n!\nbgp as-path access-list SELF permit ^$\n!\nroute-map local-in permit 10\n set weight 32768\n!\nroute-map only-self-out permit 10\n match as-path SELF\n!\nroute-map only-self-out deny 99\n!","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"Listing 2: FRR configuration of a tenant server.","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"The frr configuration in Listing 2 starts with frr defaults datacenter. This is a marker that enables compile-time provided settings that e.g. set specific values for BGP session timers. This is followed by a directive to state that instead of several configuration files for different purposes a single frr.conf file is used: service integrated-vtysh-config. The two interface specific blocks starting with interface ... enable the RA mechanism that is required for BGP unnumbered peer discovery. There is a global BGP instance configuration router bgp 4200000001 that sets the private ASN. The BGP router configuration contains a setup that identifies the BGP speaker bgp router-id 10.0.0.1. This router id should be unique. It is a good practice to assign the local loopback IPv4 as router-id. To apply the same configuration to several interfaces a peer group named TOR is defined via neighbor TOR peer-group. remote-as external activates external BGP for this peer group. To have a fast convergence, limits of default timers are reduced by timer 1 3 section. The two BGP-peer-facing interfaces are enslaved into the peer-group to inherit the peer-group's setup. Activation of IPv4 unicast protocol is completed with address-family ipv4 unicast. To prevent a tenant server from announcing other paths than lo interface a route-map only-self-out is defined. This route map is activated within the ipv4 address family: neighbor TOR route-map only-self-out out.","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"Application of the route map only-self-out enables to announce only local ip(s). This is to avoid that a tenant server announces paths to other servers (prevents unwanted traffic). To achieve this:","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"the route-map named only-self-out permits only matches against an access list named SELF\naccess list SELF permits only empty path announcements\nthe path of the tenant server itself has no ASN. It is always empty (see line *> 10.0.0.2/32 0.0.0.0 0 32768 ?):\nroot@machine:~# vtysh -c 'show bgp ipv4 unicast'\nBGP table version is 7, local router ID is 10.0.0.2, vrf id 0\nDefault local pref 100, local AS 4200000002\nStatus codes: s suppressed, d damped, h history, * valid, > best, = multipath,\n i internal, r RIB-failure, S Stale, R Removed\nNexthop codes: @NNN nexthop's vrf id, < announce-nh-self\nOrigin codes: i - IGP, e - EGP, ? - incomplete\n\n Network Next Hop Metric LocPrf Weight Path\n*= 0.0.0.0/0 lan1 0 4200000012 4200000040 i\n*> lan0 0 4200000011 4200000040 i\n*= 10.0.0.1/32 lan1 0 4200000012 4200000001 ?\n*> lan0 0 4200000011 4200000001 ?\n*> 10.0.0.2/32 0.0.0.0 0 32768 ?\n*= 10.0.0.78/32 lan1 0 4200000012 4200000001 ?\n*> lan0 0 4200000011 4200000001 ?\n\nDisplayed 4 routes and 7 total paths\nThat is why only the self ip (loopback ip) is announced.","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"To allow for peering between FRR and other routing daemons on a tenant server a listen range is specified to accept iBGP sessions on the network 10.244.0.0/16. Therewith it gets possible that pods / containers like metal-lb with IPs of this range may peer with FRR.","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"This is the only place where we use iBGP in our topology. For local peering this has the advantage, that we don't need an additional ASN that has to be handled / pruned in the AS-path of routes. Routes coming from other routing daemons look as if they are configured on the tenant server's lo interface from the viewpoint of the leaves. iBGP routes are differently handled than eBGP routes in BGPs best path algorithm. Generally BGP has the rule to prefer eBGP routes over iBGP routes (s. 'eBGP over iBGP' ). BGP adds automatically an weight based on the route type. To overcome this issue, we set the weight of iBGP routes to the same weight that eBGP routes have, namely 32768 (set weight 32768). Without this configuration we will only get a single route to the IPs announced via iBGP. So this setting is essential for HA/failover!","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"Statistics of the established BGP session can be viewed locally from the tenant server via: sudo vtysh -c 'show bgp ipv4 unicast'","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"To establish this BGP session a BGP setup is required on the leaves as well.","category":"page"},{"location":"overview/networking/#Leaf-Setup","page":"Networking","title":"Leaf Setup","text":"","category":"section"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"Every leaf switch is connected to every spine switch. Tenant servers can be distributed within the data center and thus be connected to different leaves. Routing for tenant servers is isolated in unique VRFs. These constraints imply several configuration requirements for the leaf and spine switches:","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"leaves define tenant VRFs\nleaves terminate VXLAN tunnels (aka \"VXLAN tunnel endpoint\" = VTEP)","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"The leaf setup requires the definition of a tenant VRF that enslaves the tenant server facing interfaces:","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"# /etc/network/interfaces\n\n# [...]\n\niface vrf3981\n vrf-table auto\n\niface swp1\n mtu 9000\n post-up sysctl -w net.ipv6.conf.swp1.disable_ipv6=0\n vrf vrf3981\n\n# [...]","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"Listing 3: Fragment that shows swp1 being member of vrf vrf3981.","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"There is a VRF definition iface vrf3981 to create a distinct routing table and a section vrf vrf3981 that enslaves swp1 (connects the tenant server) into the VRF. Those host facing ports are also called edge ports.","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"Unfortunately, due to a kernel bug, IPv6 is not reliably enabled, so it is enforced explicitly via post-up sysctl -w net.ipv6.conf.swp1.disable_ipv6=0. If this post-up trigger is missing the LLA of the interface might be absent.","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"Additional to the VRF definition the leaf must be configured to provide and connect a VXLAN interface to establish a VXLAN tunnel. This network virtualization begins at the leaves. Therefore, the leaves are also called Network Virtualization Edges (NVEs). The leaves encapsulate and decapsulate VXLAN packets.","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"# /etc/network/interfaces\n\n# [...]\n\niface bridge\n bridge-ports vni3981\n bridge-vids 1001\n bridge-vlan-aware yes\n\niface vlan1001\n mtu 9000\n vlan-id 1001\n vlan-raw-device bridge\n vrf vrf3981\n\niface vni3981\n mtu 9000\n bridge-access 1001\n bridge-arp-nd-suppress on\n bridge-learning off\n mstpctl-bpduguard yes\n mstpctl-portbpdufilter yes\n vxlan-id 3981\n vxlan-local-tunnelip 10.0.0.11\n\n# [...]","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"Listing 4: Fragment that shows VXLAN setup for vrf vrf3981.","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"All routing happens in the context of the tenant VRF. To send and receive packets of a VRF, several interface are in place.","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"A bridge is used to attach VXLAN interface bridge-ports vni3981 and map its local VLAN to a VNI. Router MAC addresses of remote VTEPs are installed over this interface.","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"The Routed VLAN Interface or Switched Virtual Interface (SVI) iface vlan1001 is configured corresponding to the per-tenant VXLAN interface. It is attached to the tenant VRF. Remote host routes are installed over this SVI. The vlan-raw-device bridge is used to associate the SVI with the VLAN aware bridge. For a packet received from a locally attached host the SVI interface corresponding to the VLAN determines the VRF vrf vrf3981.","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"The VXLAN interface iface vni3981 defines a tunnel address that is used for the VXLAN tunnel header vlxan-local-tunnelip 10.0.0.11. This VTEP IP address is typically the loopback device address of the switch. When EVPN is provisioned, data plane MAC learning for VXLAN interfaces must be disabled because the purpose of EVPN is to exchange MACs between VTEPs in the control plane: bridge-learning off. EVPN is responsible for installing remote MACs. bridge-arp-nd-suppress suppresses ARP flooding over VXLAN tunnels. Instead, a local proxy handles ARP requests received from locally attached hosts for remote hosts. ARP suppression is the implementation for IPv4; ND suppression is the implementation for IPv6. It is recommended to enable ARP suppression on all VXLAN interfaces. Bridge Protocol Data Unit (BPDU) are not transmitted over VXLAN interfaces. So as a good practice bpduguard and pbdufilter are enabled with mstpctl-bpduguard yes and mstpctl-portbpdufilter yes. These settings filter BPDU and guard the spanning tree topology from unauthorized switches affecting the forwarding path. vxlan-id 3981 specifies the VXLAN Network Identifier (VNI). The type of VNI can either be layer-2 (L2) or layer-3 (L3). This is an implicit thing. A VNI is a L3 VNI (L3VNI) when a mapping exists that maps the VNI to a VRF (configured in /etc/frr/frr.conf) otherwise it is a L2 VNI (L2VNI).","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"# /etc/frr/frr.conf\n# [...]\nvrf vrf3981\n vni 3981\n exit-vrf\n#[...]\nrouter bgp 4200000011\n# [...]\n address-family ipv4 unicast\n redistribute connected route-map LOOPBACKS\n # [...]\n address-family l2vpn evpn\n neighbor FABRIC activate\n advertise-all-vni\n exit-address-family\n# [...]\nrouter bgp 4200000011 vrf vrf3981\n # [...]\n address-family ipv4 unicast\n redistribute connected\n neighbor MACHINE maximum-prefix 100\n exit-address-family\n !\n address-family l2vpn evpn\n advertise ipv4 unicast\n exit-address-family\n\n# [...]\nroute-map LOOPBACKS permit 10\n match interface lo\n# [...]","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"Listing 5: Leaf FRR configuration.","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"Listing 5 shows the required FRR configuration of the BGP control plane. Only content not discussed so far is explained. The section vrf vrf3981 contains the mapping from layer-3 VNI to VRF. This is required to be able to install EVPN IP prefix routes (type-5 routes) into the routing table. Further the file contains a global BGP instance router bgp 4200000011 definition. A new setting redistribute connected route-map LOOPBACKS is in place to filter the redistribution of routes that are not matching the local loopback interface. The route-map is defined with route-map LOOPBACKS permit 10. With the configuration line address-family l2vpn evpn, the EVPN address family is enabled between BGP neighbours. advertise-all-vni makes the switch a VTEP configures it in such a way, that all locally configured VNIs should be advertised by the BGP control plane.","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"The second BGP instance configuration is specific to the tenant VRF router bgp 4200000011 vrf vrf3981. This VRF BGP instance configures the l2vpn evpn address family with advertise ipv4 unicast to announce IP prefixes in BGP's routing information base (RIB). This is required to apply learned routes to the routing tables of connected hosts. The Maximum-Prefix feature is useful to avoid that a router receives more routes than the router memory can take. The maximum number of prefixes a tenant server is allowed to announce is limited to 100 with: neighbor MACHINE maximum-prefix 100.","category":"page"},{"location":"overview/networking/#Spine-setup","page":"Networking","title":"Spine setup","text":"","category":"section"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"On the spine switches the setup is quite simple. /etc/network/interfaces contains the loopback interface definition to support BGP unnumbered and listings for connected switch ports to provide proper MTUs (Listing 6). I.e. swp1 is configured with an MTU of 9216 as it is a VXLAN-facing interface.","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"# /etc/network/interfaces\n# [...]\niface swp1\n mtu 9216","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"Listing 6: Fragment of spine interface configuration.","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"The spines are important to forward EVPN routes and transport VXLAN packets between the VTEPs. They are not configured as VTEPs. The FRR configuration only contains the already known global BGP instance configuration router bgp 4200000020 plus the activation of the l2vpn evpn address family address-family l2vpn evpn to enable EVPN type-5 route forwarding (Listing 7).","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"hostname spine01\nusername admin nopassword\n!\n# [...]\ninterface swp1\n ipv6 nd ra-interval 6\n no ipv6 nd suppress-ra\n!\n# [...]\n!\nrouter bgp 4200000020\n # [...]\n!\n address-family l2vpn evpn\n neighbor FABRIC activate\n exit-address-family\n!\n# [...]","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"Listing 7: Fragment of spine FRR configuration to show the activated L2VPN EVPN address-family.","category":"page"},{"location":"overview/networking/#Tenant-Firewalls:-EVPN-to-the-Host","page":"Networking","title":"Tenant Firewalls: EVPN-to-the-Host","text":"","category":"section"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"In case a tenant server needs to reach out to external networks as the Internet, a tenant firewall is provisioned. The firewall is a bare metal server without a switching silicon. Thus, there is no installation of SONiC. FRR provides the BGP / EVPN functionality known as EVPN-to-the-host. The firewall is configured as a VTEP and applies dynamic route-leaking to install routes of an foreign VRF. The set of routes that are leaked are restricted with route-maps.","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"As Listing 8 shows, the firewall is configured with VXLAN interfaces as known from the leaf setup. Additionally, a VXLAN setup for VRF vrfInternet is added to provide Internet access. vrfInternet contains a route to the Internet that will be leaked into the tenant VRF.","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"Traffic that originates from the tenant network 10.0.0.0/22 will be masqueraded before leaving the interface vlanInternet towards the internet.","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"# /etc/network/interfaces\n# [...]\niface bridge\n# [...]\niface vlan1001\n# [...]\niface vni3981\n# [...]\niface vrf3981\n# [...]\niface vlanInternet\n mtu 9000\n vlan-id 4009\n vlan-raw-device bridge\n vrf vrfInternet\n address 185.1.2.3\n post-up iptables -t nat -A POSTROUTING -s 10.0.0.0/22 -o vlanInternet -j MASQUERADE\n pre-down iptables -t nat -D POSTROUTING -s 10.0.0.0/22 -o vlanInternet -j MASQUERADE\n\niface vniInternet\n mtu 9000\n bridge-access 4009\n mstpctl-bpduguard yes\n mstpctl-portbpdufilter yes\n vxlan-id 104009\n vxlan-local-tunnelip 10.0.0.40\n\niface vrfInternet\n mtu 9000\n vrf-table auto","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"Listing 8: Interfaces configuration of firewall to show the VTEP interface configuration.","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"To install a default route into the routing table of tenant VRF vrf3981 a dynamic route leak is established for it (import vrf vrfInternet). With the help of a route-map import vrf route-map vrf3981-import-map only the default route will be leaked:","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"root@firewall01:~# vtysh -c 'show ip route vrf vrf3981'\n# [...]\nVRF vrf3981:\nS>* 0.0.0.0/0 [1/0] is directly connected, vrfInternet(vrf vrfInternet), 03:19:26\nB>* 10.0.0.1/32 [20/0] via 10.0.0.12, vlan1001 onlink, 02:34:48\n * via 10.0.0.11, vlan1001 onlink, 02:34:48\nB>* 10.0.0.2/32 [20/0] via 10.0.0.12, vlan1001 onlink, 02:34:49\n * via 10.0.0.11, vlan1001 onlink, 02:34:49","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"To receive responses from vrfInternet in vrf3981 a route is leaked into vrfInternet as well (import vrf vrf3981) restricted with the route-map vrfInternet-import-map that allows leaking of the tenant routes as well as internet prefixes used on worker nodes of the tenant. To limit the prefixes that are announced from the firewall within the global BGP instance a route-map only-self-out is defined and applied within the ipv4 and l2vpn evpn address family. Together with the definition of an as path access list bgp as-path access-list it avoids the announcement of prefixes to non VRF BGP peers.","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"# /etc/frr/frr.conf\n!\nvrf vrf3981\n vni 3981\n!\nvrf vrfInternet\n vni 104009\n!\n# [...]\n!\nrouter bgp 4200000040\n # [...]\n !\n address-family ipv4 unicast\n # [...]\n neighbor FABRIC route-map only-self-out out\n exit-address-family\n !\n!\nrouter bgp 4200000040 vrf vrf3981\n # [...]\n address-family ipv4 unicast\n redistribute connected\n import vrf vrfInternet\n import vrf route-map vrf3981-import-map\n # [...]\n address-family l2vpn evpn\n advertise ipv4 unicast\n # [...]\nrouter bgp 4200000040 vrf vrfInternet\n # [...]\n address-family ipv4 unicast\n redistribute connected\n import vrf vrf3981\n import vrf route-map vrfInternet-import-map\n # [...]\n address-family l2vpn evpn\n advertise ipv4 unicast\n # [...]\n bgp as-path access-list SELF permit ^$\n!\nroute-map only-self-out permit 10\n match as-path SELF\n!\nroute-map only-self-out deny 99\n!\nroute-map LOOPBACKS permit 10\n match interface lo\n!\nip prefix-list vrf3981-import-prefixes seq 100 permit 0.0.0.0/0\n!\nroute-map vrf3981-import-map permit 10\n match ip address prefix-list vrf3981-import-prefixes\n!\nroute-map vrf3981-import-map deny 99\n!\nip prefix-list vrfInternet-import-prefixes seq 100 permit 10.0.0.0/22 le 32\nip prefix-list vrfInternet-import-prefixes seq 101 permit 185.1.2.0/24 le 32\nip prefix-list vrfInternet-import-prefixes seq 102 permit 185.27.0.0/27 le 32\n!\nroute-map vrfInternet-import-map permit 10\n match ip address prefix-list vrfInternet-import-prefixes\n!\nroute-map vrfInternet-import-map deny 99\n!\nline vty\n!","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"Listing 9: FRR configuration of a tenant firewall to show route leak and prefix announcement filtering.","category":"page"},{"location":"overview/networking/#Exit-Switch","page":"Networking","title":"Exit Switch","text":"","category":"section"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"Traffic to external networks is routed via the firewalls to the exit switch. The exit switch, as an exception, connects to the Internet Service Provider using numbered BGP. Numbered BGP implies to assign IPv4 addresses to network interfaces (See Listing 10, swp1). Interface swp1 is enslaved into vrf vrfInternet to include the port that is connected to the ISP within the VRF that is expected to contain a way into the Internet. The exit switch is configured to be a VTEP to terminate traffic coming from the firewall VRF vrfInternet.","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"# /etc/network/interfaces\n# [...]\niface swp1\n mtu 9000\n vrf vrfInternet\n address 172.100.0.2/30\n# [...]\niface vlan4000\n mtu 9000\n address 10.0.0.71/24\n vlan-id 4000\n vlan-raw-device bridge\n# [...]\niface vlanInternet\n# [...]\niface vniInternet\n# [...]\niface vrfInternet\n# [...]","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"Listing 10: Fragment of interfaces configuration of exit switch.","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"The configuration of FRR is equivalent to the previously discussed ones. It contains a global BGP instance configuration that enables IPv4 unicast and l2vpn evpn address families. The vrfInternet BGP instance defines neighbor 172.100.0.1 peer-group INTERNET to use \"old style BGP\" transit network.","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"# [..]\nvrf vrfInternet\n vni 104009\n!\n# [...]\nrouter bgp 4200000031\n bgp router-id 10.0.0.31\n neighbor FABRIC peer-group\n neighbor FABRIC remote-as external\n neighbor FABRIC timers 1 3\n # [...]\n !\n address-family ipv4 unicast\n neighbor FABRIC activate\n redistribute connected route-map LOOPBACKS\n exit-address-family\n !\n address-family l2vpn evpn\n neighbor FABRIC activate\n advertise-all-vni\n exit-address-family\n!\nrouter bgp 4200000031 vrf vrfInternet\n bgp router-id 10.0.0.31\n bgp bestpath as-path multipath-relax\n neighbor INTERNET peer-group\n neighbor INTERNET remote-as external\n neighbor INTERNET timers 1 3\n neighbor 172.100.0.1 peer-group INTERNET\n !\n address-family ipv4 unicast\n neighbor INTERNET route-map PREPEND-PATH-TO-DISFAVOR-IN in\n neighbor INTERNET route-map PREPEND-PATH-TO-DISFAVOR-OUT out\n exit-address-family\n\n !\n address-family l2vpn evpn\n advertise ipv4 unicast\n exit-address-family\n!\nroute-map LOOPBACKS permit 10\n match interface lo\n!\nroute-map PREPEND-PATH-TO-DISFAVOR-IN permit 10\n set as-path prepend last-as 2\n!\nroute-map PREPEND-PATH-TO-DISFAVOR-OUT permit 10\n set as-path prepend last-as 2\n!\nvrf mgmt\n ip route 10.0.0.0/24 10.0.0.71 nexthop-vrf default\n exit-vrf\n!\nip route 0.0.0.0/0 192.168.0.254 nexthop-vrf mgmt\n!\nline vty\n!","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"Listing 11: Fragment of FRR configuration on exit switch to give an example for numbered BGP and route leak.","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"In addition to the standard BGP setup the exit switches have configured static route leak to support internet access during PXE. There is one route leak from default VRF into the mgmt VRF defined with: ip route 0.0.0.0/0 192.168.0.254 nexthop-vrf mgmt and another one from mgmt VRF into the default VRF: ip route 10.0.0.0/24 10.0.0.71 nexthop-vrf default. The first one adds a default route into the default VRF and the second one routes traffic destined to the PXE network back from mgmt VRF into the default VRF.","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"To reach out into external networks each of the exit nodes joins a BGP session with a distinct external router. There is a different latency to each of these routers. To favor routes of exit nodes connected with lower latency over exit nodes with higher latency two route maps PREPEND-PATH-TO-DISFAVOR-IN and PREPEND-PATH-TO-DISFAVOR-OUT are added to high latency exit nodes. These route maps apply actions to prolong the path of the incoming and outgoing routes. Because of this path extension BGP will calculate a lower weight for these paths and favors paths via other exit nodes. It is important to know that within an address family only one route map (the last) will be applied. To apply more than one actions within a route-map the required entries can be applied to a single route-map.","category":"page"},{"location":"overview/networking/#PXE-Boot-Mode","page":"Networking","title":"PXE Boot Mode","text":"","category":"section"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"Before a bare metal server can act as tenant server or tenant firewall, it has to be provisioned. Within the Metal domain, this provisioning mode is called \"PXE Mode\" since it is based on Preboot eXecution Environment (PXE). PXE uses protocols like DHCP. This requires all bare metal servers that need provisioning to be located in a layer-2 domain where DHCP is available. This domain is a VLAN vlan4000. A DHCP server for PXE Mode is installed on the exit switches to work in this specific VLAN.","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"# /etc/default/isc-dhcp-server\nINTERFACES=\"vlan4000\"","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"Listing 13: DHCP server configuration of exit switches.","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"As shown in listing 13, the PXE DHCP server is located on the exit switches and enforced to bind to interface vlan4000. This represents a layer-2 separation that allows only DHCP clients in the same VLAN to request IP addresses. Only unprovisionned bare metal servers are configured to be member of this VLAN. Thus unwanted or accidental provisionning is impossible.","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"To provide vlan4000 on the leaves (that face the bare metal servers) the exit and leaf switches are configured as VTEPs and share an interface configuration that contains the required interfaces (Listing 13). Since no EVPN routing is in place vni104000 is configured as an L2 VNI (there is no mapping for this VNI in /etc/frr/frr.conf).","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"# /etc/network/interfaces\n# [...]\niface bridge\n bridge-ports vni104000 [...]\n bridge-vids 4000 [...]\n bridge-vlan-aware yes\n\niface vlan4000\n# [...]\n\niface vni104000\n# [...]","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"Listing 13: Interfaces configuration on exit and leaf switches to show DHCP/PXE related fragments.","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"On the leaf switches the bare metal server facing ports are configured as VLAN access ports to carry the traffic for only the PXE VLAN vlan4000 (listing 14)to separate unprovisioned from other bare metal servers.","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"# /etc/network/interfaces\n# [...]\nauto swp1\niface swp1\n mtu 9000\n bridge-access 4000\n# [...]","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"Listing 14: VLAN access setup for bare metal server facing ports on leaves.","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"Once a bare metal server is provisioned it is deconfigured from PXE VLAN vlan4000 to avoid accidental or unwanted provisioning.","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"During provisioning bare metal servers get internet access via the management network of the exit switches. This is because the exit switches are announced as DHCP gateway to the DHCP clients.","category":"page"},{"location":"overview/networking/#Management-Network","page":"Networking","title":"Management Network","text":"","category":"section"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"To manage network switches beside the out-of-band system console access a further management access is required. For this purpose the concept of Management VRF is applied. The Management VRF is a subset of VRF. It provides a separation between out-of-band management network and the in-band data plane network by introducing another routing table mgmt. SONiC supports eth0 to be used as the management interface.","category":"page"},{"location":"overview/networking/","page":"Networking","title":"Networking","text":"To enable and use the Management VRF all switches have to be connected via their eth0 interface to a management-switch. The management switch is connected to a management server. All access is established from within the management server. Logins to the switch are set into the Management VRF context once the Management VRF is enabled.","category":"page"},{"location":"external/metalctl/docs/metalctl_size_reservation_usage/#metalctl-size-reservation-usage","page":"metalctl size reservation usage","title":"metalctl size reservation usage","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_reservation_usage/","page":"metalctl size reservation usage","title":"metalctl size reservation usage","text":"see current usage of size reservations","category":"page"},{"location":"external/metalctl/docs/metalctl_size_reservation_usage/","page":"metalctl size reservation usage","title":"metalctl size reservation usage","text":"metalctl size reservation usage [flags]","category":"page"},{"location":"external/metalctl/docs/metalctl_size_reservation_usage/#Options","page":"metalctl size reservation usage","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_reservation_usage/","page":"metalctl size reservation usage","title":"metalctl size reservation usage","text":" -h, --help help for usage\n --partition string the partition to filter\n --project string the project to filter\n --size-id string the size-id to filter\n --sort-by strings sort by (comma separated) column(s), sort direction can be changed by appending :asc or :desc behind the column identifier. possible values: amount|id|partition|project|size|used-amount","category":"page"},{"location":"external/metalctl/docs/metalctl_size_reservation_usage/#Options-inherited-from-parent-commands","page":"metalctl size reservation usage","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_reservation_usage/","page":"metalctl size reservation usage","title":"metalctl size reservation usage","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_size_reservation_usage/#SEE-ALSO","page":"metalctl size reservation usage","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_size_reservation_usage/","page":"metalctl size reservation usage","title":"metalctl size reservation usage","text":"metalctl size reservation\t - manage reservation entities","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_update-firmware/#metalctl-machine-update-firmware","page":"metalctl machine update-firmware","title":"metalctl machine update-firmware","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_update-firmware/","page":"metalctl machine update-firmware","title":"metalctl machine update-firmware","text":"update a machine firmware","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_update-firmware/#Options","page":"metalctl machine update-firmware","title":"Options","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_update-firmware/","page":"metalctl machine update-firmware","title":"metalctl machine update-firmware","text":" -h, --help help for update-firmware","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_update-firmware/#Options-inherited-from-parent-commands","page":"metalctl machine update-firmware","title":"Options inherited from parent commands","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_update-firmware/","page":"metalctl machine update-firmware","title":"metalctl machine update-firmware","text":" --api-token string api token to authenticate. Can be specified with METALCTL_API_TOKEN environment variable.\n --api-url string api server address. Can be specified with METALCTL_API_URL environment variable.\n -c, --config string alternative config file path, (default is ~/.metalctl/config.yaml).\n Example config.yaml:\n \n ---\n apitoken: \"alongtoken\"\n ...\n \n \n --debug debug output\n --force-color force colored output even without tty\n --kubeconfig string Path to the kube-config to use for authentication and authorization. Is updated by login. Uses default path if not specified.\n --no-headers do not print headers of table output format (default print headers)\n -o, --output-format string output format (table|wide|markdown|json|yaml|template), wide is a table with more columns. (default \"table\")\n --template string output template for template output-format, go template format.\n For property names inspect the output of -o json or -o yaml for reference.\n Example for machines:\n \n metalctl machine list -o template --template \"{{ .id }}:{{ .size.id }}\"\n \n \n --yes-i-really-mean-it skips security prompts (which can be dangerous to set blindly because actions can lead to data loss or additional costs)","category":"page"},{"location":"external/metalctl/docs/metalctl_machine_update-firmware/#SEE-ALSO","page":"metalctl machine update-firmware","title":"SEE ALSO","text":"","category":"section"},{"location":"external/metalctl/docs/metalctl_machine_update-firmware/","page":"metalctl machine update-firmware","title":"metalctl machine update-firmware","text":"metalctl machine\t - manage machine entities\nmetalctl machine update-firmware bios\t - update a machine BIOS\nmetalctl machine update-firmware bmc\t - update a machine BMC","category":"page"}] +} diff --git a/v0.18.15/siteinfo.js b/v0.18.15/siteinfo.js new file mode 100644 index 0000000000..09a711be8e --- /dev/null +++ b/v0.18.15/siteinfo.js @@ -0,0 +1 @@ +var DOCUMENTER_CURRENT_VERSION = "v0.18.15"; diff --git a/versions.js b/versions.js index 04fa721fec..936d2a7e6e 100644 --- a/versions.js +++ b/versions.js @@ -20,5 +20,5 @@ var DOC_VERSIONS = [ "v0.1", "dev", ]; -var DOCUMENTER_NEWEST = "v0.18.14"; +var DOCUMENTER_NEWEST = "v0.18.15"; var DOCUMENTER_STABLE = "stable";

    Welcome to the metal-stack docs!

    metal-stack is an open source software that provides an API for provisioning and managing physical servers in the data center. To categorize this product, we use the terms Metal-as-a-Service (MaaS) or bare metal cloud.

    From the perspective of a user, the metal-stack does not feel any different from working with a conventional cloud provider. Users manage their resources (machines, networks and ip addresses, etc.) by themselves, which effectively turns your data center into an elastic cloud infrastructure.

    The major difference to other cloud providers is that compute power and data reside in your own data center.

    Why metal-stack?

    Before we started with our mission to implement the metal-stack, we decided on a couple of key characteristics and constraints that we think are unique in the domain (otherwise we would definitely have chosen an existing solution).

    We hope that the following properties appeal to you as well.

    On-Premise

    Running on-premise gives you data sovereignty and usually a better price / performance ratio than with hyperscalers — especially the larger you grow your environment. Another benefit of running on-premise is an easier connectivity to existing company networks.

    Fast Provisioning

    Provisioning bare metal machines should not feel much different from virtual machines. metal-stack is capable of provisioning servers in less than a minute. The underlying network topology is based on BGP and allows announcing new routes to your host machines in a matter of seconds.

    No-Ops

    Part of the metal-stack runs on dedicated switches in your data center. This way, it is possible to automate server inventorization, permanently reconcile network configuration and automatically manage machine lifecycles. Manual configuration is neither required nor wanted.

    Security

    Our networking approach was designed for highest standards on security. Also, we enforce firewalling on dedicated tenant firewalls before users can establish connections to other networks than their private tenant network. API authentication and authorization is done with the help of OIDC.

    API driven

    The development of metal-stack is strictly API driven and offers self-service to end-users. This approach delivers the highest possible degree of automation, maintainability and performance.

    Ready for Kubernetes

    Not only does the metal-stack run smoothly on Kubernetes (K8s). The major intent of metal-stack has always been to build a scalable machine infrastructure for Kubernetes as a Service (KaaS). In partnership with the open-source project Gardener, we can provision Kubernetes clusters on metal-stack at scale.

    From the perspective of the Gardener, the metal-stack is just another cloud provider. The time savings compared to providing machines and Kubernetes by hand are significant. We actually want to be able to compete with offers of public cloud providers, especially regarding speed and usability.

    Of course, you can use metal-stack only for machine provisioning as well and just put something else on top of your metal infrastructure.

    Open Source

    The metal-stack is open source and free of constraints regarding vendors and third-party products. The stack is completely built on open source products. We have a community actively working on the metal-stack, which can assist you delivering all reasonable features you are gonna need.

    Why Bare Metal?

    Bare metal has several advantages over virtual environments and overcomes several drawbacks of virtual machines. We also listed drawbacks of the bare metal approach. Bare in mind though that it is still possible to virtualize on bare metal environments when you have your stack up and running.

    Virtual Environment Drawbacks

    • Spectre and Meltdown can only be mitigated with a "cluster per tenant" approach
    • Missing isolation of multi-tenant change impacts
    • Licensing restrictions
    • Noisy-neighbors

    Bare Metal Advantages

    • Guaranteed and fastest possible performance (especially disk i/o)
    • Reduced stack depth (Host / VM / Application vs. Host / Container)
      • Reduced attack surface
      • Lower costs, higher performance
      • No VM live-migrations
    • Bigger hardware configurations possible (hypervisors have restrictions, e.g. it is not possible to assign all CPUs to a single VM)

    Bare Metal Drawbacks

    • Hardware defects have direct impact (should be considered by design) and can not be mitigated by live-migration as in virtual environments
    • Capacity planning is more difficult (no resource overbooking possible)

    Distributed Metal Control Plane

    Problem Statement

    We face the situation that we argue for running bare metal on premise because this way the customers can control where and how their software and data are processed and stored. On the other hand, we have currently decided that our metal-api control plane components run on a kubernetes cluster (in our case on a cluster provided by one of the available hyperscalers).

    Running the control plane on Kubernetes has the following benefits:

    • Ease of deployment
    • Get most, if not all, of the required infrastructure services like (probably incomplete):
      • IPs
      • DNS
      • L7-Loadbalancing
      • Storage
      • S3 Backup
      • High Availability

    Using a kubernetes as a service offering from one of the hyperscalers, enables us to focus on using kubernetes instead of maintaining it as well.

    Goal

    It would be much saner if metal-stack has no, or only minimal dependencies to external services. Imagine a metal-stack deployment in a plant, it would be optimal if we only have to deliver a single rack with servers and networking gear installed and wired, plug that rack to the power supply and a internet uplink and its ready to go.

    Have a second plant which you want to be part of all your plants? Just tell both that they are part of something bigger and metal-api knows of two partitions.

    Possible Solutions

    We can think of two different solutions to this vision:

    1. Keep the central control plane approach and require some sort of kubernetes deployment accessible from the internet. This has the downside that the user must, provide a managed kubernetes deployment in his own datacenter or uses a hyperscaler. Still not optimal.
    2. Install the metal-api and all its dependencies in every partition, replicate or shard the databases to every connected partition, make them know each other. Connect the partitions over the internet with some sort of vpn to make the services visible to each other.

    As we can see, the first approach does not really address the problem, therefore i will describe solution #2 in more details.

    Central/Current setup

    Stateful services

    Every distributed system suffer from handling state in a scalable, fast and correct way. To start how to cope with the state, we first must identify which state can be seen as partition local only and which state must be synchronous for read, and synchronous for writes across partitions.

    Affected states:

    • masterdata: e.g. tenant and project must be present in every partition, but these are entities which are read often but updates are rare. A write can therefore be visible with a decent delay in a distinct partition with no consequences.
    • ipam: the prefixes and ip´s allocated from machines. These entities are also read often and rare updates. But we must differentiate between dirty reads for different types. A machine network is partition local, ips acquired from such a network must by synchronous in the same partition. Ips acquired from global networks such as internet must by synchronous for all partitions, as otherwise a internet ip could be acquired twice.
    • vrf ids: they must only be unique in one partition
    • image and size configurations: read often, written seldom, so no high requirements on the storage of these entities.
    • images: os images are already replicated from a central s3 storage to a per partition s3 service. metal-hammer kernel and initrd are small and pull always from the central s3, can be done similar to os images.
    • machine and machine allocation: must be only synchronous in the partition
    • switch: must be only synchronous in the partition
    • nsq messages: do not need to cross partition boundaries. No need to keep the messages persistent, even the opposite is true, we don't want to have the messages persist for a longer period.

    Now we can see that the most critical state to held and synchronize are the IPAM data, because these entities must be guaranteed to be synchronously updated, while being updated frequently.

    Datastores:

    We use three different types of datastores to persist the states of the metal application.

    • rethinkdb is the main datastore for almost all entities managed by metal-api
    • postgresql is used for masterdata and ipam data.
    • nsq uses disk and memory tho store the messages.

    Stateless services

    These are the easy part, all of our services which are stateless can be scaled up and down without any impact on functionality. Even the stateful services like masterdata and metal-api rely fully on the underlying datastore and can therefore also be scaled up and down to meet scalability requirements.

    Albeit, most of these services need to be placed behind a loadbalancer which does the L4/L7 balancing across the started/available replicas of the service for the clients talking to it. This is actually provided by kubernetes with either service type loadbalancer or type clusterip.

    One exception is the metal-console service which must have the partition in it´s dns name now, because there is no direct network connectivity between the management networks of the partitions. See "Network Setup)

    Distributed setup

    State

    In order to replicate certain data which must be available across all partitions we can use on of the existing open source databases which enable such kind of setup. There are a few available out there, the following incomplete list will highlight the pro´s and cons of each.

    • RethinkDB

      We already store most of our data in RethinkDB and it gives already the ability to synchronize the data in a distributed manner with different guarantees for consistency and latency. This is described here: Scaling, Sharding and replication. But because rethinkdb has a rough history and unsure future with the last release took more than a year, we in the team already thought that we eventually must move away from rethinkdb in the future.

    • Postgresql

      Postgres does not have a multi datacenter with replication in both directions, it just can make the remote instance store the same data.

    • CockroachDB

      Is a Postgresql compatible database enginge on the wire. CockroachDB gives you both, ACID and geo replication with writes allowed from all connected members. It is even possible to configure Follow the Workload and Geo Partitioning and Replication.

    If we migrate all metal-api entities to be stored the same way we store masterdata, we could use cockroachdb to store all metal entities in one ore more databases spread across all partitions and still ensure consistency and high availability.

    A simple setup how this would look like is shown here.

    Simple CockroachDB setup

    go-ipam was modified in a example PR here: PR 17

    API Access

    In order to make the metal-api accessible for api users like cloud-api or metalctl as easy at it is today, some effort has to be taken. One possible approach would be to use a external loadbalancer which spread the requests evenly to all metal-api endpoints in all partitions. Because all data are accessible from all partitions, a api request going to partition A with a request to create a machine in partition B, will still work. If on the other hand partition B is not in a connected state because the interconnection between both partitions is broken, then of course the request will fail.

    IMPORTANT The NSQ Message to inform metal-core must end in the correct partition

    To provide such a external loadbalancer we have several opportunities:

    • Cloudflare or comparable CDN service.
    • BGP Anycast from every partition

    Another setup would place a small gateway behind the metal-api address, which forwards to the metal-api in the partition where the request must be executed. This gateway, metal-api-router must inspect the payload, extract the desired partition, and forward the request without any modifications to the metal-api endpoint in this partition. This can be done for all requests, or if we want to optimize, only for write accesses.

    Network setup

    In order to have the impact to the overall security concept as minimal as possible i would not modify the current network setup. The only modifications which has to be made are:

    • Allow https ingress traffic to all metal-api instances.
    • Allow ssh ingress traffic to all metal-console instances.
    • Allow CockroachDB Replication between all partitions.
    • No NSQ traffic from outside required anymore, except we cant solve the topic above.

    A simple setup how this would look like is shown here, this does not work though because of the forementioned NSQ issue.

    API and Console Access

    Therefore we need the metal-api-router:

    Working API and Console Access

    Deployment

    The deployment of our components will substantially differ in a partition compared to a the deployment we have actually. Deploying it in kubernetes in the partition would be very difficult to achieve because we have no sane way to deploy kubernetes on physical machines without a underlying API. I would therefore suggest to deploy our components in the same way we do that for the services running on the management server. Use systemd to start docker containers.

    Deployment