Class: Pvectl::Services::SetNode

Inherits:
Object
  • Object
show all
Defined in:
lib/pvectl/services/set_node.rb

Overview

Orchestrates non-interactive node configuration updates.

Takes key-value pairs directly (no editor), computes diff against current config, and applies changes via the API. Supports dry-run mode and optimistic locking via digest.

The ‘timezone` key is special: it lives at `PUT /nodes/node/time` rather than `PUT /nodes/node/config`, so the service splits it off and routes it to a separate `time_repository`.

Examples:

Basic usage

service = SetNode.new(node_repository: repo)
result = service.execute(node_name: "pve1", params: { description: "updated" })

Setting timezone

service = SetNode.new(node_repository: node_repo, time_repository: time_repo)
result = service.execute(node_name: "pve1", params: { timezone: "Europe/Warsaw" })

Dry run

service = SetNode.new(node_repository: repo, options: { dry_run: true })
result = service.execute(node_name: "pve1", params: { description: "updated" })

Constant Summary collapse

TIMEZONE_KEY =

Key recognized by this service as the node timezone (handled by the ‘/time` endpoint rather than `/config`). Accepted as Symbol or String.

:timezone

Instance Method Summary collapse

Constructor Details

#initialize(node_repository:, time_repository: nil, options: {}) ⇒ SetNode

Creates a new SetNode service.

Parameters:

  • node_repository (Repositories::Node)

    Node repository

  • time_repository (Repositories::TimeConfig, nil) (defaults to: nil)

    Time repository (optional; required only when ‘params` includes `:timezone`)

  • options (Hash) (defaults to: {})

    options (dry_run)



38
39
40
41
42
# File 'lib/pvectl/services/set_node.rb', line 38

def initialize(node_repository:, time_repository: nil, options: {})
  @node_repository = node_repository
  @time_repository = time_repository
  @options = options
end

Instance Method Details

#execute(node_name:, params:) ⇒ Models::NodeOperationResult?

Executes the non-interactive node config update.

Fetches current config and (if timezone is requested) current timezone, computes diffs against the requested params, and applies changes via the appropriate API endpoint (unless dry-run).

Parameters:

  • node_name (String)

    Node name

  • params (Hash)

    key-value pairs to set

Returns:



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/pvectl/services/set_node.rb', line 53

def execute(node_name:, params:)
  node = @node_repository.get(node_name)
  return not_found_result(node_name) unless node

  config = @node_repository.fetch_config(node_name)
  config_params, requested_tz = split_timezone(params)
  current_tz = requested_tz ? current_timezone(node_name) : nil

  changes = compute_diff(config, config_params)
  tz_change = compute_timezone_change(current_tz, requested_tz)
  merge_timezone_into_diff(changes, tz_change) if tz_change

  return nil if no_changes?(changes)

  resource_info = { node_name: node_name, status: node.status, diff: changes }
  return build_result(resource_info, success: true) if @options[:dry_run]

  apply_config_changes(node_name, changes, config) unless config_changes_empty?(changes, tz_change)
  @time_repository.set_timezone(node_name, tz_change[:to]) if tz_change

  build_result(resource_info, success: true)
rescue StandardError => e
  build_result({ node_name: node_name }, success: false, error: e.message)
end