pvectl 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.claude/rules/branch-before-changes.md +52 -0
- data/.claude/rules/documentation-updates.md +104 -0
- data/.claude/rules/git-workflow.md +84 -0
- data/.claude/rules/proxmox-api-docs.md +58 -0
- data/.claude/rules/rbs-signatures.md +80 -0
- data/.claude/rules/refactoring-as-design-option.md +35 -0
- data/.claude/scheduled_tasks.lock +1 -0
- data/.claude/settings.json +51 -0
- data/.mcp.json +8 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/CHANGELOG.md +138 -0
- data/CLAUDE.md +211 -0
- data/CODE_OF_CONDUCT.md +132 -0
- data/LICENSE.txt +21 -0
- data/README.md +143 -0
- data/Rakefile +8 -0
- data/docs/proxmox-api-update.sh +96 -0
- data/exe/pvectl +5 -0
- data/lib/pvectl/argv_preprocessor.rb +334 -0
- data/lib/pvectl/cli.rb +102 -0
- data/lib/pvectl/commands/apt.rb +389 -0
- data/lib/pvectl/commands/clone_container.rb +230 -0
- data/lib/pvectl/commands/clone_vm.rb +331 -0
- data/lib/pvectl/commands/cloudinit/command.rb +122 -0
- data/lib/pvectl/commands/cloudinit/dump.rb +94 -0
- data/lib/pvectl/commands/cloudinit/pending.rb +137 -0
- data/lib/pvectl/commands/cloudinit/regenerate.rb +79 -0
- data/lib/pvectl/commands/config/command.rb +65 -0
- data/lib/pvectl/commands/config/get_contexts.rb +68 -0
- data/lib/pvectl/commands/config/set_cluster.rb +103 -0
- data/lib/pvectl/commands/config/set_context.rb +136 -0
- data/lib/pvectl/commands/config/set_credentials.rb +181 -0
- data/lib/pvectl/commands/config/use_context.rb +69 -0
- data/lib/pvectl/commands/config/view.rb +67 -0
- data/lib/pvectl/commands/console.rb +93 -0
- data/lib/pvectl/commands/console_ct.rb +187 -0
- data/lib/pvectl/commands/console_vm.rb +187 -0
- data/lib/pvectl/commands/container_lifecycle_command.rb +77 -0
- data/lib/pvectl/commands/create_backup.rb +173 -0
- data/lib/pvectl/commands/create_container.rb +141 -0
- data/lib/pvectl/commands/create_resource_command.rb +244 -0
- data/lib/pvectl/commands/create_snapshot.rb +242 -0
- data/lib/pvectl/commands/create_vm.rb +267 -0
- data/lib/pvectl/commands/delete_backup.rb +139 -0
- data/lib/pvectl/commands/delete_command.rb +119 -0
- data/lib/pvectl/commands/delete_container.rb +30 -0
- data/lib/pvectl/commands/delete_snapshot.rb +248 -0
- data/lib/pvectl/commands/delete_vm.rb +127 -0
- data/lib/pvectl/commands/describe/command.rb +251 -0
- data/lib/pvectl/commands/edit_container.rb +56 -0
- data/lib/pvectl/commands/edit_dns.rb +149 -0
- data/lib/pvectl/commands/edit_hosts.rb +135 -0
- data/lib/pvectl/commands/edit_node.rb +54 -0
- data/lib/pvectl/commands/edit_resource_command.rb +180 -0
- data/lib/pvectl/commands/edit_vm.rb +154 -0
- data/lib/pvectl/commands/edit_volume.rb +189 -0
- data/lib/pvectl/commands/feature_command.rb +230 -0
- data/lib/pvectl/commands/feature_container.rb +21 -0
- data/lib/pvectl/commands/feature_vm.rb +94 -0
- data/lib/pvectl/commands/get/command.rb +360 -0
- data/lib/pvectl/commands/get/handlers/backups.rb +76 -0
- data/lib/pvectl/commands/get/handlers/capabilities.rb +107 -0
- data/lib/pvectl/commands/get/handlers/containers.rb +148 -0
- data/lib/pvectl/commands/get/handlers/disks.rb +107 -0
- data/lib/pvectl/commands/get/handlers/dns.rb +94 -0
- data/lib/pvectl/commands/get/handlers/hosts.rb +94 -0
- data/lib/pvectl/commands/get/handlers/nodes.rb +162 -0
- data/lib/pvectl/commands/get/handlers/services.rb +81 -0
- data/lib/pvectl/commands/get/handlers/snapshots.rb +97 -0
- data/lib/pvectl/commands/get/handlers/storage.rb +118 -0
- data/lib/pvectl/commands/get/handlers/subscription.rb +69 -0
- data/lib/pvectl/commands/get/handlers/tasks.rb +89 -0
- data/lib/pvectl/commands/get/handlers/templates.rb +175 -0
- data/lib/pvectl/commands/get/handlers/time.rb +118 -0
- data/lib/pvectl/commands/get/handlers/vms.rb +145 -0
- data/lib/pvectl/commands/get/handlers/volume.rb +134 -0
- data/lib/pvectl/commands/get/resource_handler.rb +63 -0
- data/lib/pvectl/commands/get/resource_registry.rb +18 -0
- data/lib/pvectl/commands/get/watch_loop.rb +129 -0
- data/lib/pvectl/commands/irreversible_command.rb +265 -0
- data/lib/pvectl/commands/logs/command.rb +275 -0
- data/lib/pvectl/commands/logs/handlers/journal.rb +46 -0
- data/lib/pvectl/commands/logs/handlers/syslog.rb +53 -0
- data/lib/pvectl/commands/logs/handlers/task_detail.rb +52 -0
- data/lib/pvectl/commands/logs/handlers/task_logs.rb +115 -0
- data/lib/pvectl/commands/logs/resource_handler.rb +46 -0
- data/lib/pvectl/commands/logs/resource_registry.rb +22 -0
- data/lib/pvectl/commands/migrate_command.rb +282 -0
- data/lib/pvectl/commands/migrate_container.rb +23 -0
- data/lib/pvectl/commands/migrate_vm.rb +122 -0
- data/lib/pvectl/commands/move_disk_command.rb +239 -0
- data/lib/pvectl/commands/move_disk_container.rb +21 -0
- data/lib/pvectl/commands/move_disk_vm.rb +127 -0
- data/lib/pvectl/commands/ping.rb +249 -0
- data/lib/pvectl/commands/pull.rb +342 -0
- data/lib/pvectl/commands/push.rb +352 -0
- data/lib/pvectl/commands/reset.rb +64 -0
- data/lib/pvectl/commands/resource_lifecycle_command.rb +277 -0
- data/lib/pvectl/commands/resource_registry.rb +73 -0
- data/lib/pvectl/commands/restart.rb +70 -0
- data/lib/pvectl/commands/restart_container.rb +18 -0
- data/lib/pvectl/commands/restore_backup.rb +236 -0
- data/lib/pvectl/commands/resume.rb +57 -0
- data/lib/pvectl/commands/rollback_snapshot.rb +228 -0
- data/lib/pvectl/commands/sendkey_vm.rb +205 -0
- data/lib/pvectl/commands/service.rb +293 -0
- data/lib/pvectl/commands/set_container.rb +50 -0
- data/lib/pvectl/commands/set_node.rb +52 -0
- data/lib/pvectl/commands/set_resource_command.rb +185 -0
- data/lib/pvectl/commands/set_vm.rb +136 -0
- data/lib/pvectl/commands/set_volume.rb +212 -0
- data/lib/pvectl/commands/shared_config_parsers.rb +126 -0
- data/lib/pvectl/commands/shared_flags.rb +155 -0
- data/lib/pvectl/commands/shutdown.rb +73 -0
- data/lib/pvectl/commands/shutdown_container.rb +18 -0
- data/lib/pvectl/commands/start.rb +79 -0
- data/lib/pvectl/commands/start_container.rb +18 -0
- data/lib/pvectl/commands/stop.rb +75 -0
- data/lib/pvectl/commands/stop_container.rb +18 -0
- data/lib/pvectl/commands/suspend.rb +64 -0
- data/lib/pvectl/commands/template_command.rb +205 -0
- data/lib/pvectl/commands/template_container.rb +27 -0
- data/lib/pvectl/commands/template_vm.rb +106 -0
- data/lib/pvectl/commands/top/command.rb +206 -0
- data/lib/pvectl/commands/top/handlers/containers.rb +61 -0
- data/lib/pvectl/commands/top/handlers/nodes.rb +61 -0
- data/lib/pvectl/commands/top/handlers/vms.rb +61 -0
- data/lib/pvectl/commands/top/resource_handler.rb +46 -0
- data/lib/pvectl/commands/top/resource_registry.rb +22 -0
- data/lib/pvectl/commands/unlink_disk_vm.rb +232 -0
- data/lib/pvectl/commands/vm_lifecycle_command.rb +77 -0
- data/lib/pvectl/commands/wakeonlan_node.rb +153 -0
- data/lib/pvectl/config/errors.rb +62 -0
- data/lib/pvectl/config/models/cluster.rb +180 -0
- data/lib/pvectl/config/models/context.rb +100 -0
- data/lib/pvectl/config/models/resolved_config.rb +171 -0
- data/lib/pvectl/config/models/user.rb +133 -0
- data/lib/pvectl/config/provider.rb +297 -0
- data/lib/pvectl/config/service.rb +300 -0
- data/lib/pvectl/config/store.rb +161 -0
- data/lib/pvectl/config/wizard.rb +309 -0
- data/lib/pvectl/config_serializer.rb +1034 -0
- data/lib/pvectl/connection/retry_handler.rb +161 -0
- data/lib/pvectl/connection.rb +157 -0
- data/lib/pvectl/console/terminal_session.rb +449 -0
- data/lib/pvectl/editor_session.rb +157 -0
- data/lib/pvectl/exit_codes.rb +43 -0
- data/lib/pvectl/formatters/base.rb +55 -0
- data/lib/pvectl/formatters/color_support.rb +90 -0
- data/lib/pvectl/formatters/json.rb +45 -0
- data/lib/pvectl/formatters/output_helper.rb +77 -0
- data/lib/pvectl/formatters/registry.rb +72 -0
- data/lib/pvectl/formatters/table.rb +235 -0
- data/lib/pvectl/formatters/wide.rb +93 -0
- data/lib/pvectl/formatters/yaml.rb +49 -0
- data/lib/pvectl/manifest_serializer.rb +142 -0
- data/lib/pvectl/models/apt_package.rb +107 -0
- data/lib/pvectl/models/backup.rb +173 -0
- data/lib/pvectl/models/base.rb +49 -0
- data/lib/pvectl/models/capability.rb +62 -0
- data/lib/pvectl/models/container.rb +205 -0
- data/lib/pvectl/models/container_operation_result.rb +27 -0
- data/lib/pvectl/models/dns_config.rb +54 -0
- data/lib/pvectl/models/hosts_file.rb +47 -0
- data/lib/pvectl/models/journal_entry.rb +16 -0
- data/lib/pvectl/models/network_interface.rb +85 -0
- data/lib/pvectl/models/node.rb +195 -0
- data/lib/pvectl/models/node_operation_result.rb +45 -0
- data/lib/pvectl/models/operation_result.rb +110 -0
- data/lib/pvectl/models/physical_disk.rb +193 -0
- data/lib/pvectl/models/service.rb +80 -0
- data/lib/pvectl/models/snapshot.rb +101 -0
- data/lib/pvectl/models/snapshot_description.rb +39 -0
- data/lib/pvectl/models/storage.rb +180 -0
- data/lib/pvectl/models/subscription.rb +87 -0
- data/lib/pvectl/models/syslog_entry.rb +17 -0
- data/lib/pvectl/models/task.rb +95 -0
- data/lib/pvectl/models/task_entry.rb +52 -0
- data/lib/pvectl/models/task_log_line.rb +17 -0
- data/lib/pvectl/models/time_config.rb +47 -0
- data/lib/pvectl/models/vm.rb +137 -0
- data/lib/pvectl/models/vm_operation_result.rb +27 -0
- data/lib/pvectl/models/volume.rb +133 -0
- data/lib/pvectl/models/volume_operation_result.rb +26 -0
- data/lib/pvectl/parsers/cloud_init_config.rb +92 -0
- data/lib/pvectl/parsers/disk_config.rb +97 -0
- data/lib/pvectl/parsers/lxc_mount_config.rb +98 -0
- data/lib/pvectl/parsers/lxc_net_config.rb +97 -0
- data/lib/pvectl/parsers/net_config.rb +95 -0
- data/lib/pvectl/parsers/smart_text.rb +42 -0
- data/lib/pvectl/plugin_loader.rb +157 -0
- data/lib/pvectl/presenters/apt_package.rb +99 -0
- data/lib/pvectl/presenters/backup.rb +128 -0
- data/lib/pvectl/presenters/base.rb +283 -0
- data/lib/pvectl/presenters/capability.rb +104 -0
- data/lib/pvectl/presenters/config/context.rb +80 -0
- data/lib/pvectl/presenters/container.rb +574 -0
- data/lib/pvectl/presenters/container_operation_result.rb +109 -0
- data/lib/pvectl/presenters/disk.rb +184 -0
- data/lib/pvectl/presenters/dns_config.rb +68 -0
- data/lib/pvectl/presenters/hosts_file.rb +61 -0
- data/lib/pvectl/presenters/journal_entry.rb +20 -0
- data/lib/pvectl/presenters/node.rb +762 -0
- data/lib/pvectl/presenters/node_operation_result.rb +50 -0
- data/lib/pvectl/presenters/operation_result.rb +61 -0
- data/lib/pvectl/presenters/service.rb +76 -0
- data/lib/pvectl/presenters/snapshot.rb +239 -0
- data/lib/pvectl/presenters/snapshot_operation_result.rb +125 -0
- data/lib/pvectl/presenters/storage.rb +329 -0
- data/lib/pvectl/presenters/subscription.rb +189 -0
- data/lib/pvectl/presenters/syslog_entry.rb +20 -0
- data/lib/pvectl/presenters/task_entry.rb +69 -0
- data/lib/pvectl/presenters/task_log_line.rb +20 -0
- data/lib/pvectl/presenters/template.rb +76 -0
- data/lib/pvectl/presenters/time_config.rb +86 -0
- data/lib/pvectl/presenters/top_container.rb +112 -0
- data/lib/pvectl/presenters/top_node.rb +115 -0
- data/lib/pvectl/presenters/top_presenter.rb +59 -0
- data/lib/pvectl/presenters/top_vm.rb +105 -0
- data/lib/pvectl/presenters/vm.rb +853 -0
- data/lib/pvectl/presenters/vm_operation_result.rb +109 -0
- data/lib/pvectl/presenters/volume.rb +136 -0
- data/lib/pvectl/presenters/volume_operation_result.rb +58 -0
- data/lib/pvectl/repositories/apt.rb +93 -0
- data/lib/pvectl/repositories/backup.rb +186 -0
- data/lib/pvectl/repositories/base.rb +110 -0
- data/lib/pvectl/repositories/capabilities.rb +96 -0
- data/lib/pvectl/repositories/container.rb +503 -0
- data/lib/pvectl/repositories/disk.rb +87 -0
- data/lib/pvectl/repositories/dns.rb +54 -0
- data/lib/pvectl/repositories/hosts.rb +63 -0
- data/lib/pvectl/repositories/journal.rb +23 -0
- data/lib/pvectl/repositories/node.rb +537 -0
- data/lib/pvectl/repositories/service.rb +139 -0
- data/lib/pvectl/repositories/snapshot.rb +133 -0
- data/lib/pvectl/repositories/storage.rb +302 -0
- data/lib/pvectl/repositories/subscription.rb +77 -0
- data/lib/pvectl/repositories/syslog.rb +25 -0
- data/lib/pvectl/repositories/task.rb +82 -0
- data/lib/pvectl/repositories/task_list.rb +30 -0
- data/lib/pvectl/repositories/task_log.rb +31 -0
- data/lib/pvectl/repositories/time_config.rb +53 -0
- data/lib/pvectl/repositories/vm.rb +616 -0
- data/lib/pvectl/repositories/volume.rb +306 -0
- data/lib/pvectl/selectors/base.rb +201 -0
- data/lib/pvectl/selectors/container.rb +116 -0
- data/lib/pvectl/selectors/disk.rb +59 -0
- data/lib/pvectl/selectors/vm.rb +116 -0
- data/lib/pvectl/selectors/volume.rb +59 -0
- data/lib/pvectl/services/backup.rb +209 -0
- data/lib/pvectl/services/clone_container.rb +260 -0
- data/lib/pvectl/services/clone_vm.rb +265 -0
- data/lib/pvectl/services/cloudinit.rb +96 -0
- data/lib/pvectl/services/console.rb +152 -0
- data/lib/pvectl/services/container_lifecycle.rb +124 -0
- data/lib/pvectl/services/create_container.rb +179 -0
- data/lib/pvectl/services/create_vm.rb +191 -0
- data/lib/pvectl/services/edit_container.rb +125 -0
- data/lib/pvectl/services/edit_dns.rb +159 -0
- data/lib/pvectl/services/edit_hosts.rb +78 -0
- data/lib/pvectl/services/edit_node.rb +147 -0
- data/lib/pvectl/services/edit_vm.rb +125 -0
- data/lib/pvectl/services/edit_volume.rb +224 -0
- data/lib/pvectl/services/get/resource_service.rb +98 -0
- data/lib/pvectl/services/move_disk.rb +132 -0
- data/lib/pvectl/services/pull_config.rb +94 -0
- data/lib/pvectl/services/push_config.rb +524 -0
- data/lib/pvectl/services/resize_volume.rb +253 -0
- data/lib/pvectl/services/resource_delete.rb +169 -0
- data/lib/pvectl/services/resource_migration.rb +170 -0
- data/lib/pvectl/services/sendkey.rb +108 -0
- data/lib/pvectl/services/service_lifecycle.rb +89 -0
- data/lib/pvectl/services/set_container.rb +128 -0
- data/lib/pvectl/services/set_node.rb +236 -0
- data/lib/pvectl/services/set_vm.rb +128 -0
- data/lib/pvectl/services/set_volume.rb +126 -0
- data/lib/pvectl/services/snapshot.rb +261 -0
- data/lib/pvectl/services/task_listing.rb +75 -0
- data/lib/pvectl/services/unlink_disk.rb +86 -0
- data/lib/pvectl/services/vm_lifecycle.rb +124 -0
- data/lib/pvectl/services/wakeonlan.rb +79 -0
- data/lib/pvectl/utils/resource_resolver.rb +80 -0
- data/lib/pvectl/version.rb +13 -0
- data/lib/pvectl/wizards/create_container.rb +105 -0
- data/lib/pvectl/wizards/create_vm.rb +98 -0
- data/lib/pvectl.rb +439 -0
- data/sig/external/gli.rbs +16 -0
- data/sig/external/proxmox_api.rbs +10 -0
- data/sig/pvectl/argv_preprocessor.rbs +53 -0
- data/sig/pvectl/cli.rbs +26 -0
- data/sig/pvectl/commands/apt.rbs +47 -0
- data/sig/pvectl/commands/clone_container.rbs +31 -0
- data/sig/pvectl/commands/clone_vm.rbs +33 -0
- data/sig/pvectl/commands/cloudinit/command.rbs +13 -0
- data/sig/pvectl/commands/cloudinit/dump.rbs +13 -0
- data/sig/pvectl/commands/cloudinit/pending.rbs +17 -0
- data/sig/pvectl/commands/cloudinit/regenerate.rbs +11 -0
- data/sig/pvectl/commands/config/command.rbs +9 -0
- data/sig/pvectl/commands/config/get_contexts.rbs +11 -0
- data/sig/pvectl/commands/config/set_cluster.rbs +11 -0
- data/sig/pvectl/commands/config/set_context.rbs +15 -0
- data/sig/pvectl/commands/config/set_credentials.rbs +15 -0
- data/sig/pvectl/commands/config/use_context.rbs +11 -0
- data/sig/pvectl/commands/config/view.rbs +11 -0
- data/sig/pvectl/commands/console.rbs +9 -0
- data/sig/pvectl/commands/console_ct.rbs +27 -0
- data/sig/pvectl/commands/console_vm.rbs +27 -0
- data/sig/pvectl/commands/container_lifecycle_command.rbs +25 -0
- data/sig/pvectl/commands/create_backup.rbs +29 -0
- data/sig/pvectl/commands/create_container.rbs +30 -0
- data/sig/pvectl/commands/create_resource_command.rbs +53 -0
- data/sig/pvectl/commands/create_snapshot.rbs +35 -0
- data/sig/pvectl/commands/create_vm.rbs +30 -0
- data/sig/pvectl/commands/delete_backup.rbs +25 -0
- data/sig/pvectl/commands/delete_command.rbs +45 -0
- data/sig/pvectl/commands/delete_container.rbs +11 -0
- data/sig/pvectl/commands/delete_snapshot.rbs +35 -0
- data/sig/pvectl/commands/delete_vm.rbs +13 -0
- data/sig/pvectl/commands/describe/command.rbs +27 -0
- data/sig/pvectl/commands/edit_container.rbs +17 -0
- data/sig/pvectl/commands/edit_dns.rbs +25 -0
- data/sig/pvectl/commands/edit_hosts.rbs +23 -0
- data/sig/pvectl/commands/edit_node.rbs +17 -0
- data/sig/pvectl/commands/edit_resource_command.rbs +35 -0
- data/sig/pvectl/commands/edit_vm.rbs +19 -0
- data/sig/pvectl/commands/edit_volume.rbs +24 -0
- data/sig/pvectl/commands/feature_command.rbs +43 -0
- data/sig/pvectl/commands/feature_container.rbs +10 -0
- data/sig/pvectl/commands/feature_vm.rbs +12 -0
- data/sig/pvectl/commands/get/command.rbs +42 -0
- data/sig/pvectl/commands/get/handlers/backups.rbs +23 -0
- data/sig/pvectl/commands/get/handlers/capabilities.rbs +29 -0
- data/sig/pvectl/commands/get/handlers/containers.rbs +35 -0
- data/sig/pvectl/commands/get/handlers/disks.rbs +27 -0
- data/sig/pvectl/commands/get/handlers/dns.rbs +25 -0
- data/sig/pvectl/commands/get/handlers/hosts.rbs +25 -0
- data/sig/pvectl/commands/get/handlers/nodes.rbs +33 -0
- data/sig/pvectl/commands/get/handlers/services.rbs +23 -0
- data/sig/pvectl/commands/get/handlers/snapshots.rbs +27 -0
- data/sig/pvectl/commands/get/handlers/storage.rbs +25 -0
- data/sig/pvectl/commands/get/handlers/subscription.rbs +25 -0
- data/sig/pvectl/commands/get/handlers/tasks.rbs +28 -0
- data/sig/pvectl/commands/get/handlers/templates.rbs +35 -0
- data/sig/pvectl/commands/get/handlers/time.rbs +29 -0
- data/sig/pvectl/commands/get/handlers/vms.rbs +35 -0
- data/sig/pvectl/commands/get/handlers/volume.rbs +27 -0
- data/sig/pvectl/commands/get/resource_handler.rbs +13 -0
- data/sig/pvectl/commands/get/resource_registry.rbs +8 -0
- data/sig/pvectl/commands/get/watch_loop.rbs +33 -0
- data/sig/pvectl/commands/irreversible_command.rbs +32 -0
- data/sig/pvectl/commands/logs/command.rbs +35 -0
- data/sig/pvectl/commands/logs/handlers/journal.rbs +21 -0
- data/sig/pvectl/commands/logs/handlers/syslog.rbs +21 -0
- data/sig/pvectl/commands/logs/handlers/task_detail.rbs +21 -0
- data/sig/pvectl/commands/logs/handlers/task_logs.rbs +35 -0
- data/sig/pvectl/commands/logs/resource_handler.rbs +11 -0
- data/sig/pvectl/commands/logs/resource_registry.rbs +8 -0
- data/sig/pvectl/commands/migrate_command.rbs +45 -0
- data/sig/pvectl/commands/migrate_container.rbs +11 -0
- data/sig/pvectl/commands/migrate_vm.rbs +13 -0
- data/sig/pvectl/commands/move_disk_command.rbs +43 -0
- data/sig/pvectl/commands/move_disk_container.rbs +11 -0
- data/sig/pvectl/commands/move_disk_vm.rbs +13 -0
- data/sig/pvectl/commands/ping.rbs +39 -0
- data/sig/pvectl/commands/pull.rbs +33 -0
- data/sig/pvectl/commands/push.rbs +32 -0
- data/sig/pvectl/commands/reset.rbs +11 -0
- data/sig/pvectl/commands/resource_lifecycle_command.rbs +55 -0
- data/sig/pvectl/commands/resource_registry.rbs +19 -0
- data/sig/pvectl/commands/restart.rbs +11 -0
- data/sig/pvectl/commands/restart_container.rbs +9 -0
- data/sig/pvectl/commands/restore_backup.rbs +27 -0
- data/sig/pvectl/commands/resume.rbs +11 -0
- data/sig/pvectl/commands/rollback_snapshot.rbs +31 -0
- data/sig/pvectl/commands/sendkey_vm.rbs +25 -0
- data/sig/pvectl/commands/service.rbs +38 -0
- data/sig/pvectl/commands/set_container.rbs +13 -0
- data/sig/pvectl/commands/set_node.rbs +13 -0
- data/sig/pvectl/commands/set_resource_command.rbs +25 -0
- data/sig/pvectl/commands/set_vm.rbs +15 -0
- data/sig/pvectl/commands/set_volume.rbs +24 -0
- data/sig/pvectl/commands/shared_config_parsers.rbs +19 -0
- data/sig/pvectl/commands/shared_flags.rbs +10 -0
- data/sig/pvectl/commands/shutdown.rbs +11 -0
- data/sig/pvectl/commands/shutdown_container.rbs +9 -0
- data/sig/pvectl/commands/start.rbs +11 -0
- data/sig/pvectl/commands/start_container.rbs +9 -0
- data/sig/pvectl/commands/stop.rbs +11 -0
- data/sig/pvectl/commands/stop_container.rbs +9 -0
- data/sig/pvectl/commands/suspend.rbs +11 -0
- data/sig/pvectl/commands/template_command.rbs +21 -0
- data/sig/pvectl/commands/template_container.rbs +10 -0
- data/sig/pvectl/commands/template_vm.rbs +12 -0
- data/sig/pvectl/commands/top/command.rbs +31 -0
- data/sig/pvectl/commands/top/handlers/containers.rbs +21 -0
- data/sig/pvectl/commands/top/handlers/nodes.rbs +21 -0
- data/sig/pvectl/commands/top/handlers/vms.rbs +21 -0
- data/sig/pvectl/commands/top/resource_handler.rbs +11 -0
- data/sig/pvectl/commands/top/resource_registry.rbs +8 -0
- data/sig/pvectl/commands/unlink_disk_vm.rbs +27 -0
- data/sig/pvectl/commands/vm_lifecycle_command.rbs +25 -0
- data/sig/pvectl/commands/wakeonlan_node.rbs +21 -0
- data/sig/pvectl/config/errors.rbs +24 -0
- data/sig/pvectl/config/models/cluster.rbs +39 -0
- data/sig/pvectl/config/models/context.rbs +23 -0
- data/sig/pvectl/config/models/resolved_config.rbs +51 -0
- data/sig/pvectl/config/models/user.rbs +31 -0
- data/sig/pvectl/config/provider.rbs +40 -0
- data/sig/pvectl/config/service.rbs +65 -0
- data/sig/pvectl/config/store.rbs +14 -0
- data/sig/pvectl/config/wizard.rbs +48 -0
- data/sig/pvectl/config_serializer.rbs +121 -0
- data/sig/pvectl/connection/retry_handler.rbs +31 -0
- data/sig/pvectl/connection.rbs +35 -0
- data/sig/pvectl/console/terminal_session.rbs +63 -0
- data/sig/pvectl/editor_session.rbs +33 -0
- data/sig/pvectl/exit_codes.rbs +19 -0
- data/sig/pvectl/formatters/base.rbs +13 -0
- data/sig/pvectl/formatters/color_support.rbs +13 -0
- data/sig/pvectl/formatters/json.rbs +7 -0
- data/sig/pvectl/formatters/output_helper.rbs +9 -0
- data/sig/pvectl/formatters/registry.rbs +13 -0
- data/sig/pvectl/formatters/table.rbs +25 -0
- data/sig/pvectl/formatters/wide.rbs +15 -0
- data/sig/pvectl/formatters/yaml.rbs +7 -0
- data/sig/pvectl/manifest_serializer.rbs +18 -0
- data/sig/pvectl/models/apt_package.rbs +26 -0
- data/sig/pvectl/models/backup.rbs +31 -0
- data/sig/pvectl/models/base.rbs +11 -0
- data/sig/pvectl/models/capability.rbs +16 -0
- data/sig/pvectl/models/container.rbs +44 -0
- data/sig/pvectl/models/container_operation_result.rbs +9 -0
- data/sig/pvectl/models/dns_config.rbs +15 -0
- data/sig/pvectl/models/hosts_file.rbs +13 -0
- data/sig/pvectl/models/journal_entry.rbs +10 -0
- data/sig/pvectl/models/network_interface.rbs +20 -0
- data/sig/pvectl/models/node.rbs +47 -0
- data/sig/pvectl/models/node_operation_result.rbs +12 -0
- data/sig/pvectl/models/operation_result.rbs +21 -0
- data/sig/pvectl/models/physical_disk.rbs +35 -0
- data/sig/pvectl/models/service.rbs +18 -0
- data/sig/pvectl/models/snapshot.rbs +21 -0
- data/sig/pvectl/models/snapshot_description.rbs +18 -0
- data/sig/pvectl/models/storage.rbs +39 -0
- data/sig/pvectl/models/subscription.rbs +24 -0
- data/sig/pvectl/models/syslog_entry.rbs +10 -0
- data/sig/pvectl/models/task.rbs +22 -0
- data/sig/pvectl/models/task_entry.rbs +24 -0
- data/sig/pvectl/models/task_log_line.rbs +10 -0
- data/sig/pvectl/models/time_config.rbs +12 -0
- data/sig/pvectl/models/vm.rbs +32 -0
- data/sig/pvectl/models/vm_operation_result.rbs +9 -0
- data/sig/pvectl/models/volume.rbs +29 -0
- data/sig/pvectl/models/volume_operation_result.rbs +9 -0
- data/sig/pvectl/parsers/cloud_init_config.rbs +15 -0
- data/sig/pvectl/parsers/disk_config.rbs +19 -0
- data/sig/pvectl/parsers/lxc_mount_config.rbs +19 -0
- data/sig/pvectl/parsers/lxc_net_config.rbs +19 -0
- data/sig/pvectl/parsers/net_config.rbs +19 -0
- data/sig/pvectl/parsers/smart_text.rbs +7 -0
- data/sig/pvectl/plugin_loader.rbs +25 -0
- data/sig/pvectl/presenters/apt_package.rbs +19 -0
- data/sig/pvectl/presenters/backup.rbs +25 -0
- data/sig/pvectl/presenters/base.rbs +41 -0
- data/sig/pvectl/presenters/capability.rbs +19 -0
- data/sig/pvectl/presenters/config/context.rbs +17 -0
- data/sig/pvectl/presenters/container.rbs +78 -0
- data/sig/pvectl/presenters/container_operation_result.rbs +19 -0
- data/sig/pvectl/presenters/disk.rbs +31 -0
- data/sig/pvectl/presenters/dns_config.rbs +13 -0
- data/sig/pvectl/presenters/hosts_file.rbs +13 -0
- data/sig/pvectl/presenters/journal_entry.rbs +11 -0
- data/sig/pvectl/presenters/node.rbs +118 -0
- data/sig/pvectl/presenters/node_operation_result.rbs +11 -0
- data/sig/pvectl/presenters/operation_result.rbs +17 -0
- data/sig/pvectl/presenters/service.rbs +15 -0
- data/sig/pvectl/presenters/snapshot.rbs +35 -0
- data/sig/pvectl/presenters/snapshot_operation_result.rbs +27 -0
- data/sig/pvectl/presenters/storage.rbs +59 -0
- data/sig/pvectl/presenters/subscription.rbs +36 -0
- data/sig/pvectl/presenters/syslog_entry.rbs +11 -0
- data/sig/pvectl/presenters/task_entry.rbs +21 -0
- data/sig/pvectl/presenters/task_log_line.rbs +11 -0
- data/sig/pvectl/presenters/template.rbs +15 -0
- data/sig/pvectl/presenters/time_config.rbs +19 -0
- data/sig/pvectl/presenters/top_container.rbs +17 -0
- data/sig/pvectl/presenters/top_node.rbs +17 -0
- data/sig/pvectl/presenters/top_presenter.rbs +13 -0
- data/sig/pvectl/presenters/top_vm.rbs +17 -0
- data/sig/pvectl/presenters/vm.rbs +91 -0
- data/sig/pvectl/presenters/vm_operation_result.rbs +19 -0
- data/sig/pvectl/presenters/volume.rbs +23 -0
- data/sig/pvectl/presenters/volume_operation_result.rbs +11 -0
- data/sig/pvectl/repositories/apt.rbs +17 -0
- data/sig/pvectl/repositories/backup.rbs +27 -0
- data/sig/pvectl/repositories/base.rbs +23 -0
- data/sig/pvectl/repositories/capabilities.rbs +20 -0
- data/sig/pvectl/repositories/container.rbs +63 -0
- data/sig/pvectl/repositories/disk.rbs +17 -0
- data/sig/pvectl/repositories/dns.rbs +13 -0
- data/sig/pvectl/repositories/hosts.rbs +13 -0
- data/sig/pvectl/repositories/journal.rbs +7 -0
- data/sig/pvectl/repositories/node.rbs +68 -0
- data/sig/pvectl/repositories/service.rbs +27 -0
- data/sig/pvectl/repositories/snapshot.rbs +19 -0
- data/sig/pvectl/repositories/storage.rbs +37 -0
- data/sig/pvectl/repositories/subscription.rbs +17 -0
- data/sig/pvectl/repositories/syslog.rbs +7 -0
- data/sig/pvectl/repositories/task.rbs +19 -0
- data/sig/pvectl/repositories/task_list.rbs +7 -0
- data/sig/pvectl/repositories/task_log.rbs +11 -0
- data/sig/pvectl/repositories/time_config.rbs +13 -0
- data/sig/pvectl/repositories/vm.rbs +85 -0
- data/sig/pvectl/repositories/volume.rbs +43 -0
- data/sig/pvectl/selectors/base.rbs +37 -0
- data/sig/pvectl/selectors/container.rbs +19 -0
- data/sig/pvectl/selectors/disk.rbs +13 -0
- data/sig/pvectl/selectors/vm.rbs +19 -0
- data/sig/pvectl/selectors/volume.rbs +13 -0
- data/sig/pvectl/services/backup.rbs +27 -0
- data/sig/pvectl/services/clone_container.rbs +35 -0
- data/sig/pvectl/services/clone_vm.rbs +35 -0
- data/sig/pvectl/services/cloudinit.rbs +19 -0
- data/sig/pvectl/services/console.rbs +23 -0
- data/sig/pvectl/services/container_lifecycle.rbs +26 -0
- data/sig/pvectl/services/create_container.rbs +64 -0
- data/sig/pvectl/services/create_vm.rbs +72 -0
- data/sig/pvectl/services/edit_container.rbs +17 -0
- data/sig/pvectl/services/edit_dns.rbs +23 -0
- data/sig/pvectl/services/edit_hosts.rbs +13 -0
- data/sig/pvectl/services/edit_node.rbs +21 -0
- data/sig/pvectl/services/edit_vm.rbs +17 -0
- data/sig/pvectl/services/edit_volume.rbs +18 -0
- data/sig/pvectl/services/get/resource_service.rbs +23 -0
- data/sig/pvectl/services/move_disk.rbs +21 -0
- data/sig/pvectl/services/pull_config.rbs +18 -0
- data/sig/pvectl/services/push_config.rbs +37 -0
- data/sig/pvectl/services/resize_volume.rbs +47 -0
- data/sig/pvectl/services/resource_delete.rbs +27 -0
- data/sig/pvectl/services/resource_migration.rbs +29 -0
- data/sig/pvectl/services/sendkey.rbs +19 -0
- data/sig/pvectl/services/service_lifecycle.rbs +17 -0
- data/sig/pvectl/services/set_container.rbs +14 -0
- data/sig/pvectl/services/set_node.rbs +23 -0
- data/sig/pvectl/services/set_vm.rbs +14 -0
- data/sig/pvectl/services/set_volume.rbs +12 -0
- data/sig/pvectl/services/snapshot.rbs +35 -0
- data/sig/pvectl/services/task_listing.rbs +13 -0
- data/sig/pvectl/services/unlink_disk.rbs +17 -0
- data/sig/pvectl/services/vm_lifecycle.rbs +26 -0
- data/sig/pvectl/services/wakeonlan.rbs +17 -0
- data/sig/pvectl/utils/resource_resolver.rbs +17 -0
- data/sig/pvectl/wizards/create_container.rbs +21 -0
- data/sig/pvectl/wizards/create_vm.rbs +21 -0
- data/sig/pvectl.rbs +9 -0
- metadata +675 -0
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pvectl
|
|
4
|
+
module Services
|
|
5
|
+
# Orchestrates LXC container creation operations.
|
|
6
|
+
#
|
|
7
|
+
# Handles auto-CTID allocation, parameter building (mapping rootfs/mountpoints/net
|
|
8
|
+
# configs to Proxmox API format), sync/async modes, and optional auto-start.
|
|
9
|
+
#
|
|
10
|
+
# @example Basic container creation
|
|
11
|
+
# service = CreateContainer.new(container_repository: ct_repo, task_repository: task_repo)
|
|
12
|
+
# result = service.execute(hostname: "web-ct", node: "pve1",
|
|
13
|
+
# ostemplate: "local:vztmpl/debian-12.tar.zst",
|
|
14
|
+
# cores: 2, memory: 2048)
|
|
15
|
+
#
|
|
16
|
+
# @example Async creation with auto-start
|
|
17
|
+
# service = CreateContainer.new(container_repository: ct_repo, task_repository: task_repo,
|
|
18
|
+
# options: { async: true, start: true })
|
|
19
|
+
# result = service.execute(ctid: 200, hostname: "db-ct", node: "pve1",
|
|
20
|
+
# ostemplate: "local:vztmpl/debian-12.tar.zst")
|
|
21
|
+
#
|
|
22
|
+
class CreateContainer
|
|
23
|
+
# @return [Integer] Default timeout for create operations (seconds)
|
|
24
|
+
DEFAULT_TIMEOUT = 300
|
|
25
|
+
|
|
26
|
+
# @return [Integer] Default timeout for start operations (seconds)
|
|
27
|
+
START_TIMEOUT = 60
|
|
28
|
+
|
|
29
|
+
# Creates a new CreateContainer service.
|
|
30
|
+
#
|
|
31
|
+
# @param container_repository [Repositories::Container] Container repository
|
|
32
|
+
# @param task_repository [Repositories::Task] Task repository
|
|
33
|
+
# @param options [Hash] Options (timeout, async, start)
|
|
34
|
+
def initialize(container_repository:, task_repository:, options: {})
|
|
35
|
+
@container_repository = container_repository
|
|
36
|
+
@task_repository = task_repository
|
|
37
|
+
@options = options
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Executes container creation operation.
|
|
41
|
+
#
|
|
42
|
+
# @param ctid [Integer, nil] Container identifier (auto-allocated if nil)
|
|
43
|
+
# @param hostname [String] Container hostname
|
|
44
|
+
# @param node [String] Target node
|
|
45
|
+
# @param ostemplate [String] OS template path
|
|
46
|
+
# @param cores [Integer, nil] Number of CPU cores
|
|
47
|
+
# @param memory [Integer, nil] Memory in MB
|
|
48
|
+
# @param swap [Integer, nil] Swap in MB
|
|
49
|
+
# @param rootfs [Hash, nil] Root filesystem config
|
|
50
|
+
# @param mountpoints [Array<Hash>, nil] Mountpoint configurations
|
|
51
|
+
# @param nets [Array<Hash>, nil] Network configurations
|
|
52
|
+
# @param privileged [Boolean, nil] Create privileged container
|
|
53
|
+
# @param features [String, nil] LXC features string
|
|
54
|
+
# @param password [String, nil] Root password
|
|
55
|
+
# @param ssh_public_keys [String, nil] SSH public keys
|
|
56
|
+
# @param onboot [Boolean, nil] Start on boot
|
|
57
|
+
# @param startup [String, nil] Startup order spec
|
|
58
|
+
# @param description [String, nil] Container description
|
|
59
|
+
# @param tags [String, nil] Tags (comma-separated)
|
|
60
|
+
# @param pool [String, nil] Resource pool
|
|
61
|
+
# @return [Models::ContainerOperationResult] Creation result
|
|
62
|
+
def execute(ctid: nil, hostname:, node:, ostemplate:, cores: nil, memory: nil,
|
|
63
|
+
swap: nil, rootfs: nil, mountpoints: nil, nets: nil, privileged: nil,
|
|
64
|
+
features: nil, password: nil, ssh_public_keys: nil, onboot: nil,
|
|
65
|
+
startup: nil, description: nil, tags: nil, pool: nil)
|
|
66
|
+
ctid ||= @container_repository.next_available_ctid
|
|
67
|
+
|
|
68
|
+
params = build_params(
|
|
69
|
+
hostname: hostname, ostemplate: ostemplate, cores: cores, memory: memory,
|
|
70
|
+
swap: swap, rootfs: rootfs, mountpoints: mountpoints, nets: nets,
|
|
71
|
+
privileged: privileged, features: features, password: password,
|
|
72
|
+
ssh_public_keys: ssh_public_keys, onboot: onboot, startup: startup,
|
|
73
|
+
description: description, tags: tags, pool: pool
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
upid = @container_repository.create(node, ctid, params)
|
|
77
|
+
resource_info = { ctid: ctid, hostname: hostname, node: node }
|
|
78
|
+
|
|
79
|
+
if @options[:async]
|
|
80
|
+
build_result(resource_info, task_upid: upid, success: :pending)
|
|
81
|
+
else
|
|
82
|
+
task = @task_repository.wait(upid, timeout: timeout)
|
|
83
|
+
start_container(ctid, node) if task.successful? && @options[:start]
|
|
84
|
+
build_result(resource_info, task: task, success: task.successful?)
|
|
85
|
+
end
|
|
86
|
+
rescue StandardError => e
|
|
87
|
+
build_result({ ctid: ctid, hostname: hostname, node: node },
|
|
88
|
+
success: false, error: e.message)
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
private
|
|
92
|
+
|
|
93
|
+
# Builds Proxmox API parameters from user-friendly options.
|
|
94
|
+
#
|
|
95
|
+
# Maps rootfs/mountpoint configs through {Parsers::LxcMountConfig.to_proxmox} and
|
|
96
|
+
# network configs through {Parsers::LxcNetConfig.to_proxmox}.
|
|
97
|
+
#
|
|
98
|
+
# @return [Hash] Proxmox API parameters
|
|
99
|
+
def build_params(hostname:, ostemplate:, cores:, memory:, swap:, rootfs:,
|
|
100
|
+
mountpoints:, nets:, privileged:, features:, password:,
|
|
101
|
+
ssh_public_keys:, onboot:, startup:, description:, tags:, pool:)
|
|
102
|
+
params = { hostname: hostname, ostemplate: ostemplate }
|
|
103
|
+
params[:cores] = cores if cores
|
|
104
|
+
params[:memory] = memory if memory
|
|
105
|
+
params[:swap] = swap if swap
|
|
106
|
+
params[:unprivileged] = privileged ? 0 : 1 unless privileged.nil?
|
|
107
|
+
params[:rootfs] = Parsers::LxcMountConfig.to_proxmox(rootfs) if rootfs
|
|
108
|
+
add_mountpoint_params(params, mountpoints) if mountpoints
|
|
109
|
+
add_net_params(params, nets) if nets
|
|
110
|
+
params[:features] = features if features
|
|
111
|
+
params[:password] = password if password
|
|
112
|
+
params[:"ssh-public-keys"] = ssh_public_keys if ssh_public_keys
|
|
113
|
+
params[:onboot] = onboot ? 1 : 0 unless onboot.nil?
|
|
114
|
+
params[:startup] = startup if startup
|
|
115
|
+
params[:description] = description if description
|
|
116
|
+
params[:tags] = tags if tags
|
|
117
|
+
params[:pool] = pool if pool
|
|
118
|
+
params
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
# Adds mountpoint parameters mapped to mp0, mp1, etc.
|
|
122
|
+
#
|
|
123
|
+
# @param params [Hash] Parameters hash to modify
|
|
124
|
+
# @param mountpoints [Array<Hash>] Mountpoint configurations
|
|
125
|
+
# @return [void]
|
|
126
|
+
def add_mountpoint_params(params, mountpoints)
|
|
127
|
+
mountpoints.each_with_index do |mp, index|
|
|
128
|
+
params[:"mp#{index}"] = Parsers::LxcMountConfig.to_proxmox(mp)
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
# Adds network parameters mapped to net0, net1, etc.
|
|
133
|
+
#
|
|
134
|
+
# @param params [Hash] Parameters hash to modify
|
|
135
|
+
# @param nets [Array<Hash>] Network configurations
|
|
136
|
+
# @return [void]
|
|
137
|
+
def add_net_params(params, nets)
|
|
138
|
+
nets.each_with_index do |net, index|
|
|
139
|
+
params[:"net#{index}"] = Parsers::LxcNetConfig.to_proxmox(net)
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
# Starts a container after successful creation.
|
|
144
|
+
#
|
|
145
|
+
# @param ctid [Integer] Container identifier
|
|
146
|
+
# @param node [String] Node name
|
|
147
|
+
# @return [void]
|
|
148
|
+
def start_container(ctid, node)
|
|
149
|
+
upid = @container_repository.start(ctid, node)
|
|
150
|
+
@task_repository.wait(upid, timeout: START_TIMEOUT)
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
# Returns configured timeout.
|
|
154
|
+
#
|
|
155
|
+
# @return [Integer] Timeout in seconds
|
|
156
|
+
def timeout
|
|
157
|
+
@options[:timeout] || DEFAULT_TIMEOUT
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
# Builds a ContainerOperationResult with the :create operation.
|
|
161
|
+
#
|
|
162
|
+
# Creates a minimal Container model for presenter compatibility.
|
|
163
|
+
#
|
|
164
|
+
# @param resource_info [Hash] Resource info (ctid, hostname, node)
|
|
165
|
+
# @param attrs [Hash] Additional result attributes
|
|
166
|
+
# @return [Models::ContainerOperationResult] Operation result
|
|
167
|
+
def build_result(resource_info, **attrs)
|
|
168
|
+
container = Models::Container.new(
|
|
169
|
+
vmid: resource_info[:ctid],
|
|
170
|
+
name: resource_info[:hostname],
|
|
171
|
+
node: resource_info[:node]
|
|
172
|
+
)
|
|
173
|
+
Models::ContainerOperationResult.new(
|
|
174
|
+
operation: :create, container: container, resource: resource_info, **attrs
|
|
175
|
+
)
|
|
176
|
+
end
|
|
177
|
+
end
|
|
178
|
+
end
|
|
179
|
+
end
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pvectl
|
|
4
|
+
module Services
|
|
5
|
+
# Orchestrates VM creation operations.
|
|
6
|
+
#
|
|
7
|
+
# Handles auto-VMID allocation, parameter building (mapping disk/net/cloud-init
|
|
8
|
+
# configs to Proxmox API format), sync/async modes, and optional auto-start.
|
|
9
|
+
#
|
|
10
|
+
# @example Basic VM creation
|
|
11
|
+
# service = CreateVm.new(vm_repository: vm_repo, task_repository: task_repo)
|
|
12
|
+
# result = service.execute(name: "web-server", node: "pve1",
|
|
13
|
+
# cores: 4, memory: 4096,
|
|
14
|
+
# disks: [{ storage: "local-lvm", size: "32G" }])
|
|
15
|
+
#
|
|
16
|
+
# @example Async creation with auto-start
|
|
17
|
+
# service = CreateVm.new(vm_repository: vm_repo, task_repository: task_repo,
|
|
18
|
+
# options: { async: true, start: true })
|
|
19
|
+
# result = service.execute(vmid: 200, name: "db-server", node: "pve1",
|
|
20
|
+
# cores: 8, memory: 16384)
|
|
21
|
+
#
|
|
22
|
+
class CreateVm
|
|
23
|
+
# @return [Integer] Default timeout for create operations (seconds)
|
|
24
|
+
DEFAULT_TIMEOUT = 300
|
|
25
|
+
|
|
26
|
+
# @return [Integer] Default timeout for start operations (seconds)
|
|
27
|
+
START_TIMEOUT = 60
|
|
28
|
+
|
|
29
|
+
# Creates a new CreateVm service.
|
|
30
|
+
#
|
|
31
|
+
# @param vm_repository [Repositories::Vm] VM repository
|
|
32
|
+
# @param task_repository [Repositories::Task] Task repository
|
|
33
|
+
# @param options [Hash] Options (timeout, async, start)
|
|
34
|
+
def initialize(vm_repository:, task_repository:, options: {})
|
|
35
|
+
@vm_repository = vm_repository
|
|
36
|
+
@task_repository = task_repository
|
|
37
|
+
@options = options
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Executes VM creation operation.
|
|
41
|
+
#
|
|
42
|
+
# @param vmid [Integer, nil] VM identifier (auto-allocated if nil)
|
|
43
|
+
# @param name [String] VM name
|
|
44
|
+
# @param node [String] Target node
|
|
45
|
+
# @param cores [Integer, nil] Number of CPU cores
|
|
46
|
+
# @param sockets [Integer, nil] Number of CPU sockets
|
|
47
|
+
# @param cpu_type [String, nil] CPU type (e.g. "host", "kvm64")
|
|
48
|
+
# @param numa [Boolean, nil] Enable NUMA
|
|
49
|
+
# @param memory [Integer, nil] Memory in MB
|
|
50
|
+
# @param balloon [Integer, nil] Balloon memory in MB
|
|
51
|
+
# @param disks [Array<Hash>, nil] Disk configurations
|
|
52
|
+
# @param scsihw [String, nil] SCSI controller type
|
|
53
|
+
# @param cdrom [String, nil] CD-ROM ISO path
|
|
54
|
+
# @param nets [Array<Hash>, nil] Network configurations
|
|
55
|
+
# @param bios [String, nil] BIOS type (seabios or ovmf)
|
|
56
|
+
# @param boot_order [String, nil] Boot order (e.g. "scsi0;net0")
|
|
57
|
+
# @param machine [String, nil] Machine type (e.g. "q35")
|
|
58
|
+
# @param efidisk [String, nil] EFI disk specification
|
|
59
|
+
# @param cloud_init [Hash, nil] Cloud-init parameters
|
|
60
|
+
# @param agent [Boolean, nil] Enable QEMU guest agent
|
|
61
|
+
# @param ostype [String, nil] OS type (e.g. "l26", "win10")
|
|
62
|
+
# @param description [String, nil] VM description
|
|
63
|
+
# @param tags [String, nil] Tags (semicolon-separated)
|
|
64
|
+
# @param pool [String, nil] Resource pool
|
|
65
|
+
# @return [Models::VmOperationResult] Creation result
|
|
66
|
+
def execute(vmid: nil, name:, node:, cores: nil, sockets: nil, cpu_type: nil,
|
|
67
|
+
numa: nil, memory: nil, balloon: nil, disks: nil, scsihw: nil,
|
|
68
|
+
cdrom: nil, nets: nil, bios: nil, boot_order: nil, machine: nil,
|
|
69
|
+
efidisk: nil, cloud_init: nil, agent: nil, ostype: nil,
|
|
70
|
+
description: nil, tags: nil, pool: nil)
|
|
71
|
+
vmid ||= @vm_repository.next_available_vmid
|
|
72
|
+
|
|
73
|
+
params = build_params(
|
|
74
|
+
name: name, cores: cores, sockets: sockets, cpu_type: cpu_type,
|
|
75
|
+
numa: numa, memory: memory, balloon: balloon, disks: disks,
|
|
76
|
+
scsihw: scsihw, cdrom: cdrom, nets: nets, bios: bios,
|
|
77
|
+
boot_order: boot_order, machine: machine, efidisk: efidisk,
|
|
78
|
+
cloud_init: cloud_init, agent: agent, ostype: ostype,
|
|
79
|
+
description: description, tags: tags, pool: pool
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
upid = @vm_repository.create(node, vmid, params)
|
|
83
|
+
resource_info = { vmid: vmid, name: name, node: node }
|
|
84
|
+
|
|
85
|
+
if @options[:async]
|
|
86
|
+
build_result(resource_info, task_upid: upid, success: :pending)
|
|
87
|
+
else
|
|
88
|
+
task = @task_repository.wait(upid, timeout: timeout)
|
|
89
|
+
start_vm(vmid, node) if task.successful? && @options[:start]
|
|
90
|
+
build_result(resource_info, task: task, success: task.successful?)
|
|
91
|
+
end
|
|
92
|
+
rescue StandardError => e
|
|
93
|
+
build_result({ vmid: vmid, name: name, node: node },
|
|
94
|
+
success: false, error: e.message)
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
private
|
|
98
|
+
|
|
99
|
+
# Builds Proxmox API parameters from user-friendly options.
|
|
100
|
+
#
|
|
101
|
+
# Maps disk configs through {Parsers::DiskConfig.to_proxmox} and
|
|
102
|
+
# network configs through {Parsers::NetConfig.to_proxmox}.
|
|
103
|
+
#
|
|
104
|
+
# @return [Hash] Proxmox API parameters
|
|
105
|
+
def build_params(name:, cores:, sockets:, cpu_type:, numa:, memory:,
|
|
106
|
+
balloon:, disks:, scsihw:, cdrom:, nets:, bios:,
|
|
107
|
+
boot_order:, machine:, efidisk:, cloud_init:, agent:,
|
|
108
|
+
ostype:, description:, tags:, pool:)
|
|
109
|
+
params = { name: name }
|
|
110
|
+
params[:cores] = cores if cores
|
|
111
|
+
params[:sockets] = sockets if sockets
|
|
112
|
+
params[:cpu] = cpu_type if cpu_type
|
|
113
|
+
params[:numa] = numa ? 1 : 0 unless numa.nil?
|
|
114
|
+
params[:memory] = memory if memory
|
|
115
|
+
params[:balloon] = balloon if balloon
|
|
116
|
+
add_disk_params(params, disks) if disks
|
|
117
|
+
params[:scsihw] = scsihw if scsihw
|
|
118
|
+
params[:cdrom] = cdrom if cdrom
|
|
119
|
+
add_net_params(params, nets) if nets
|
|
120
|
+
params[:bios] = bios if bios
|
|
121
|
+
params[:boot] = "order=#{boot_order}" if boot_order
|
|
122
|
+
params[:machine] = machine if machine
|
|
123
|
+
params[:efidisk0] = efidisk if efidisk
|
|
124
|
+
params.merge!(cloud_init) if cloud_init
|
|
125
|
+
params[:agent] = agent ? "1" : "0" unless agent.nil?
|
|
126
|
+
params[:ostype] = ostype if ostype
|
|
127
|
+
params[:description] = description if description
|
|
128
|
+
params[:tags] = tags if tags
|
|
129
|
+
params[:pool] = pool if pool
|
|
130
|
+
params
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
# Adds disk parameters mapped to scsi0, scsi1, etc.
|
|
134
|
+
#
|
|
135
|
+
# @param params [Hash] Parameters hash to modify
|
|
136
|
+
# @param disks [Array<Hash>] Disk configurations
|
|
137
|
+
# @return [void]
|
|
138
|
+
def add_disk_params(params, disks)
|
|
139
|
+
disks.each_with_index do |disk, index|
|
|
140
|
+
params[:"scsi#{index}"] = Parsers::DiskConfig.to_proxmox(disk)
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
# Adds network parameters mapped to net0, net1, etc.
|
|
145
|
+
#
|
|
146
|
+
# @param params [Hash] Parameters hash to modify
|
|
147
|
+
# @param nets [Array<Hash>] Network configurations
|
|
148
|
+
# @return [void]
|
|
149
|
+
def add_net_params(params, nets)
|
|
150
|
+
nets.each_with_index do |net, index|
|
|
151
|
+
params[:"net#{index}"] = Parsers::NetConfig.to_proxmox(net)
|
|
152
|
+
end
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
# Starts a VM after successful creation.
|
|
156
|
+
#
|
|
157
|
+
# @param vmid [Integer] VM identifier
|
|
158
|
+
# @param node [String] Node name
|
|
159
|
+
# @return [void]
|
|
160
|
+
def start_vm(vmid, node)
|
|
161
|
+
upid = @vm_repository.start(vmid, node)
|
|
162
|
+
@task_repository.wait(upid, timeout: START_TIMEOUT)
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
# Returns configured timeout.
|
|
166
|
+
#
|
|
167
|
+
# @return [Integer] Timeout in seconds
|
|
168
|
+
def timeout
|
|
169
|
+
@options[:timeout] || DEFAULT_TIMEOUT
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
# Builds a VmOperationResult with the :create operation.
|
|
173
|
+
#
|
|
174
|
+
# Creates a minimal Vm model for presenter compatibility.
|
|
175
|
+
#
|
|
176
|
+
# @param resource_info [Hash] Resource info (vmid, name, node)
|
|
177
|
+
# @param attrs [Hash] Additional result attributes
|
|
178
|
+
# @return [Models::VmOperationResult] Operation result
|
|
179
|
+
def build_result(resource_info, **attrs)
|
|
180
|
+
vm = Models::Vm.new(
|
|
181
|
+
vmid: resource_info[:vmid],
|
|
182
|
+
name: resource_info[:name],
|
|
183
|
+
node: resource_info[:node]
|
|
184
|
+
)
|
|
185
|
+
Models::VmOperationResult.new(
|
|
186
|
+
operation: :create, vm: vm, resource: resource_info, **attrs
|
|
187
|
+
)
|
|
188
|
+
end
|
|
189
|
+
end
|
|
190
|
+
end
|
|
191
|
+
end
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pvectl
|
|
4
|
+
module Services
|
|
5
|
+
# Orchestrates the interactive container configuration editing flow.
|
|
6
|
+
#
|
|
7
|
+
# Fetches current config, opens it in an editor as structured YAML,
|
|
8
|
+
# validates changes, computes a diff, and applies updates via the API.
|
|
9
|
+
# Supports dry-run mode and optimistic locking via digest.
|
|
10
|
+
#
|
|
11
|
+
# @example Basic usage
|
|
12
|
+
# service = EditContainer.new(container_repository: repo)
|
|
13
|
+
# result = service.execute(ctid: 200)
|
|
14
|
+
#
|
|
15
|
+
# @example Dry run with injected editor session
|
|
16
|
+
# service = EditContainer.new(container_repository: repo, editor_session: session,
|
|
17
|
+
# options: { dry_run: true })
|
|
18
|
+
# result = service.execute(ctid: 200)
|
|
19
|
+
#
|
|
20
|
+
class EditContainer
|
|
21
|
+
# Creates a new EditContainer service.
|
|
22
|
+
#
|
|
23
|
+
# @param container_repository [Repositories::Container] Container repository
|
|
24
|
+
# @param editor_session [EditorSession, nil] optional injected editor session
|
|
25
|
+
# @param options [Hash] options (dry_run)
|
|
26
|
+
def initialize(container_repository:, editor_session: nil, options: {})
|
|
27
|
+
@container_repository = container_repository
|
|
28
|
+
@editor_session = editor_session
|
|
29
|
+
@options = options
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Executes the interactive container edit flow.
|
|
33
|
+
#
|
|
34
|
+
# @param ctid [Integer] Container identifier
|
|
35
|
+
# @return [Models::ContainerOperationResult, nil] operation result, or nil if cancelled/no changes
|
|
36
|
+
def execute(ctid:)
|
|
37
|
+
container = @container_repository.get(ctid)
|
|
38
|
+
return not_found_result(ctid) unless container
|
|
39
|
+
|
|
40
|
+
config = @container_repository.fetch_config(container.node, ctid)
|
|
41
|
+
resource_info = { ctid: ctid, node: container.node, status: container.status }
|
|
42
|
+
|
|
43
|
+
yaml_content = ConfigSerializer.to_yaml(config, type: :container, resource: resource_info)
|
|
44
|
+
|
|
45
|
+
validator = ->(content) { ConfigSerializer.validate(content, type: :container) }
|
|
46
|
+
session = @editor_session || EditorSession.new(validator: validator)
|
|
47
|
+
edited = session.edit(yaml_content)
|
|
48
|
+
|
|
49
|
+
return nil unless edited
|
|
50
|
+
|
|
51
|
+
original_roundtrip = ConfigSerializer.from_yaml(yaml_content, type: :container)
|
|
52
|
+
edited_flat = ConfigSerializer.from_yaml(edited, type: :container)
|
|
53
|
+
|
|
54
|
+
violations = ConfigSerializer.readonly_violations(original_roundtrip, edited_flat, type: :container)
|
|
55
|
+
unless violations.empty?
|
|
56
|
+
return build_result(resource_info, success: false,
|
|
57
|
+
error: "Read-only fields cannot be changed: #{violations.join(', ')}")
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
changes = ConfigSerializer.diff(original_roundtrip, edited_flat)
|
|
61
|
+
|
|
62
|
+
if changes[:changed].empty? && changes[:added].empty? && changes[:removed].empty?
|
|
63
|
+
return nil
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
params = build_update_params(changes, config)
|
|
67
|
+
|
|
68
|
+
resource_info[:diff] = changes
|
|
69
|
+
|
|
70
|
+
if @options[:dry_run]
|
|
71
|
+
return build_result(resource_info, success: true)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
@container_repository.update(ctid, container.node, params)
|
|
75
|
+
build_result(resource_info, success: true)
|
|
76
|
+
rescue StandardError => e
|
|
77
|
+
build_result({ ctid: ctid }, success: false, error: e.message)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
private
|
|
81
|
+
|
|
82
|
+
# Builds API update parameters from a diff hash.
|
|
83
|
+
#
|
|
84
|
+
# Maps changed/added keys to their new values, removed keys to the
|
|
85
|
+
# Proxmox `delete` parameter, and includes digest for optimistic locking.
|
|
86
|
+
#
|
|
87
|
+
# @param changes [Hash] diff hash with :changed, :added, :removed
|
|
88
|
+
# @param original_config [Hash] original flat config (for digest)
|
|
89
|
+
# @return [Hash] Proxmox API parameters
|
|
90
|
+
def build_update_params(changes, original_config)
|
|
91
|
+
params = {}
|
|
92
|
+
changes[:changed].each { |key, (_old, new_val)| params[key] = new_val }
|
|
93
|
+
changes[:added].each { |key, val| params[key] = val }
|
|
94
|
+
unless changes[:removed].empty?
|
|
95
|
+
params[:delete] = changes[:removed].map(&:to_s).join(",")
|
|
96
|
+
end
|
|
97
|
+
params[:digest] = original_config[:digest] if original_config[:digest]
|
|
98
|
+
params
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
# Builds a ContainerOperationResult with the :edit operation.
|
|
102
|
+
#
|
|
103
|
+
# @param resource_info [Hash] resource info (ctid, node, status)
|
|
104
|
+
# @param attrs [Hash] additional result attributes
|
|
105
|
+
# @return [Models::ContainerOperationResult]
|
|
106
|
+
def build_result(resource_info, **attrs)
|
|
107
|
+
container = Models::Container.new(
|
|
108
|
+
vmid: resource_info[:ctid],
|
|
109
|
+
node: resource_info[:node]
|
|
110
|
+
)
|
|
111
|
+
Models::ContainerOperationResult.new(
|
|
112
|
+
operation: :edit, container: container, resource: resource_info, **attrs
|
|
113
|
+
)
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
# Builds a not-found error result.
|
|
117
|
+
#
|
|
118
|
+
# @param ctid [Integer] Container identifier
|
|
119
|
+
# @return [Models::ContainerOperationResult]
|
|
120
|
+
def not_found_result(ctid)
|
|
121
|
+
build_result({ ctid: ctid }, success: false, error: "Container #{ctid} not found")
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
end
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Pvectl
|
|
4
|
+
module Services
|
|
5
|
+
# Orchestrates the interactive editing flow for node DNS settings.
|
|
6
|
+
#
|
|
7
|
+
# Fetches current DNS config, presents it as YAML in an editor, computes
|
|
8
|
+
# a diff, and applies changes via the Proxmox API. The Proxmox PUT endpoint
|
|
9
|
+
# requires the `search` field — the service validates this before calling.
|
|
10
|
+
#
|
|
11
|
+
# @example Basic usage
|
|
12
|
+
# service = EditDns.new(dns_repository: repo)
|
|
13
|
+
# result = service.execute(node_name: "pve1")
|
|
14
|
+
#
|
|
15
|
+
# @example Dry run
|
|
16
|
+
# service = EditDns.new(dns_repository: repo, options: { dry_run: true })
|
|
17
|
+
# result = service.execute(node_name: "pve1")
|
|
18
|
+
#
|
|
19
|
+
class EditDns
|
|
20
|
+
# Editable keys exposed in the YAML editor (in order).
|
|
21
|
+
EDITABLE_KEYS = %i[search dns1 dns2 dns3].freeze
|
|
22
|
+
|
|
23
|
+
# Creates a new EditDns service.
|
|
24
|
+
#
|
|
25
|
+
# @param dns_repository [Repositories::Dns] DNS repository
|
|
26
|
+
# @param editor_session [EditorSession, nil] optional injected editor session
|
|
27
|
+
# @param options [Hash] options (dry_run)
|
|
28
|
+
def initialize(dns_repository:, editor_session: nil, options: {})
|
|
29
|
+
@dns_repository = dns_repository
|
|
30
|
+
@editor_session = editor_session
|
|
31
|
+
@options = options
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Executes the interactive DNS edit flow.
|
|
35
|
+
#
|
|
36
|
+
# @param node_name [String] node name
|
|
37
|
+
# @return [Models::NodeOperationResult, nil] result, or nil if cancelled/no changes
|
|
38
|
+
def execute(node_name:)
|
|
39
|
+
dns = @dns_repository.fetch(node_name)
|
|
40
|
+
resource_info = { node_name: node_name }
|
|
41
|
+
|
|
42
|
+
editable = build_editable(dns)
|
|
43
|
+
yaml_content = "# Node: #{node_name} — DNS configuration\n" \
|
|
44
|
+
"# 'search' is required by Proxmox. dns1/dns2/dns3 are optional.\n" +
|
|
45
|
+
editable.to_yaml
|
|
46
|
+
|
|
47
|
+
session = @editor_session || EditorSession.new
|
|
48
|
+
edited = session.edit(yaml_content)
|
|
49
|
+
|
|
50
|
+
return nil unless edited
|
|
51
|
+
|
|
52
|
+
cleaned = edited.lines.reject { |l| l.strip.start_with?("#") }.join
|
|
53
|
+
edited_config = YAML.safe_load(cleaned, symbolize_names: true) || {}
|
|
54
|
+
|
|
55
|
+
original_symbolized = editable.transform_keys(&:to_sym)
|
|
56
|
+
changes = compute_diff(original_symbolized, edited_config)
|
|
57
|
+
|
|
58
|
+
if changes[:changed].empty? && changes[:added].empty? && changes[:removed].empty?
|
|
59
|
+
return nil
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
validate!(edited_config)
|
|
63
|
+
|
|
64
|
+
resource_info[:diff] = changes
|
|
65
|
+
|
|
66
|
+
return build_result(resource_info, success: true) if @options[:dry_run]
|
|
67
|
+
|
|
68
|
+
@dns_repository.update(node_name, build_update_params(edited_config))
|
|
69
|
+
build_result(resource_info, success: true)
|
|
70
|
+
rescue StandardError => e
|
|
71
|
+
build_result({ node_name: node_name }, success: false, error: e.message)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
private
|
|
75
|
+
|
|
76
|
+
# Builds editable hash (string-keyed) from a DnsConfig model.
|
|
77
|
+
#
|
|
78
|
+
# @param dns [Models::DnsConfig] current config
|
|
79
|
+
# @return [Hash{String=>String}] editable values
|
|
80
|
+
def build_editable(dns)
|
|
81
|
+
{
|
|
82
|
+
"search" => dns.search,
|
|
83
|
+
"dns1" => dns.dns1,
|
|
84
|
+
"dns2" => dns.dns2,
|
|
85
|
+
"dns3" => dns.dns3
|
|
86
|
+
}.compact
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# Validates the edited config satisfies API requirements.
|
|
90
|
+
#
|
|
91
|
+
# @param edited [Hash] edited config with symbol keys
|
|
92
|
+
# @return [void]
|
|
93
|
+
# @raise [ArgumentError] if `search` is missing or empty
|
|
94
|
+
def validate!(edited)
|
|
95
|
+
search = edited[:search]
|
|
96
|
+
if search.nil? || search.to_s.strip.empty?
|
|
97
|
+
raise ArgumentError, "search field is required by Proxmox API"
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
# Computes diff between original and edited configs.
|
|
102
|
+
#
|
|
103
|
+
# @param original [Hash] original config (symbol keys)
|
|
104
|
+
# @param edited [Hash] edited config (symbol keys)
|
|
105
|
+
# @return [Hash] diff with :changed, :added, :removed
|
|
106
|
+
def compute_diff(original, edited)
|
|
107
|
+
changed = {}
|
|
108
|
+
added = {}
|
|
109
|
+
removed = []
|
|
110
|
+
|
|
111
|
+
edited.each do |key, value|
|
|
112
|
+
orig_value = original[key]
|
|
113
|
+
if orig_value.nil?
|
|
114
|
+
added[key] = value
|
|
115
|
+
elsif orig_value.to_s != value.to_s
|
|
116
|
+
changed[key] = [orig_value.to_s, value.to_s]
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
original.each_key do |key|
|
|
121
|
+
removed << key unless edited.key?(key)
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
{ changed: changed, added: added, removed: removed }
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
# Builds API update parameters from edited config.
|
|
128
|
+
#
|
|
129
|
+
# The PUT endpoint requires `search` and accepts optional dns1-3.
|
|
130
|
+
# Removed keys are sent as empty strings to clear the field
|
|
131
|
+
# (Proxmox accepts empty strings as "unset" for optional dns* fields).
|
|
132
|
+
#
|
|
133
|
+
# @param edited [Hash] edited config (symbol keys)
|
|
134
|
+
# @return [Hash] API parameters with all editable keys present
|
|
135
|
+
def build_update_params(edited)
|
|
136
|
+
params = {}
|
|
137
|
+
EDITABLE_KEYS.each do |key|
|
|
138
|
+
value = edited[key]
|
|
139
|
+
params[key] = value.nil? ? "" : value
|
|
140
|
+
end
|
|
141
|
+
# search must always have a real value (validated above)
|
|
142
|
+
params[:search] = edited[:search]
|
|
143
|
+
params
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
# Builds a NodeOperationResult with the :edit operation.
|
|
147
|
+
#
|
|
148
|
+
# @param resource_info [Hash] resource info (node_name)
|
|
149
|
+
# @param attrs [Hash] additional result attributes
|
|
150
|
+
# @return [Models::NodeOperationResult]
|
|
151
|
+
def build_result(resource_info, **attrs)
|
|
152
|
+
node_model = Models::Node.new(name: resource_info[:node_name])
|
|
153
|
+
Models::NodeOperationResult.new(
|
|
154
|
+
operation: :edit, node_model: node_model, resource: resource_info, **attrs
|
|
155
|
+
)
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
end
|