feat(agent): pvesh storage collector
This commit is contained in:
parent
8c3e953e4e
commit
ec7f08dfda
3 changed files with 108 additions and 0 deletions
37
agent/lib/proxmox_agent/collectors/storage.ex
Normal file
37
agent/lib/proxmox_agent/collectors/storage.ex
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
defmodule ProxmoxAgent.Collectors.Storage do
|
||||||
|
@moduledoc "Collects Proxmox storage summary via pvesh."
|
||||||
|
|
||||||
|
@spec collect(keyword()) :: %{storages: [map()], errors: [map()]}
|
||||||
|
def collect(opts \\ []) do
|
||||||
|
runner = Keyword.get(opts, :runner, &ProxmoxAgent.Shell.run/2)
|
||||||
|
node = Keyword.fetch!(opts, :node)
|
||||||
|
|
||||||
|
case runner.("pvesh", ["get", "/nodes/#{node}/storage", "--output-format", "json"]) do
|
||||||
|
{:ok, body} ->
|
||||||
|
case Jason.decode(body) do
|
||||||
|
{:ok, list} when is_list(list) ->
|
||||||
|
%{storages: Enum.map(list, &normalize/1), errors: []}
|
||||||
|
|
||||||
|
{:error, e} ->
|
||||||
|
%{storages: [], errors: [%{tag: "decode", message: Exception.message(e)}]}
|
||||||
|
end
|
||||||
|
|
||||||
|
{:error, reason} ->
|
||||||
|
%{storages: [], errors: [%{tag: "pvesh", message: inspect(reason)}]}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp normalize(entry) do
|
||||||
|
%{
|
||||||
|
name: entry["storage"],
|
||||||
|
type: entry["type"],
|
||||||
|
content: entry["content"],
|
||||||
|
active: entry["active"] == 1,
|
||||||
|
enabled: entry["enabled"] == 1,
|
||||||
|
used_bytes: entry["used"] || 0,
|
||||||
|
total_bytes: entry["total"] || 0,
|
||||||
|
avail_bytes: entry["avail"] || 0,
|
||||||
|
used_fraction: entry["used_fraction"] || 0.0
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
35
agent/test/fixtures/pvesh/storage.json
vendored
Normal file
35
agent/test/fixtures/pvesh/storage.json
vendored
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"storage": "local",
|
||||||
|
"type": "dir",
|
||||||
|
"content": "backup,iso,vztmpl",
|
||||||
|
"active": 1,
|
||||||
|
"enabled": 1,
|
||||||
|
"used": 50000000000,
|
||||||
|
"total": 500000000000,
|
||||||
|
"avail": 450000000000,
|
||||||
|
"used_fraction": 0.1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"storage": "local-zfs",
|
||||||
|
"type": "zfspool",
|
||||||
|
"content": "images,rootdir",
|
||||||
|
"active": 1,
|
||||||
|
"enabled": 1,
|
||||||
|
"used": 200000000000,
|
||||||
|
"total": 500000000000,
|
||||||
|
"avail": 300000000000,
|
||||||
|
"used_fraction": 0.4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"storage": "backup-nfs",
|
||||||
|
"type": "nfs",
|
||||||
|
"content": "backup",
|
||||||
|
"active": 0,
|
||||||
|
"enabled": 1,
|
||||||
|
"used": 0,
|
||||||
|
"total": 0,
|
||||||
|
"avail": 0,
|
||||||
|
"used_fraction": 0.0
|
||||||
|
}
|
||||||
|
]
|
||||||
36
agent/test/proxmox_agent/collectors/storage_test.exs
Normal file
36
agent/test/proxmox_agent/collectors/storage_test.exs
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
defmodule ProxmoxAgent.Collectors.StorageTest do
|
||||||
|
use ExUnit.Case, async: true
|
||||||
|
|
||||||
|
alias ProxmoxAgent.Collectors.Storage
|
||||||
|
|
||||||
|
@fixtures Path.expand("../../fixtures/pvesh", __DIR__)
|
||||||
|
|
||||||
|
defp fake_runner do
|
||||||
|
fn
|
||||||
|
"pvesh", ["get", "/nodes/" <> _, "--output-format", "json"] ->
|
||||||
|
{:ok, File.read!(Path.join(@fixtures, "storage.json"))}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
test "returns one summary per storage entry" do
|
||||||
|
sample = Storage.collect(node: "pve-01", runner: fake_runner())
|
||||||
|
|
||||||
|
assert length(sample.storages) == 3
|
||||||
|
local = Enum.find(sample.storages, &(&1.name == "local"))
|
||||||
|
assert local.type == "dir"
|
||||||
|
assert local.active == true
|
||||||
|
assert local.used_bytes == 50_000_000_000
|
||||||
|
assert local.total_bytes == 500_000_000_000
|
||||||
|
assert local.content == "backup,iso,vztmpl"
|
||||||
|
|
||||||
|
nfs = Enum.find(sample.storages, &(&1.name == "backup-nfs"))
|
||||||
|
assert nfs.active == false
|
||||||
|
end
|
||||||
|
|
||||||
|
test "populates errors on failure" do
|
||||||
|
failing = fn _, _ -> {:error, {:enoent, "pvesh"}} end
|
||||||
|
sample = Storage.collect(node: "pve-01", runner: failing)
|
||||||
|
assert sample.storages == []
|
||||||
|
assert sample.errors != []
|
||||||
|
end
|
||||||
|
end
|
||||||
Loading…
Add table
Add a link
Reference in a new issue