Class: Pvectl::Services::EditDns

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

Overview

Orchestrates the interactive editing flow for node DNS settings.

Fetches current DNS config, presents it as YAML in an editor, computes a diff, and applies changes via the Proxmox API. The Proxmox PUT endpoint requires the ‘search` field — the service validates this before calling.

Examples:

Basic usage

service = EditDns.new(dns_repository: repo)
result = service.execute(node_name: "pve1")

Dry run

service = EditDns.new(dns_repository: repo, options: { dry_run: true })
result = service.execute(node_name: "pve1")

Constant Summary collapse

EDITABLE_KEYS =

Editable keys exposed in the YAML editor (in order).

%i[search dns1 dns2 dns3].freeze

Instance Method Summary collapse

Constructor Details

#initialize(dns_repository:, editor_session: nil, options: {}) ⇒ EditDns

Creates a new EditDns service.

Parameters:

  • dns_repository (Repositories::Dns)

    DNS repository

  • editor_session (EditorSession, nil) (defaults to: nil)

    optional injected editor session

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

    options (dry_run)



28
29
30
31
32
# File 'lib/pvectl/services/edit_dns.rb', line 28

def initialize(dns_repository:, editor_session: nil, options: {})
  @dns_repository = dns_repository
  @editor_session = editor_session
  @options = options
end

Instance Method Details

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

Executes the interactive DNS edit flow.

Parameters:

  • node_name (String)

    node name

Returns:



38
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
# File 'lib/pvectl/services/edit_dns.rb', line 38

def execute(node_name:)
  dns = @dns_repository.fetch(node_name)
  resource_info = { node_name: node_name }

  editable = build_editable(dns)
  yaml_content = "# Node: #{node_name} — DNS configuration\n" \
                 "# 'search' is required by Proxmox. dns1/dns2/dns3 are optional.\n" +
                 editable.to_yaml

  session = @editor_session || EditorSession.new
  edited = session.edit(yaml_content)

  return nil unless edited

  cleaned = edited.lines.reject { |l| l.strip.start_with?("#") }.join
  edited_config = YAML.safe_load(cleaned, symbolize_names: true) || {}

  original_symbolized = editable.transform_keys(&:to_sym)
  changes = compute_diff(original_symbolized, edited_config)

  if changes[:changed].empty? && changes[:added].empty? && changes[:removed].empty?
    return nil
  end

  validate!(edited_config)

  resource_info[:diff] = changes

  return build_result(resource_info, success: true) if @options[:dry_run]

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