Class: Pvectl::Services::EditNode
- Inherits:
-
Object
- Object
- Pvectl::Services::EditNode
- Defined in:
- lib/pvectl/services/edit_node.rb
Overview
Orchestrates the interactive node configuration editing flow.
Fetches current config, presents it as YAML in an editor, computes diff, and applies changes. Uses plain YAML (not ConfigSerializer) since node config is flat key-value.
Constant Summary collapse
- READONLY_KEYS =
Read-only keys that should not be sent back to the API.
%i[digest].freeze
Instance Method Summary collapse
-
#execute(node_name:) ⇒ Models::NodeOperationResult?
Executes the interactive node edit flow.
-
#initialize(node_repository:, editor_session: nil, options: {}) ⇒ EditNode
constructor
Creates a new EditNode service.
Constructor Details
#initialize(node_repository:, editor_session: nil, options: {}) ⇒ EditNode
Creates a new EditNode service.
29 30 31 32 33 |
# File 'lib/pvectl/services/edit_node.rb', line 29 def initialize(node_repository:, editor_session: nil, options: {}) @node_repository = node_repository @editor_session = editor_session @options = end |
Instance Method Details
#execute(node_name:) ⇒ Models::NodeOperationResult?
Executes the interactive node edit flow.
39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/pvectl/services/edit_node.rb', line 39 def execute(node_name:) node = @node_repository.get(node_name) return not_found_result(node_name) unless node config = @node_repository.fetch_config(node_name) resource_info = { node_name: node_name, status: node.status } # Build editable YAML (exclude digest — it's for optimistic locking only) editable = config.reject { |k, _| READONLY_KEYS.include?(k) } # Convert symbol keys to strings for clean YAML output (avoids :key: format) string_keyed = editable.transform_keys(&:to_s) yaml_content = "# Node: #{node_name}\n# Edit configuration below. Save and close to apply.\n" + string_keyed.to_yaml session = @editor_session || EditorSession.new edited = session.edit(yaml_content) return nil unless edited # Parse edited YAML (strip comment lines) cleaned = edited.lines.reject { |l| l.strip.start_with?("#") }.join edited_config = YAML.safe_load(cleaned, symbolize_names: true) || {} # Compute diff against original editable config (with symbol keys) changes = compute_diff(editable, edited_config) if changes[:changed].empty? && changes[:added].empty? && changes[:removed].empty? return nil end resource_info[:diff] = changes if @options[:dry_run] return build_result(resource_info, success: true) end update_params = build_update_params(changes, config) @node_repository.update(node_name, update_params) build_result(resource_info, success: true) rescue StandardError => e build_result({ node_name: node_name }, success: false, error: e.) end |