summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJannik Schönartz2021-03-23 20:15:24 +0100
committerJannik Schönartz2021-03-23 20:15:24 +0100
commit392e235d744c29b8852dea58b3db4aa19b1346a8 (patch)
treeddf8be32ce200b5a16e43e7d5172c565aff21633
parent[server/pci] Add gitignore & small bugfix (diff)
downloadbas-392e235d744c29b8852dea58b3db4aa19b1346a8.tar.gz
bas-392e235d744c29b8852dea58b3db4aa19b1346a8.tar.xz
bas-392e235d744c29b8852dea58b3db4aa19b1346a8.zip
[server/registration] Add support for the new hw collection python script (not fully finished)
-rw-r--r--server/api/registration.js220
1 files changed, 212 insertions, 8 deletions
diff --git a/server/api/registration.js b/server/api/registration.js
index fd10fba..b9d6f0b 100644
--- a/server/api/registration.js
+++ b/server/api/registration.js
@@ -12,6 +12,7 @@ const config = require(path.join(__appdir, 'config', 'config'))
const url = config.https.host // + ':' + config.https.port
const log = require(path.join(__appdir, 'lib', 'log'))
const HttpResponse = require(path.join(__appdir, 'lib', 'httpresponse'))
+// const pci = require(path.join(__appdir, 'lib', 'pci')) // This is needed for parsing vendor/product codes (not required for now)
// Permission check middleware
router.all(['', '/hooks', '/:y', '/hooks/:x'], async (req, res, next) => {
@@ -324,14 +325,21 @@ noAuthRouter.postAsync('/clients', async (req, res) => {
})
noAuthRouter.postAsync('/clients/:uuid', async (req, res) => {
- let client = req.body.client
- if (typeof client === 'string') client = JSON.parse(client)
-
- if (client && client.ram && client.ram.modules) {
- // Add the name to the ram modules.
- for (let ram of client.ram.modules) {
- ram.name = ram.formfactor
- if (client.ram.isEcc === 'Single-bit ECC') ram.name += '-ECC'
+ let client = {}
+ if (req.body.version && req.body.version >= 2) {
+ /* New hardware collection script */
+ client = parseHardwareInformation(req.body)
+ } else {
+ /* OLD SCRIPT */
+ client = req.body.client
+ if (typeof client === 'string') client = JSON.parse(client)
+
+ if (client && client.ram && client.ram.modules) {
+ // Add the name to the ram modules.
+ for (let ram of client.ram.modules) {
+ ram.name = ram.formfactor
+ if (client.ram.isEcc === 'Single-bit ECC') ram.name += '-ECC'
+ }
}
}
@@ -471,6 +479,202 @@ function getRecursiveParents (groupIds) {
}
/*
+ * New mehthod for preparing the new json formatted hw information
+ */
+function parseHardwareInformation (data) {
+ let result = {
+ 'client': {
+ 'parents': [], // TODO:
+ 'type': '', // SERVER OR CLIENT
+ 'uuid': '',
+ 'networks': [], // { 'mac': '', 'ip': '' }
+ 'system': {
+ 'model': '',
+ 'manufacturer': '',
+ 'serialnumber': ''
+ },
+ 'cpus': [],
+ 'ram': {
+ 'modules': [],
+ 'isEcc': false
+ },
+ 'drives': [],
+ 'gpus': []
+ }
+ }
+
+ // TODO: Rack and Bay stuff
+
+ /* DmiDecode: CPU, RAM, System Information (Serial, Model, ...) */
+ if (data.dmidecode && data.dmidecode.length > 0) {
+ const filter = [
+ /* "BIOS Information", "OEM Strings"," Base Board Information", "Chassis Information", "System Power Supply" */
+ 'System Information',
+ 'Processor Information',
+ 'Memory Device',
+ 'Physical Memory Array'
+ ]
+ const filteredData = data.dmidecode.filter(x => filter.includes(x.name))
+ for (let entry of filteredData) {
+ switch (entry.name) {
+ case 'System Information':
+ result.client.system.model = entry.props['Product Name'].values[0]
+ result.client.system.manufacturer = entry.props['Manufacturer'].values[0]
+ result.client.system.serialnumber = entry.props['Serial Number'].values[0]
+ result.client.uuid = entry.props['UUID'].values[0]
+ break
+
+ case 'Processor Information':
+ result.client.cpus.push({
+ 'model': entry.props['Version'].values[0],
+ 'manufacturer': entry.props['Manufacturer'].values[0],
+ 'type': entry.props['Family'].values[0],
+ 'cores': entry.props['Core Count'].values[0],
+ 'frequency': entry.props['Current Speed'].values[0].split(' ')[0],
+ 'unit': entry.props['Current Speed'].values[0].split(' ')[1]
+ })
+ break
+
+ case 'Memory Device':
+ if (entry.props['Size'].values[0] === 'No Module Installed') break
+ result.client.ram.modules.push({
+ 'capacity': entry.props['Size'].values[0].split(' ')[0],
+ 'unit': entry.props['Size'].values[0].split(' ')[1],
+ 'manufacturer': entry.props['Manufacturer'].values[0],
+ 'model': entry.props['Part Number'].values[0],
+ 'type': entry.props['Type'].values[0],
+ 'formfactor': entry.props['Form Factor'].values[0],
+ 'speed': entry.props['Speed'].values[0],
+ 'serialnumber': entry.props['Serial Number'].values[0]
+ })
+ break
+
+ case 'Physical Memory Array':
+ result.client.ram.isEcc = !!entry.props['Error Correction Type'].values[0].endsWith('ECC')
+ break
+ }
+ }
+ }
+
+ /* Smartctl */
+ for (let key in data.smartctl) {
+ let drive = {
+ 'model': '',
+ 'family': '', // NEW
+ 'firmware': '', // NEW maybe save in desc?
+ 'serial': '', // TODO: Update this to serialnumber to unify (also need to be changed in the idoit backend then)
+ 'capacity': '',
+ 'unit': '',
+ 'type': '',
+ 'formfactor': '',
+ 'connection': '', // CHECK?!
+ 'connection_speed': '' // NEW
+ }
+ let units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB']
+
+ /* Figure out if it's HDD, SSD or CD/DVD-ROM */
+ if (data.smartctl[key]['user_capacity']) {
+ let capacity = data.smartctl[key]['user_capacity']['bytes']
+ let unitcounter = 0
+ while (capacity > 1000) {
+ if (unitcounter + 1 <= units.length) {
+ capacity = capacity / 1000
+ unitcounter++
+ }
+ }
+ drive['capacity'] = Math.round(capacity)
+ drive['unit'] = units[unitcounter]
+
+ if (data.smartctl[key]['rotation_rate']) {
+ if (data.smartctl[key]['rotation_rate'] > 0) {
+ drive['type'] = 'HDD'
+ } else if (data.smartctl[key]['rotation_rate'] === 0) {
+ drive['type'] = 'SSD'
+ }
+ }
+ } else {
+ const regexCDDVD = /\/dev\/sr[0-9]+/
+ // Seems to be a CD/DVD-ROM
+ if (data.smartctl[key]['readlink'].match(regexCDDVD)) drive['type'] = 'CD/DVD-ROM'
+ else drive['type'] = 'UNKNOWN'
+ }
+
+ if (data.smartctl[key]['form_factor']) drive['formfactor'] = data.smartctl[key]['form_factor'].name
+ if (data.smartctl[key]['sata_version']) drive['connection'] = data.smartctl[key]['sata_version'].string
+ if (data.smartctl[key]['interface_speed']) {
+ if (data.smartctl[key]['interface_speed'].current) drive['connection_speed'] = data.smartctl[key]['interface_speed'].current.string
+ else if (data.smartctl[key]['interface_speed'].max) drive['connection_speed'] = data.smartctl[key]['interface_speed'].max.string
+ }
+
+ if (data.smartctl[key]['model_name']) drive.model = data.smartctl[key]['model_name']
+ if (data.smartctl[key]['model_family']) drive.family = data.smartctl[key]['model_family']
+ if (data.smartctl[key]['serial_number']) drive.serial = data.smartctl[key]['serial_number']
+ if (data.smartctl[key]['firmware_version']) drive.firmware = data.smartctl[key]['firmware_version']
+
+ result.client.drives.push(drive)
+ }
+
+ /* lspci */
+
+ /* ip */
+ for (let ip of data.ip) {
+ if (ip['link_type'] === 'loopback') continue
+ let network = {
+ 'name': ip.ifname,
+ 'mac': ip.address,
+ 'ip': '',
+ 'ipv6': '',
+ 'hostname': ''
+ }
+
+ for (let addr of ip['addr_info']) {
+ if (addr.scope !== 'global') continue
+ if (addr.family === 'inet') network.ip = addr.local
+ else if (addr.family === 'inet6') network.ipv6 = addr.local
+ }
+
+ result.client.networks.push(network)
+ }
+
+ /* net */
+ /* Get network information as fallback for ip */
+ if (result.client.networks.length <= 0) {
+ for (let key in data.net) {
+ let network = {
+ 'name': key,
+ 'mac': data.net[key]['mac'],
+ 'ip': data.net[key]['ipv4'],
+ 'ipv6': data.net[key]['ipv6'],
+ 'hostname': ''
+ }
+ result.client.networks.push(network)
+ }
+ }
+
+ /* edid */
+
+ /* lshw */
+ if (data.lshw && data.lshw.length > 0) {
+ /* Get display information (as fallback) */
+ if (result.client.gpus && result.client.gpus.length === 0) {
+ const gpus = data.lshw[0].children.filter(y => y.id === 'core')[0].children.filter(z => z.id === 'pci')[0].children.filter(w => w.id === 'display')
+ for (let gpu of gpus) {
+ result.client.gpus.push({
+ 'manufacturer': gpu.vendor,
+ 'model': gpu.product
+ /*,
+ 'memory': ,
+ 'unit':
+ */
+ })
+ }
+ }
+ }
+
+ return result
+}
+
+/*
* id: id of the current selected location.
* name: Name of the current selected location
* groups: List of group [{ id: <GROUP_ID>, name: <GROUP_NAME> }, ...]