proxmox-sdk 0.1.1 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 18becda6b3edf4aba2a1146a3f889e618c9c49ad9d476f45197b63bae0930f5e
4
- data.tar.gz: bc2b3f12e06eb9ef9941acf1035a81bdad3be29627fbdec33ee520e374ddb221
3
+ metadata.gz: f7c0b67d16c5998e774ca622ca64f157b586080e958323c97d10225595a3372f
4
+ data.tar.gz: c2ced47a6a4c274adf06a69b728b2c5c175b964696d7f2984927376502390c2c
5
5
  SHA512:
6
- metadata.gz: 4aa011f0cb9ea2ca0694a095e549a410f572cd96325d3cf4886bc1a9ba80536e8d4f64ea9005bdf9836368c2b8a5c823e8d28cc81da77601958a96cd27132865
7
- data.tar.gz: 3628b92158ebb7288bdd9f231e9db71eb180789df6e36fc7faa69d744b41bcde25535efc90bec9f0b48c1c959a5d9f0811a9aa54850a4a83ab75af6c4016ccb5
6
+ metadata.gz: d5157b2839030a07102344ff43188e6f4b54bcb2c631016bce6d373c45ebda9519447a4f80a6446bdf1e81d40e68b8c1129bd2208db19676221c566a4b846cec
7
+ data.tar.gz: fa53ebc0acac4c23b3cda3d6a4687bf8bbb67740ef32da50e4fd1e5c2626371daf5dab7aaf09b3000ce91416ad361ebf325d4b8a94644bfc80c524f861991cdc
data/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # Proxmox
2
2
 
