Class: Pvectl::Commands::Get::Handlers::Nodes

Inherits:
Object
  • Object
show all
Includes:
ResourceHandler
Defined in:
lib/pvectl/commands/get/handlers/nodes.rb,
sig/pvectl/commands/get/handlers/nodes.rbs

Overview

Handler for listing Proxmox cluster nodes.

Implements ResourceHandler interface for the "nodes" resource type. Uses Repositories::Node for data access and Presenters::Node for formatting.

Supports filtering by status and sorting by various fields.

Examples:

Using via ResourceRegistry

handler = ResourceRegistry.for("nodes")
nodes = handler.list(filter: { status: "online" }, sort: "memory")

See Also:

Constant Summary collapse

SORT_FIELDS =

Sort field mappings. Negative values for descending sort (higher values first).

{
  "name" => ->(n) { n.name },
  "status" => ->(n) { n.status },
  "cpu" => ->(n) { -(n.cpu || 0) },
  "memory" => ->(n) { -(n.mem || 0) },
  "disk" => ->(n) { -(n.disk || 0) },
  "guests" => ->(n) { -n.guests_total },
  "uptime" => ->(n) { -(n.uptime || 0) }
}.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from ResourceHandler

#selector_class

Constructor Details

#initialize(repository: nil) ⇒ Nodes

Creates handler with optional repository for dependency injection.



40
41
42
# File 'lib/pvectl/commands/get/handlers/nodes.rb', line 40

def initialize(repository: nil)
  @repository = repository
end

Instance Attribute Details

#repositoryRepositories::Node (readonly)

Returns repository, creating it if necessary.



97
98
99
# File 'lib/pvectl/commands/get/handlers/nodes.rb', line 97

def repository
  @repository ||= build_repository
end

Instance Method Details

#apply_filters(nodes, filter) ⇒ Array<Models::Node>

Applies filter criteria to nodes collection.



116
117
118
119
120
121
122
123
124
# File 'lib/pvectl/commands/get/handlers/nodes.rb', line 116

def apply_filters(nodes, filter)
  filter.each do |key, value|
    case key.to_s
    when "status"
      nodes = nodes.select { |n| n.status == value }
    end
  end
  nodes
end

#apply_sort(nodes, sort_field) ⇒ Array<Models::Node>

Applies sorting to nodes collection.



131
132
133
134
135
136
# File 'lib/pvectl/commands/get/handlers/nodes.rb', line 131

def apply_sort(nodes, sort_field)
  sort_proc = SORT_FIELDS[sort_field.to_s]
  return nodes unless sort_proc

  nodes.sort_by(&sort_proc)
end

#build_repositoryRepositories::Node

Builds repository with connection from config.



104
105
106
107
108
109
# File 'lib/pvectl/commands/get/handlers/nodes.rb', line 104

def build_repository
  config_service = Pvectl::Config::Service.new
  config_service.load
  connection = Pvectl::Connection.new(config_service.current_config)
  Pvectl::Repositories::Node.new(connection)
end

#describe(name:, node: nil, args: [], vmid: nil) ⇒ Models::Node

Describes a single node with comprehensive details.

Raises:



83
84
85
86
87
88
89
90
# File 'lib/pvectl/commands/get/handlers/nodes.rb', line 83

def describe(name:, node: nil, args: [], vmid: nil)
  raise ArgumentError, "Invalid node name" unless valid_node_name?(name)

  node = repository.describe(name)
  raise Pvectl::ResourceNotFoundError, "Node not found: #{name}" if node.nil?

  node
end

#list(node: nil, name: nil, args: [], storage: nil, filter: nil, sort: nil, include_details: true, **_options) ⇒ Array<Models::Node>

Lists nodes with optional filtering and sorting.



54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/pvectl/commands/get/handlers/nodes.rb', line 54

def list(node: nil, name: nil, args: [], storage: nil, filter: nil, sort: nil, include_details: true, **_options)
  nodes = repository.list(include_details: include_details)

  # Filter by name
  nodes = nodes.select { |n| n.name == name } if name

  # Apply filters
  nodes = apply_filters(nodes, filter) if filter

  # Apply sorting
  nodes = apply_sort(nodes, sort) if sort

  nodes
end

#presenterPresenters::Node

Returns presenter for nodes.



72
73
74
# File 'lib/pvectl/commands/get/handlers/nodes.rb', line 72

def presenter
  Pvectl::Presenters::Node.new
end

#valid_node_name?(name) ⇒ Boolean

Validates node name format.

Proxmox node names are alphanumeric, can contain hyphens, must start with alphanumeric character, max 63 characters.



145
146
147
148
149
150
# File 'lib/pvectl/commands/get/handlers/nodes.rb', line 145

def valid_node_name?(name)
  return false if name.nil? || name.empty?

  # Proxmox node names: alphanumeric, can contain hyphens, max 63 chars
  name.match?(/\A[a-zA-Z0-9][-a-zA-Z0-9]{0,62}\z/)
end