Cisco APs OK

This commit is contained in:
Douglas Barone 2022-03-24 12:31:56 -04:00
parent 3ee2504c24
commit 8172769249
7 changed files with 224 additions and 38 deletions

View File

@ -0,0 +1,58 @@
-- DropForeignKey
ALTER TABLE "PAHost" DROP CONSTRAINT "PAHost_ownerId_fkey";
-- DropForeignKey
ALTER TABLE "ResetToken" DROP CONSTRAINT "ResetToken_creatorId_fkey";
-- DropForeignKey
ALTER TABLE "ResetToken" DROP CONSTRAINT "ResetToken_userId_fkey";
-- AlterTable
ALTER TABLE "WifiDevice" ADD COLUMN "accessPointId" INTEGER;
-- CreateTable
CREATE TABLE "AccessPoint" (
"id" SERIAL NOT NULL,
"mac" TEXT NOT NULL,
"hostname" TEXT NOT NULL,
"name" TEXT,
"local" TEXT,
"notes" TEXT,
"uptime" TEXT,
"controller" TEXT,
"model" TEXT,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "AccessPoint_pkey" PRIMARY KEY ("id")
);
-- CreateIndex
CREATE UNIQUE INDEX "AccessPoint_mac_key" ON "AccessPoint"("mac");
-- CreateIndex
CREATE UNIQUE INDEX "AccessPoint_hostname_key" ON "AccessPoint"("hostname");
-- AddForeignKey
ALTER TABLE "ResetToken" ADD CONSTRAINT "ResetToken_creatorId_fkey" FOREIGN KEY ("creatorId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "ResetToken" ADD CONSTRAINT "ResetToken_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "WifiDevice" ADD CONSTRAINT "WifiDevice_accessPointId_fkey" FOREIGN KEY ("accessPointId") REFERENCES "AccessPoint"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "PAHost" ADD CONSTRAINT "PAHost_ownerId_fkey" FOREIGN KEY ("ownerId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- RenameIndex
ALTER INDEX "PAHost.cidr_unique" RENAME TO "PAHost_cidr_key";
-- RenameIndex
ALTER INDEX "ResetToken.token_unique" RENAME TO "ResetToken_token_key";
-- RenameIndex
ALTER INDEX "User.sAMAccountName_unique" RENAME TO "User_sAMAccountName_key";
-- RenameIndex
ALTER INDEX "WifiDevice.mac_unique" RENAME TO "WifiDevice_mac_key";

View File

@ -0,0 +1,3 @@
# Please do not edit this file manually
# It should be added in your version-control system (i.e. Git)
provider = "postgresql"

View File

@ -73,22 +73,24 @@ model User {
}
model WifiDevice {
id Int @id @default(autoincrement())
oui String?
mac String @unique
hostname String?
firstSeen DateTime? @default(now())
lastSeen DateTime?
essid String?
ip String?
uptime String?
apName String?
status Status?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
userId Int?
controller String @default("unknown")
user User? @relation("wifidevice_to_user", fields: [userId], references: [id])
id Int @id @default(autoincrement())
oui String?
mac String @unique
hostname String?
firstSeen DateTime? @default(now())
lastSeen DateTime?
essid String?
ip String?
uptime String?
apName String?
accessPointId Int?
accessPoint AccessPoint? @relation("wifidevice_to_ap", fields: [accessPointId], references: [id])
status Status?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
userId Int?
controller String @default("unknown")
user User? @relation("wifidevice_to_user", fields: [userId], references: [id])
}
enum Status {
@ -137,3 +139,20 @@ model PAHost {
ownerId Int
owner User @relation("pahost_to_user", fields: [ownerId], references: [id])
}
model AccessPoint {
id Int @id @default(autoincrement())
mac String @unique
hostname String @unique
name String?
local String?
notes String?
uptime String?
controller String?
model String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
WifiDevices WifiDevice[] @relation("wifidevice_to_ap")
}

View File

@ -0,0 +1,23 @@
import prisma from '../prisma'
import { getAccessPoints as getCiscoAccessPoints } from './ciscoController'
async function getAccessPoints() {
const ciscoAccessPoints = await getCiscoAccessPoints()
return ciscoAccessPoints
}
async function updateDB(accessPoints) {
for (const accessPoint of accessPoints) {
await prisma.accessPoint.upsert({
where: { mac: accessPoint.mac },
create: accessPoint,
update: accessPoint
})
}
}
export async function updateAccessPoints() {
const accessPoints = await getAccessPoints()
await updateDB(accessPoints)
}

View File

@ -6,25 +6,25 @@ import { logError } from './logger'
const TIMEOUT_IN_MS = 120000
const REQUEST_TIMEOUT_IN_MS = 20000
const getUri = (skip, page, take) =>
const getDevicesUri = (skip, page, take) =>
`https://${process.env.CISCO_HOST}/data/client-table.html?columns=524287&take=${take}&skip=${skip}&page=${page}&pageSize=50&sort[0][field]=ST&sort[0][dir]=desc`
const httpsAgent = new https.Agent({
rejectUnauthorized: false,
ciphers: 'AES256-SHA' // That's necessary to connect to a TLS 1.0 server. Run node with --tls-min-v1.0
})
const ciscoAxios = create({
httpsAgent: httpsAgent,
timeout: REQUEST_TIMEOUT_IN_MS,
auth: {
username: process.env.CISCO_USER,
password: process.env.CISCO_PASSWORD
}
})
function getDevices() {
return new Promise(async (resolve, reject) => {
const httpsAgent = new https.Agent({
rejectUnauthorized: false,
ciphers: 'AES256-SHA' // That's necessary to connect to a TLS 1.0 server. Run node with --tls-min-v1.0
})
const axios = create({
httpsAgent: httpsAgent,
timeout: REQUEST_TIMEOUT_IN_MS,
auth: {
username: process.env.CISCO_USER,
password: process.env.CISCO_PASSWORD
}
})
const source = CancelToken.source()
const timeout = setTimeout(() => {
@ -43,9 +43,12 @@ function getDevices() {
const responsesPromises = []
try {
const firstResponse = await axios.get(getUri(skip, page, take), {
cancelToken: source.token
})
const firstResponse = await ciscoAxios.get(
getDevicesUri(skip, page, take),
{
cancelToken: source.token
}
)
const { total, data: page1devices } = firstResponse.data
@ -54,7 +57,7 @@ function getDevices() {
while (total > skip) {
responsesPromises.push(
axios.get(getUri(skip, page, take), {
ciscoAxios.get(getDevicesUri(skip, page, take), {
cancelToken: source.token
})
)
@ -90,7 +93,7 @@ export async function getOnlineWifiDevices() {
const now = new Date()
const hydratedOnlineDevices = onlineDevices.map(client => ({
const restructuredOnlineDevices = onlineDevices.map(client => ({
user: client.Name == 'unknown' ? null : client.Name,
oui: ouiFinder(client.macaddr),
mac: client.macaddr,
@ -105,5 +108,49 @@ export async function getOnlineWifiDevices() {
controller: 'Cisco'
}))
return hydratedOnlineDevices
return restructuredOnlineDevices
}
export async function getAccessPoints() {
const source = CancelToken.source()
const timeout = setTimeout(() => {
source.cancel('timeout')
reject(
new Error(
'A operação getDevices foi cancelada pois atingiu o tempo limite'
)
)
}, TIMEOUT_IN_MS)
try {
const {
data: { Data: accessPoints }
} = await ciscoAxios.get(
`https://${process.env.CISCO_HOST}/data/ap-attributes-slot0.html?columns=28157`,
{
cancelToken: source.token
}
)
clearTimeout(timeout)
const restructuredAccessPoints = accessPoints.map(({ Nm, Mc, Md, Ut }) => ({
mac: Mc,
hostname: Nm,
uptime: Ut.toString(),
controller: 'Cisco',
model: Md
}))
return restructuredAccessPoints
} catch (e) {
logError({
tags: ['cisco', 'accessPoints'],
message: e.message,
data: { ...e, config: { ...e.config, auth: '*****' } }
})
throw e
}
}

View File

@ -4,7 +4,10 @@ import { ResetToken } from '../../classes/ResetToken'
import { updateDevicesInfo } from '../../lib/wifiDevices'
import { updateUserIdMappings, addHost } from '../../lib/paloalto'
import { logInfo, logSuccess } from '../../lib/logger'
import { logInfo, logSuccess, logError } from '../../lib/logger'
import { updateAccessPoints } from '../../lib/accessPoints'
import prisma from '../../prisma'
const Mutation = {
@ -82,6 +85,19 @@ const Mutation = {
throw new Error('Você não pode apagar o host de outro usuário')
return prisma.pAHost.delete({ where: { id } })
},
async updateAccessPoints() {
try {
await updateAccessPoints()
return 'Atualização concluída'
} catch (e) {
logError({
tags: ['accessPoints'],
message: `Erro tentando atualizar os pontos de acesso: ${e.message}`,
data: { error: e }
})
}
}
}

View File

@ -51,7 +51,11 @@ const typeDefs = gql`
limit: Int = 200
): [Log]! @auth(roles: ["superAdmin"])
"All PA hosts"
pAHosts: [PAHost!]! @auth(roles: ["superAdmin"])
"All Access Points"
accessPoints: [AccessPoint!]! @auth(roles: ["superAdmin"])
}
type Mutation {
@ -89,6 +93,9 @@ const typeDefs = gql`
"Remove a PA host"
delPAHost(id: Int!): PAHost! @auth(roles: ["superAdmin"])
"Update Access Points"
updateAccessPoints: String! @auth(roles: ["superAdmin"])
}
type Subscription {
@ -279,6 +286,19 @@ const typeDefs = gql`
updatedAt: String
}
"A Wireless Access Point"
type AccessPoint {
id: ID!
mac: String!
hostname: String
name: String
local: String
notes: String
createdAt: String
updatedAt: String
WifiDevices: [WifiDevice]
}
input LoginInput {
username: String!
password: String!