3
+ [![Gem Version](https://badge.fury.io/rb/proxmox-sdk.svg)](https://badge.fury.io/rb/proxmox-sdk)
4
+
3
5
  A lightweight Ruby gem that provides a clean, idiomatic interface to the Proxmox VE REST API. It handles authentication, token management, and all common API endpoints (nodes, virtual machines, storage, containers, etc.) so you can focus on building automation, orchestration, or custom tooling without dealing with raw HTTP calls.
4
6
 
5
7
  ## Installation
@@ -1,27 +1,64 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "faraday"
4
+ require "json"
5
+ require "time"
4
6
 
5
7
  module Proxmox
6
8
  # Proxmox SDK Http Client
7
9
  class Client
10
+ # Konstanten für die Gültigkeit des Tokens
11
+ # Proxmox Tickets sind standardmäßig 2 Stunden (7200 Sekunden) gültig.
12
+ TOKEN_VALIDITY_SECONDS = 7200
13
+ # Wir erneuern den Token 5 Minuten (300 Sekunden) vor Ablauf.
14
+ RENEWAL_BUFFER_SECONDS = 300
15
+
8
16
  attr_reader :ticket, :csrf_token, :base_url
9
17
 
10
18
  def initialize(base_url:, username:, password:, realm: "pam", ignore_ssl: false)
11
19
  @base_url = base_url
12
20
  @verify_ssl = !ignore_ssl
13
- login(username, password, realm)
21
+
22
+ # Anmeldedaten für die automatische Erneuerung speichern
23
+ @username = username
24
+ @password = password
25
+ @realm = realm
26
+
27
+ # Initiales Login
28
+ login
14
29
  end
15
30
 
16
- def login(user, pass, realm)
31
+ def cluster
32
+ @cluster ||= Proxmox::Resources::Cluster.new(self)
33
+ end
34
+
35
+ def node(name)
36
+ Proxmox::Resources::Node.new(self, name)
37
+ end
38
+
39
+ def nodes
40
+ request(:get, "/nodes").map do |node_data|
41
+ Proxmox::Resources::Node.new(self, node_data)
42
+ end
43
+ end
44
+
45
+ def login
17
46
  resp = http.post("/api2/json/access/ticket",
18
- { username: "#{user}@#{realm}", password: pass })
47
+ { username: "#{@username}@#{@realm}", password: @password })
48
+
49
+ raise "Login failed: #{resp.body}" unless resp.success?
50
+
19
51
  data = JSON.parse(resp.body)["data"]
20
- @ticket = data["ticket"]
52
+ @ticket = data["ticket"]
21
53
  @csrf_token = data["CSRFPreventionToken"]
54
+ # Zeitstempel der Ticketerstellung speichern
55
+ @ticket_creation_time = Time.now
22
56
  end
23
57
 
24
58
  def request(method, path, params = {}, body = nil)
59
+ # Vor jeder Anfrage die Gültigkeit des Tokens prüfen und ggf. erneuern
60
+ ensure_token_validity
61
+
25
62
  response = perform_http_call(method, path, params, body)
26
63
 
27
64
  ensure_success!(response)
@@ -30,6 +67,23 @@ module Proxmox
30
67
 
31
68
  private
32
69
 
70
+ # NEUE METHODE: Stellt sicher, dass der Token gültig ist
71
+ def ensure_token_validity
72
+ login if token_expired?
73
+ end
74
+
75
+ # NEUE METHODE: Prüft, ob der Token abgelaufen ist oder bald abläuft
76
+ def token_expired?
77
+ # Wenn noch kein Ticket erstellt wurde, nicht als abgelaufen betrachten
78
+ return false if @ticket_creation_time.nil?
79
+
80
+ # Berechne die Ablaufzeit (Erstellungszeit + Gültigkeit - Puffer)
81
+ renewal_time = @ticket_creation_time + TOKEN_VALIDITY_SECONDS - RENEWAL_BUFFER_SECONDS
82
+
83
+ # Ist die aktuelle Zeit nach der errechneten Erneuerungszeit?
84
+ Time.now > renewal_time
85
+ end
86
+
33
87
  def perform_http_call(method, path, params, body)
34
88
  http.send(method) do |req|
35
89
  set_url(req, path)
@@ -59,14 +113,22 @@ module Proxmox
59
113
  end
60
114
 
61
115
  def set_body(req, body)
62
- req.body = body.to_json if body
116
+ req.body = body if body
63
117
  end
64
118
 
65
119
  def ensure_success!(response)
66
- raise ApiError, response.body unless response.success?
120
+ # Optional: Wenn ein 401 (Unauthorized) Fehler kommt, könnte man hier auch ein erneutes Login erzwingen.
121
+ # if response.status == 401
122
+ # login
123
+ # # Hier könnte man die Anfrage wiederholen.
124
+ # end
125
+ raise "ApiError: #{response.body}" unless response.success?
67
126
  end
68
127
 
69
128
  def extract_data(response)
129
+ # Sicherstellen, dass der Body nicht leer ist, bevor geparst wird
130
+ return nil if response.body.nil? || response.body.empty?
131
+
70
132
  JSON.parse(response.body)["data"]
71
133
  end
72
134
 
@@ -77,4 +139,7 @@ module Proxmox
77
139
  end
78
140
  end
79
141
  end
142
+
143
+ # Eigene Fehlerklasse (optional, aber guter Stil)
144
+ class ApiError < StandardError; end
80
145
  end
@@ -8,6 +8,10 @@ module Proxmox
8
8
  @client = client
9
9
  end
10
10
 
11
+ def inspect
12
+ "#<Proxmox::Resources::Cluster client_url=#{@client.base_url}>"
13
+ end
14
+
11
15
  def log(max: nil)
12
16
  params = {}
13
17
  params[:max] = max unless max.nil?
@@ -38,9 +42,8 @@ module Proxmox
38
42
  @client.request(:get, "/cluster/tasks")
39
43
  end
40
44
 
41
- # Getting all Nodes
42
45
  def nodes
43
- @client.request(:get, "/nodes")
46
+ @client.nodes
44
47
  end
45
48
  end
46
49
  end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Proxmox
4
+ module Resources
5
+ module Clusters
6
+ # Proxmox Cluster Acme class
7
+ class Backup
8
+ def initialize(client)
9
+ @client = client
10
+ end
11
+
12
+ def all
13
+ @client.request(:get, "/cluster/backup")
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -4,9 +4,37 @@ module Proxmox
4
4
  module Resources
5
5
  # Proxmox Node Class
6
6
  class Node
7
- def initialize(client, node_name)
7
+ # Define the attributes we expect from the API
8
+ STATS_ATTRIBUTES = %i[id cpu maxcpu mem maxmem uptime].freeze
9
+ attr_reader :node, *STATS_ATTRIBUTES
10
+ alias name node
11
+
12
+ def initialize(client, name_or_data)
8
13
  @client = client
9
- @node = node_name
14
+ if name_or_data.is_a?(Hash)
15
+ @node = name_or_data["node"]
16
+ @raw_status = name_or_data["status"]
17
+
18
+ # Dynamically set known attributes to avoid boilerplate
19
+ STATS_ATTRIBUTES.each do |attr|
20
+ instance_variable_set("@#{attr}", name_or_data[attr.to_s])
21
+ end
22
+ else
23
+ @node = name_or_data
24
+ end
25
+ end
26
+
27
+ def inspect
28
+ "#<Proxmox::Resources::Node name=#{@node} status=#{@raw_status}>"
29
+ end
30
+
31
+ def online?
32
+ @raw_status == "online"
33
+ end
34
+
35
+ # Access the Cluster resource
36
+ def cluster
37
+ @client.cluster
10
38
  end
11
39
 
12
40
  # Getting status of the Node
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Proxmox
4
- VERSION = "0.1.1"
4
+ VERSION = "0.1.4"
5
5
  end
data/lib/proxmox.rb CHANGED
@@ -4,6 +4,7 @@ require "proxmox/version"
4
4
  require "proxmox/client"
5
5
  require "proxmox/resources/cluster"
6
6
  require "proxmox/resources/clusters/acme"
7
+ require "proxmox/resources/clusters/backup"
7
8
  require "proxmox/resources/node"
8
9
 
9
10
  module Proxmox
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: proxmox-sdk
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alex Wellnitz
@@ -38,6 +38,7 @@ files:
38
38
  - lib/proxmox/client.rb
39
39
  - lib/proxmox/resources/cluster.rb
40
40
  - lib/proxmox/resources/clusters/acme.rb
41
+ - lib/proxmox/resources/clusters/backup.rb
41
42
  - lib/proxmox/resources/node.rb
42
43
  - lib/proxmox/version.rb
43
44
  - sig/proxmox.rbs
@@ -63,7 +64,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
63
64
  - !ruby/object:Gem::Version
64
65
  version: '0'
65
66
  requirements: []
66
- rubygems_version: 3.6.9
67
+ rubygems_version: 4.0.10
67
68
  specification_version: 4
68
69
  summary: A gem that provides a client interface for Proxmox
69
70
  test_files: []