feat: version agent remontée au serveur et affichée dans la popup

- payload.rs : champ version (env!("CARGO_PKG_VERSION"))
- models.go  : Version dans AgentMetrics et Agent
- db.go      : colonne version dans agents + migration ALTER TABLE
- popups.js  : badge version dans la section INFORMATIONS

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Gilles Soulier
2026-05-22 20:27:26 +02:00
parent 243c97d71b
commit 0df716b8b0
5 changed files with 21 additions and 9 deletions
+1
View File
@@ -68,6 +68,7 @@ fn main() {
hostname: hostname.clone(),
ip: ip.clone(),
status: "online".to_string(),
version: env!("CARGO_PKG_VERSION").to_string(),
..Default::default()
};
+1
View File
@@ -5,6 +5,7 @@ pub struct AgentMetrics {
pub hostname: String,
pub ip: String,
pub status: String,
pub version: String,
pub cpu_percent: Option<f32>,
pub memory_used: Option<u64>,
pub memory_free: Option<u64>,
+3
View File
@@ -119,6 +119,9 @@ const Popups = (() => {
<div class="meta-grid">
<div class="meta"><div class="meta-lbl">HOSTNAME</div><div class="meta-val">${esc(agent.hostname)}</div></div>
<div class="meta"><div class="meta-lbl">ADRESSE IP</div><div class="meta-val">${esc(agent.ip) || '—'}</div></div>
<div class="meta"><div class="meta-lbl">VERSION AGENT</div><div class="meta-val" style="display:flex;align-items:center;gap:6px">
${agent.version ? `<span style="font-family:var(--font-mono);background:var(--bg-1);border:1px solid var(--border-2);border-radius:5px;padding:1px 7px;font-size:11px;color:var(--accent)">v${esc(agent.version)}</span>` : '<span style="color:var(--ink-4)">—</span>'}
</div></div>
<div class="meta"><div class="meta-lbl">PROTOCOLES ACTIFS</div><div style="display:flex;gap:5px;margin-top:4px">${protos || '—'}</div></div>
<div class="meta"><div class="meta-lbl">DERNIER CONTACT</div><div class="meta-val">${new Date(agent.last_seen * 1000).toLocaleTimeString('fr-FR')}</div></div>
</div>
+13 -8
View File
@@ -20,7 +20,7 @@ const schema = `
CREATE TABLE IF NOT EXISTS agents (
id TEXT PRIMARY KEY, hostname TEXT NOT NULL,
ip TEXT NOT NULL DEFAULT '', status TEXT NOT NULL DEFAULT 'offline',
last_seen INTEGER NOT NULL DEFAULT 0
last_seen INTEGER NOT NULL DEFAULT 0, version TEXT NOT NULL DEFAULT ''
);
CREATE TABLE IF NOT EXISTS metrics (
id INTEGER PRIMARY KEY AUTOINCREMENT, agent_id TEXT NOT NULL, ts INTEGER NOT NULL,
@@ -57,8 +57,12 @@ func Open(path string) (*DB, error) {
}
func (d *DB) migrate() error {
_, err := d.conn.Exec(schema)
if _, err := d.conn.Exec(schema); err != nil {
return err
}
// Migrations additives pour les colonnes ajoutées après la création initiale
_, _ = d.conn.Exec(`ALTER TABLE agents ADD COLUMN version TEXT NOT NULL DEFAULT ''`)
return nil
}
func (d *DB) Close() { _ = d.conn.Close() }
@@ -66,11 +70,12 @@ func (d *DB) Close() { _ = d.conn.Close() }
func (d *DB) UpsertAgent(m *models.AgentMetrics) error {
ts := time.Now().Unix()
_, err := d.conn.Exec(`
INSERT INTO agents (id, hostname, ip, status, last_seen)
VALUES (?, ?, ?, ?, ?)
INSERT INTO agents (id, hostname, ip, status, last_seen, version)
VALUES (?, ?, ?, ?, ?, ?)
ON CONFLICT(id) DO UPDATE SET
ip=excluded.ip, status=excluded.status, last_seen=excluded.last_seen`,
m.Hostname, m.Hostname, m.IP, m.Status, ts)
ip=excluded.ip, status=excluded.status, last_seen=excluded.last_seen,
version=CASE WHEN excluded.version != '' THEN excluded.version ELSE version END`,
m.Hostname, m.Hostname, m.IP, m.Status, ts, m.Version)
return err
}
@@ -104,7 +109,7 @@ func (d *DB) InsertMetrics(m *models.AgentMetrics) error {
}
func (d *DB) GetAgents() ([]models.Agent, error) {
rows, err := d.conn.Query(`SELECT id, hostname, ip, status, last_seen FROM agents`)
rows, err := d.conn.Query(`SELECT id, hostname, ip, status, last_seen, version FROM agents`)
if err != nil {
return nil, err
}
@@ -112,7 +117,7 @@ func (d *DB) GetAgents() ([]models.Agent, error) {
var agents []models.Agent
for rows.Next() {
var a models.Agent
if err := rows.Scan(&a.ID, &a.Hostname, &a.IP, &a.Status, &a.LastSeen); err != nil {
if err := rows.Scan(&a.ID, &a.Hostname, &a.IP, &a.Status, &a.LastSeen, &a.Version); err != nil {
return nil, err
}
agents = append(agents, a)
+2
View File
@@ -4,6 +4,7 @@ type AgentMetrics struct {
Hostname string `json:"hostname"`
IP string `json:"ip"`
Status string `json:"status"`
Version string `json:"version"`
CPUPercent *float64 `json:"cpu_percent"`
MemoryUsed *int64 `json:"memory_used"`
MemoryFree *int64 `json:"memory_free"`
@@ -32,6 +33,7 @@ type Agent struct {
IP string `json:"ip"`
Status string `json:"status"`
LastSeen int64 `json:"last_seen"`
Version string `json:"version,omitempty"`
LastMetrics *AgentMetrics `json:"last_metrics,omitempty"`
}