genieacs: fix with diagnosticos
Signed-off-by: Rodrigo Bertoldo de Sousa Martins <rodrigo.sousa.577@gmail.com>
This commit is contained in:
1 parent
63591000f0
commit
b6e898c885
3 files changed
+102
-2
No files matched your search
@@ -1070,6 +1070,20 @@ Digite /help para ver todos os comandos disponíveis!
|
||||
: Promise.resolve({ success: false, skipped: true })
|
||||
]);
|
||||
|
||||
// Sincronização TAG GenieACS ↔ PPPoE TopSapp (fire-and-forget, silencioso)
|
||||
// Garante que o login PPPoE do cliente fica registrado como TAG no GenieACS,
|
||||
// permitindo buscas futuras por "ver roteador <login>".
|
||||
if (serial && pppoeLogin && this.genieacs.isReady()) {
|
||||
this.genieacs.sincronizarTagPPPoE(serial, pppoeLogin)
|
||||
.then(r => {
|
||||
if (r.success && !r.already) {
|
||||
logger.info(`[GenieACS] TAG "${r.tag}" sincronizada em ${r.deviceId}`);
|
||||
console.log(`🏷️ [GenieACS] TAG "${r.tag}" adicionada ao device ${r.deviceId}`);
|
||||
}
|
||||
})
|
||||
.catch(e => logger.warn(`[GenieACS] Falha ao sincronizar TAG: ${e.message}`));
|
||||
}
|
||||
|
||||
// Montar relatório
|
||||
let msg = `🩺 *Diagnóstico do Cliente*\n`;
|
||||
msg += `━━━━━━━━━━━━━━━━━━━━━\n\n`;
|
||||
|
||||
@@ -158,6 +158,34 @@ class GenieACSApi {
|
||||
return this._buscar({ [`Tags.${tag.toLowerCase()}`]: true }, instance, 'tag');
|
||||
}
|
||||
|
||||
/**
|
||||
* Adiciona uma TAG a um dispositivo na NBI do GenieACS.
|
||||
* Endpoint: POST /devices/{id}/tags/{tag}
|
||||
*
|
||||
* @param {string} deviceId - _id do dispositivo (ex.: "00E0FC-Huawei-VMXQU22716608217")
|
||||
* @param {string} tag - Tag a adicionar (ex.: "clickcolmeia2025")
|
||||
* @param {Object} instance - Instância de GenieACSConfig
|
||||
* @returns {Promise<Object>} - { success, error }
|
||||
*/
|
||||
async adicionarTag(deviceId, tag, instance) {
|
||||
const client = this._buildClient(instance);
|
||||
const encodedId = encodeURIComponent(deviceId);
|
||||
const encodedTag = encodeURIComponent(tag);
|
||||
|
||||
try {
|
||||
await client.post(`/devices/${encodedId}/tags/${encodedTag}`);
|
||||
logger.info(`[GenieACS] TAG "${tag}" adicionada ao device ${deviceId}`);
|
||||
return { success: true };
|
||||
} catch (error) {
|
||||
const status = error.response?.status;
|
||||
const msg = status
|
||||
? `Erro HTTP ${status} ao adicionar TAG "${tag}" (${instance.name})`
|
||||
: `Falha ao adicionar TAG: ${error.message}`;
|
||||
logger.error(`[GenieACS] ${msg}`);
|
||||
return { success: false, error: msg };
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extrai os campos relevantes de um dispositivo bruto retornado pela NBI.
|
||||
* @param {Object} raw - Objeto bruto do GenieACS
|
||||
|
||||
+60
-2
@@ -20,6 +20,7 @@ class GenieACSManager {
|
||||
/**
|
||||
* Busca informações de um roteador/CPE pelo serial number ou pela TAG (username TopSapp).
|
||||
* Tenta por serial primeiro; se não encontrar, tenta por TAG.
|
||||
* Se o termo contém "@", também tenta a parte antes do @ como TAG.
|
||||
*
|
||||
* @param {string} termo - Serial ou TAG do dispositivo
|
||||
* @param {string} location - Texto de localização (opcional)
|
||||
@@ -36,20 +37,31 @@ class GenieACSManager {
|
||||
const instance = this.config.getInstanceByLocation(location);
|
||||
const termoLimpo = termo.trim();
|
||||
|
||||
// 1ª tentativa: busca por serial
|
||||
// 1ª tentativa: busca por serial (exato e uppercase)
|
||||
logger.info(`[GenieACS] Tentando como serial: "${termoLimpo}"`);
|
||||
const porSerial = await this.api.buscarDispositivo(termoLimpo, instance);
|
||||
if (porSerial.success) {
|
||||
return { ...porSerial, instance: instance.name };
|
||||
}
|
||||
|
||||
// 2ª tentativa: busca por TAG (usuario/login TopSapp)
|
||||
// 2ª tentativa: busca por TAG (termo completo)
|
||||
logger.info(`[GenieACS] Não encontrado como serial. Tentando como TAG: "${termoLimpo}"`);
|
||||
const porTag = await this.api.buscarPorTag(termoLimpo, instance);
|
||||
if (porTag.success) {
|
||||
return { ...porTag, instance: instance.name };
|
||||
}
|
||||
|
||||
// 3ª tentativa: se o termo tem "@", tentar só a parte antes do @ como TAG
|
||||
// (ex.: "clickcolmeia2025@isp" -> tenta "clickcolmeia2025")
|
||||
if (termoLimpo.includes('@')) {
|
||||
const tagBase = termoLimpo.split('@')[0].toLowerCase();
|
||||
logger.info(`[GenieACS] Tentando TAG sem domínio: "${tagBase}"`);
|
||||
const porTagBase = await this.api.buscarPorTag(tagBase, instance);
|
||||
if (porTagBase.success) {
|
||||
return { ...porTagBase, instance: instance.name };
|
||||
}
|
||||
}
|
||||
|
||||
// Nenhum resultado
|
||||
const errConexao = porSerial.error || porTag.error;
|
||||
return {
|
||||
@@ -57,6 +69,52 @@ class GenieACSManager {
|
||||
error: errConexao || `Nenhum dispositivo encontrado com serial ou TAG "${termoLimpo}"`
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Sincroniza o login PPPoE do TopSapp como TAG no GenieACS.
|
||||
*
|
||||
* Fluxo:
|
||||
* 1. Busca o dispositivo pelo serial (vindo do TopSapp)
|
||||
* 2. Deriva a TAG do login PPPoE (parte antes do "@", em minúsculo)
|
||||
* 3. Se a TAG ainda não existir no dispositivo, adiciona via NBI
|
||||
*
|
||||
* @param {string} serial - Serial do dispositivo (do cadastro TopSapp)
|
||||
* @param {string} pppoeLogin - Login PPPoE do cliente (ex.: "clickcolmeia2025" ou "user@isp")
|
||||
* @param {string} location - Texto de localização (opcional)
|
||||
* @returns {Promise<Object>} - { success, tag, deviceId, already, error }
|
||||
*/
|
||||
async sincronizarTagPPPoE(serial, pppoeLogin, location = '') {
|
||||
if (!this.isReady() || !serial || !pppoeLogin) {
|
||||
return { success: false, skipped: true };
|
||||
}
|
||||
|
||||
const instance = this.config.getInstanceByLocation(location);
|
||||
|
||||
// A TAG usa apenas a parte antes do "@", em minúsculo,
|
||||
// igualando ao padrão que o GenieACS já exibe na UI (ex.: "clickcolmeia2025")
|
||||
const tag = pppoeLogin.split('@')[0].toLowerCase();
|
||||
|
||||
// Localizar dispositivo pelo serial
|
||||
const result = await this.api.buscarDispositivo(serial.trim(), instance);
|
||||
if (!result.success || !result.device?.deviceId) {
|
||||
logger.warn(`[GenieACS] Sync TAG: dispositivo serial "${serial}" não encontrado`);
|
||||
return { success: false, error: 'Dispositivo não encontrado pelo serial' };
|
||||
}
|
||||
|
||||
const deviceId = result.device.deviceId;
|
||||
const tagsAtuais = result.device.tags || [];
|
||||
|
||||
// Verificar se a tag já está presente (case-insensitive)
|
||||
if (tagsAtuais.some(t => t.toLowerCase() === tag)) {
|
||||
logger.info(`[GenieACS] Sync TAG: "${tag}" já existe em ${deviceId}`);
|
||||
return { success: true, already: true, tag, deviceId };
|
||||
}
|
||||
|
||||
// Adicionar a TAG
|
||||
logger.info(`[GenieACS] Sync TAG: adicionando "${tag}" em ${deviceId}`);
|
||||
const addResult = await this.api.adicionarTag(deviceId, tag, instance);
|
||||
return { ...addResult, tag, deviceId };
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = GenieACSManager;
|
||||
Reference in new issue
Block a user