Class: Kitchen::Driver::Proxmox::ApiClient

Inherits:
Object
  • Object
show all
Defined in:
lib/kitchen/driver/proxmox/api_client.rb

Overview

HTTP client for the Proxmox VE REST API. Authenticates via API tokens. Provides convenience methods for VM lifecycle operations.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(base_url:, token_id:, token_secret:, ssl_verify: true) ⇒ ApiClient

Returns a new instance of ApiClient.



19
20
21
22
23
24
# File 'lib/kitchen/driver/proxmox/api_client.rb', line 19

def initialize(base_url:, token_id:, token_secret:, ssl_verify: true)
  @base_url = base_url.chomp('/')
  @token_id = token_id
  @token_secret = token_secret
  @ssl_verify = ssl_verify
end

Instance Attribute Details

#base_urlObject (readonly)

Returns the value of attribute base_url.



17
18
19
# File 'lib/kitchen/driver/proxmox/api_client.rb', line 17

def base_url
  @base_url
end

#ssl_verifyObject (readonly)

Returns the value of attribute ssl_verify.



17
18
19
# File 'lib/kitchen/driver/proxmox/api_client.rb', line 17

def ssl_verify
  @ssl_verify
end

#token_idObject (readonly)

Returns the value of attribute token_id.



17
18
19
# File 'lib/kitchen/driver/proxmox/api_client.rb', line 17

def token_id
  @token_id
end

#token_secretObject (readonly)

Returns the value of attribute token_secret.



17
18
19
# File 'lib/kitchen/driver/proxmox/api_client.rb', line 17

def token_secret
  @token_secret
end

Instance Method Details

#agent_network_interfaces(node:, vm_id:) ⇒ Object



86
87
88
# File 'lib/kitchen/driver/proxmox/api_client.rb', line 86

def agent_network_interfaces(node:, vm_id:)
  get("/api2/json/nodes/#{node}/qemu/#{vm_id}/agent/network-get-interfaces")
end

#clone_vm(node:, template_id:, new_id:, **options) ⇒ Object



30
31
32
33
34
35
36
37
# File 'lib/kitchen/driver/proxmox/api_client.rb', line 30

def clone_vm(node:, template_id:, new_id:, **options)
  full = options.fetch(:full, true)
  body = { newid: new_id, full: full ? 1 : 0, target: node }
  body[:name] = options[:name] if options[:name]
  body[:pool] = options[:pool] if options[:pool]
  body[:storage] = options[:storage] if options[:storage]
  post("/api2/json/nodes/#{node}/qemu/#{template_id}/clone", body)
end

#configure_vm(node:, vm_id:, cpus: nil, memory: nil, network_bridge: nil) ⇒ Object



39
40
41
42
43
44
45
46
47
# File 'lib/kitchen/driver/proxmox/api_client.rb', line 39

def configure_vm(node:, vm_id:, cpus: nil, memory: nil, network_bridge: nil)
  body = {}
  body[:cores] = cpus if cpus
  body[:memory] = memory if memory
  body[:net0] = "virtio,bridge=#{network_bridge}" if network_bridge
  return nil if body.empty?

  put("/api2/json/nodes/#{node}/qemu/#{vm_id}/config", body)
end

#destroy_vm(node:, vm_id:, purge: true) ⇒ Object



57
58
59
60
# File 'lib/kitchen/driver/proxmox/api_client.rb', line 57

def destroy_vm(node:, vm_id:, purge: true)
  params = purge ? { purge: 1 } : {}
  delete("/api2/json/nodes/#{node}/qemu/#{vm_id}", params)
end

#list_nodesObject



90
91
92
# File 'lib/kitchen/driver/proxmox/api_client.rb', line 90

def list_nodes
  get('/api2/json/nodes')
end

#list_templatesObject



94
95
96
97
# File 'lib/kitchen/driver/proxmox/api_client.rb', line 94

def list_templates
  resources = get('/api2/json/cluster/resources?type=vm')
  resources.select { |r| r['template'] == 1 }
end

#next_vm_idObject



26
27
28
# File 'lib/kitchen/driver/proxmox/api_client.rb', line 26

def next_vm_id
  get('/api2/json/cluster/nextid')
end

#start_vm(node:, vm_id:) ⇒ Object



49
50
51
# File 'lib/kitchen/driver/proxmox/api_client.rb', line 49

def start_vm(node:, vm_id:)
  post("/api2/json/nodes/#{node}/qemu/#{vm_id}/status/start")
end

#stop_vm(node:, vm_id:) ⇒ Object



53
54
55
# File 'lib/kitchen/driver/proxmox/api_client.rb', line 53

def stop_vm(node:, vm_id:)
  post("/api2/json/nodes/#{node}/qemu/#{vm_id}/status/stop")
end

#task_status(node:, upid:) ⇒ Object



70
71
72
73
# File 'lib/kitchen/driver/proxmox/api_client.rb', line 70

def task_status(node:, upid:)
  encoded = URI.encode_www_form_component(upid)
  get("/api2/json/nodes/#{node}/tasks/#{encoded}/status")
end

#vm_config(node:, vm_id:) ⇒ Object



66
67
68
# File 'lib/kitchen/driver/proxmox/api_client.rb', line 66

def vm_config(node:, vm_id:)
  get("/api2/json/nodes/#{node}/qemu/#{vm_id}/config")
end

#vm_status(node:, vm_id:) ⇒ Object



62
63
64
# File 'lib/kitchen/driver/proxmox/api_client.rb', line 62

def vm_status(node:, vm_id:)
  get("/api2/json/nodes/#{node}/qemu/#{vm_id}/status/current")
end

#wait_for_task(node:, upid:, timeout: 300, interval: 2) ⇒ Object



75
76
77
78
79
80
81
82
83
84
# File 'lib/kitchen/driver/proxmox/api_client.rb', line 75

def wait_for_task(node:, upid:, timeout: 300, interval: 2)
  deadline = Time.now + timeout
  loop do
    status = task_status(node:, upid:)
    return status if status['status'] == 'stopped'
    raise "Task timeout after #{timeout}s: #{upid}" if Time.now > deadline

    sleep interval
  end
end