Sikuliaq IT Asset Manager (skqitam)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

1153 lines
52 KiB

var path = require('path')
var fs = require('fs')
var skqlib = require('./skq_modules/skq-lib')
// GLOBAL CONFIG
process['CONFIG'] = JSON.parse(fs.readFileSync(path.join(__dirname, 'config','skqitam-server-config.json'), 'utf8'))
process['CONFIG']['GLOBAL']['RUN_DIR'] = __dirname
process['CONFIG']['LOCAL']= skqlib.it_am_init()
// console.log(JSON.stringify(process['CONFIG'], null, 2))
console.log ("Sikuliaq Cyber Asset Manager - Data Analyzer")
console.log (" - Version: v" + process['CONFIG']['LOCAL']['PACKAGE']['version'] + ' ' + process['CONFIG']['LOCAL']['PACKAGE']['version_date'] + ' (Beta)')
console.log (" - Copyright (C) 2021 University of Alaska Fairbanks - College of Fisheries and Ocean Sciences - R/V Sikuliaq")
console.log (" - Author: John Haverlack (jehaverlack@alaska.edu)\n")
console.log('Data Dir: ' + path.join(__dirname, process['CONFIG']['GLOBAL']['ITAM_DATA_DIR']))
let hostdir_base = path.join(__dirname, process['CONFIG']['GLOBAL']['ITAM_DATA_DIR'], 'hosts')
let hostdirs = fs.readdirSync(hostdir_base)
let index_keys = [
'DATA_TIMESTAMP',
'AM_ID',
'AM_HOSTNAME',
'INVENTORIED_BY',
'DESCRIPTION',
'LOCAL_HOSTNAME',
'SYSTEM_OWNER',
'IP_ADDR',
'OS',
'OS_VERSION',
'OS_ARCH',
'OS_INSTALL_DATE',
'KERNEL',
'KERNEL_VERSION',
'HW_MAKE',
'HW_MODEL',
'HW_SERIAL_NUMBER',
'HW_BIOS_VENDOR',
'HW_BIOS_VERSION',
'HW_BIOS_DATE',
'HW_CPU_MODEL',
'HW_CPU_CORES',
'HW_RAM_MB',
'HW_NETWORK'
]
let sw_index_keys = [
"NAME",
"VERSION",
"KERNEL",
"ARCH",
"INSTALL_DATE",
"ORIGIN"
]
// console.log(JSON.stringify(hostdirs, null, 2))
try {
fs.mkdirSync(path.join(__dirname, process['CONFIG']['GLOBAL']['ITAM_DATA_DIR'], 'reports'), { recursive: true })
} catch (e) {
console.log('ERROR: Could not mkdir: ' + path.join(__dirname, process['CONFIG']['GLOBAL']['ITAM_DATA_DIR'], 'reports'))
process.exit(1)
}
try {
fs.mkdirSync(path.join(__dirname, process['CONFIG']['GLOBAL']['ITAM_DATA_DIR'], 'proc'), { recursive: true })
} catch (e) {
console.log('ERROR: Could not mkdir: ' + path.join(__dirname, process['CONFIG']['GLOBAL']['ITAM_DATA_DIR'], 'proc'))
process.exit(1)
}
let index_data_file = path.join(__dirname, process['CONFIG']['GLOBAL']['ITAM_DATA_DIR'], 'proc', 'index-data.json')
let index_data = {}
try {
index_data = JSON.parse(fs.readFileSync(index_data_file, 'utf8'))
} catch (e) {
// Do Nothing
}
let sw_index_data_file = path.join(__dirname, process['CONFIG']['GLOBAL']['ITAM_DATA_DIR'], 'proc', 'sw-index-data.json')
let sw_index_data = {}
try {
sw_index_data = JSON.parse(fs.readFileSync(sw_index_data_file, 'utf8'))
} catch (e) {
// Do Nothing
}
for (hd in hostdirs) {
let data_files = fs.readdirSync(path.join(__dirname, process['CONFIG']['GLOBAL']['ITAM_DATA_DIR'], 'hosts', hostdirs[hd], 'raw'))
// console.log(JSON.stringify(data_files, null, 2))
// console.log ("LATEST DATA: " + path.join(__dirname, process['CONFIG']['GLOBAL']['ITAM_DATA_DIR'], 'hosts', hostdirs[hd], 'raw', data_files[(data_files.length - 1)]))
// Get Latest Data
let host_data = JSON.parse(fs.readFileSync(path.join(__dirname, process['CONFIG']['GLOBAL']['ITAM_DATA_DIR'], 'hosts', hostdirs[hd], 'raw', data_files[(data_files.length - 1)]), 'utf8'))
// console.log("DEUG: " + JSON.stringify(host_data['ITAM'], null, 2))
if (host_data['ITAM'].hasOwnProperty('SKQITAM_VERSION')) {
console.log("------------------- ASSET ID: " + host_data['ITAM']['ID'] + " -------------------")
console.log(" " + host_data['ITAM']['STARTTIME'] + ' on ' + host_data['ITAM']['HOSTNAME'] + ' by ITAM v' + host_data['ITAM']['SKQITAM_VERSION'] + "\n");
// console.log(JSON.stringify(host_data['ITAM'], null, 2))
if (!index_data.hasOwnProperty(host_data['ITAM']['ID'])) {
index_data[ host_data['ITAM']['ID'] ] = {}
}
// Initialize
for (ik in index_keys) {
if (!index_data[ host_data['ITAM']['ID'] ].hasOwnProperty(index_keys[ik])) {
index_data[ host_data['ITAM']['ID'] ][ index_keys[ik] ] = ''
}
}
for (ik in sw_index_keys) {
if (!index_data[ host_data['ITAM']['ID'] ].hasOwnProperty(sw_index_keys[ik])) {
index_data[ host_data['ITAM']['ID'] ][ sw_index_keys[ik] ] = ''
}
}
// console.log('DATA INIT: ' + JSON.stringify(index_data[ host_data['ITAM']['ID'] ], null, 2))
index_data[ host_data['ITAM']['ID'] ]['DATA_TIMESTAMP'] = host_data['ITAM']['STARTTIME'].replace(' (UTC)', '')
index_data[ host_data['ITAM']['ID'] ]['AM_ID'] = host_data['ITAM']['ID']
index_data[ host_data['ITAM']['ID'] ]['AM_HOSTNAME'] = host_data['ITAM']['HOSTNAME']
index_data[ host_data['ITAM']['ID'] ]['INVENTORIED_BY'] = "ITAM: " + host_data['ITAM']['SKQITAM_VERSION']
index_data[ host_data['ITAM']['ID'] ]['DESCRIPTION'] = ''
index_data[ host_data['ITAM']['ID'] ]['LOCAL_HOSTNAME'] = host_data['SOURCE']['NODEJS']['HOST']['HOSTNAME']
index_data[ host_data['ITAM']['ID'] ]['IP_ADDR'] = host_data['SOURCE']['NODEJS']['HOST']['IP_ADDR'][0]['address']
index_data[ host_data['ITAM']['ID'] ]['OS'] = host_data['SOURCE']['NODEJS']['OS']['DISTRO']
index_data[ host_data['ITAM']['ID'] ]['OS_VERSION'] = host_data['SOURCE']['NODEJS']['OS']['DISTRO_VERSION']
index_data[ host_data['ITAM']['ID'] ]['OS_ARCH'] = host_data['SOURCE']['NODEJS']['OS']['ARCH']
index_data[ host_data['ITAM']['ID'] ]['OS_INSTALL_DATE'] = host_data['SOURCE']['OS_INSTALL_ISO_DATE']
index_data[ host_data['ITAM']['ID'] ]['KERNEL'] = host_data['SOURCE']['NODEJS']['OS']['KERNEL']
index_data[ host_data['ITAM']['ID'] ]['KERNEL_VERSION'] = host_data['SOURCE']['NODEJS']['OS']['KERNEL_VERSION']
// index_data[ host_data['ITAM']['ID'] ]['HW_MAKE'] = ''
// index_data[ host_data['ITAM']['ID'] ]['HW_MODEL'] = ''
// index_data[ host_data['ITAM']['ID'] ]['HW_SERIAL_NUMBER'] = ''
// index_data[ host_data['ITAM']['ID'] ]['HW_BIOS_VENDOR'] = ''
// index_data[ host_data['ITAM']['ID'] ]['HW_BIOS_VERSION'] = ''
// index_data[ host_data['ITAM']['ID'] ]['HW_BIOS_DATE'] = ''
if (host_data['SOURCE'].hasOwnProperty('DMIDECODE')) {
// console.log(JSON.stringify(host_data['SOURCE']['DMIDECODE'], null, 2));
index_data[ host_data['ITAM']['ID'] ]['HW_MAKE'] = host_data['SOURCE']['DMIDECODE']['baseboard-manufacturer']
index_data[ host_data['ITAM']['ID'] ]['HW_MODEL'] = host_data['SOURCE']['DMIDECODE']['baseboard-product-name']
switch (host_data['SOURCE']['DMIDECODE']['baseboard-serial-number']) {
case 'None':
index_data[ host_data['ITAM']['ID'] ]['HW_SERIAL_NUMBER'] = host_data['SOURCE']['DMIDECODE']['system-uuid']
break;
case 'Default string':
index_data[ host_data['ITAM']['ID'] ]['HW_SERIAL_NUMBER'] = host_data['SOURCE']['DMIDECODE']['system-uuid']
break;
default:
index_data[ host_data['ITAM']['ID'] ]['HW_SERIAL_NUMBER'] = host_data['SOURCE']['DMIDECODE']['baseboard-serial-number']
}
index_data[ host_data['ITAM']['ID'] ]['HW_BIOS_VENDOR'] = host_data['SOURCE']['DMIDECODE']['bios-vendor']
index_data[ host_data['ITAM']['ID'] ]['HW_BIOS_VERSION'] = host_data['SOURCE']['DMIDECODE']['bios-version']
index_data[ host_data['ITAM']['ID'] ]['HW_BIOS_DATE'] = host_data['SOURCE']['DMIDECODE']['bios-release-date']
}
if (host_data['SOURCE'].hasOwnProperty('FACTER')) {
if (!index_data[ host_data['ITAM']['ID'] ]['HW_SERIAL_NUMBER']) {
index_data[ host_data['ITAM']['ID'] ]['HW_SERIAL_NUMBER'] = host_data['SOURCE']['FACTER']['uniqueid']
}
if (host_data['SOURCE']['FACTER']['is_virtual'] == "true") {
switch (host_data['SOURCE']['FACTER']['virtual']) {
case 'vmware':
index_data[ host_data['ITAM']['ID'] ]['HW_MAKE'] = 'VMware'
index_data[ host_data['ITAM']['ID'] ]['HW_MODEL'] = 'ESXi v6.7.0'
break;
case 'virtualbox':
index_data[ host_data['ITAM']['ID'] ]['HW_MAKE'] = 'Oracle Corporation'
index_data[ host_data['ITAM']['ID'] ]['HW_MODEL'] = 'VirtualBox'
break;
}
}
}
if (host_data['SOURCE'].hasOwnProperty('RASPBERRY_SERIALNUMBER')) {
index_data[ host_data['ITAM']['ID'] ]['HW_SERIAL_NUMBER'] = host_data['SOURCE']['RASPBERRY_SERIALNUMBER']
}
if (host_data['SOURCE'].hasOwnProperty('RASPBERRY_PI_MODEL')) {
index_data[ host_data['ITAM']['ID'] ]['HW_MAKE'] = 'Raspberry Pi'
index_data[ host_data['ITAM']['ID'] ]['HW_MODEL'] = host_data['SOURCE']['RASPBERRY_PI_MODEL']
}
if (index_data[ host_data['ITAM']['ID'] ]['KERNEL'] == 'Linux') {
if (host_data['SOURCE'].hasOwnProperty('ETC_PASSWD')) {
if (host_data['SOURCE']['ETC_PASSWD'].hasOwnProperty('sqadmin')) {
index_data[ host_data['ITAM']['ID'] ]['SYSTEM_OWNER'] = 'SKQ IT'
} else if (host_data['SOURCE'].hasOwnProperty('HOME_DIRS')) {
index_data[ host_data['ITAM']['ID'] ]['SYSTEM_OWNER'] = JSON.stringify(host_data['SOURCE']['HOME_DIRS'])
}
}
}
if (host_data['SOURCE'].hasOwnProperty('SYSTEMINFO')) {
if (host_data['SOURCE']['SYSTEMINFO']['System Manufacturer'] == "VMware, Inc.") {
index_data[ host_data['ITAM']['ID'] ]['HW_MAKE'] = 'VMware'
index_data[ host_data['ITAM']['ID'] ]['HW_MODEL'] = 'ESXi v6.7.0'
} else {
index_data[ host_data['ITAM']['ID'] ]['HW_MAKE'] = host_data['SOURCE']['SYSTEMINFO']['System Manufacturer']
index_data[ host_data['ITAM']['ID'] ]['HW_MODEL'] = host_data['SOURCE']['SYSTEMINFO']['System Model']
}
index_data[ host_data['ITAM']['ID'] ]['HW_SERIAL_NUMBER'] = host_data['SOURCE']['SYSTEMINFO']['baseboard-serial-number']
index_data[ host_data['ITAM']['ID'] ]['HW_BIOS_VENDOR'] = host_data['SOURCE']['SYSTEMINFO']['BIOS Version']
index_data[ host_data['ITAM']['ID'] ]['HW_BIOS_VERSION'] = host_data['SOURCE']['SYSTEMINFO']['BIOS Version']
index_data[ host_data['ITAM']['ID'] ]['HW_BIOS_DATE'] = host_data['SOURCE']['SYSTEMINFO']['BIOS Version']
index_data[ host_data['ITAM']['ID'] ]['SYSTEM_OWNER'] = host_data['SOURCE']['SYSTEMINFO']['Registered Owner']
}
if (host_data['SOURCE'].hasOwnProperty('WMIC_SERIALNUMBER')) {
index_data[ host_data['ITAM']['ID'] ]['HW_SERIAL_NUMBER'] = host_data['SOURCE']['WMIC_SERIALNUMBER']
}
if (host_data['SOURCE'].hasOwnProperty('SYSTEM_PROFILER')) {
if (host_data['SOURCE']['SYSTEM_PROFILER']['SPHardwareDataType'].hasOwnProperty('Hardware')) {
index_data[ host_data['ITAM']['ID'] ]['HW_MAKE'] = 'Apple Inc.'
index_data[ host_data['ITAM']['ID'] ]['HW_MODEL'] = host_data['SOURCE']['SYSTEM_PROFILER']['SPHardwareDataType']['Hardware']['Hardware Overview']['Model Identifier']
index_data[ host_data['ITAM']['ID'] ]['HW_SERIAL_NUMBER'] = host_data['SOURCE']['SYSTEM_PROFILER']['SPHardwareDataType']['Hardware']['Hardware Overview']['Serial Number (system)']
index_data[ host_data['ITAM']['ID'] ]['HW_BIOS_VENDOR'] = 'Apple Inc.'
index_data[ host_data['ITAM']['ID'] ]['HW_BIOS_VERSION'] = host_data['SOURCE']['SYSTEM_PROFILER']['SPHardwareDataType']['Hardware']['Hardware Overview']['Boot ROM Version']
index_data[ host_data['ITAM']['ID'] ]['SYSTEM_OWNER'] = host_data['SOURCE']['SYSTEM_PROFILER']['SPSoftwareDataType']['Software']['System Software Overview']['User Name']
} else if (host_data['SOURCE']['SYSTEM_PROFILER']['SPHardwareDataType'][0].hasOwnProperty('serial_number')) {
index_data[ host_data['ITAM']['ID'] ]['HW_MAKE'] = 'Apple Inc.'
index_data[ host_data['ITAM']['ID'] ]['HW_MODEL'] = host_data['SOURCE']['SYSTEM_PROFILER']['SPHardwareDataType'][0]['machine_model']
index_data[ host_data['ITAM']['ID'] ]['HW_SERIAL_NUMBER'] = host_data['SOURCE']['SYSTEM_PROFILER']['SPHardwareDataType'][0]['serial_number']
index_data[ host_data['ITAM']['ID'] ]['HW_BIOS_VENDOR'] = 'Apple Inc.'
index_data[ host_data['ITAM']['ID'] ]['HW_BIOS_VERSION'] = host_data['SOURCE']['SYSTEM_PROFILER']['SPHardwareDataType'][0]['boot_rom_version']
index_data[ host_data['ITAM']['ID'] ]['SYSTEM_OWNER'] = host_data['SOURCE']['SYSTEM_PROFILER']['SPSoftwareDataType'][0]['user_name']
}
}
index_data[ host_data['ITAM']['ID'] ]['HW_CPU_MODEL'] = host_data['SOURCE']['NODEJS']['HW']['CPU']['MODEL']
index_data[ host_data['ITAM']['ID'] ]['HW_CPU_CORES'] = host_data['SOURCE']['NODEJS']['HW']['CPU']['CORES']
index_data[ host_data['ITAM']['ID'] ]['HW_RAM_MB'] = host_data['SOURCE']['NODEJS']['HW']['RAM_MEMORY']['MB']
// console.log(JSON.stringify())
index_data[ host_data['ITAM']['ID'] ]['HW_NETWORK'] = ''
for (nic in host_data['SOURCE']['NODEJS']['HW']['NETWORK']) {
for (addr in host_data['SOURCE']['NODEJS']['HW']['NETWORK'][nic]) {
index_data[ host_data['ITAM']['ID'] ]['HW_NETWORK'] += "," + nic + '_' + host_data['SOURCE']['NODEJS']['HW']['NETWORK'][nic][addr]['family'] + '_' + host_data['SOURCE']['NODEJS']['HW']['NETWORK'][nic][addr]['mac'] + '_' + host_data['SOURCE']['NODEJS']['HW']['NETWORK'][nic][addr]['family'] + '_' + host_data['SOURCE']['NODEJS']['HW']['NETWORK'][nic][addr]['cidr']
}
}
index_data[ host_data['ITAM']['ID'] ]['HW_NETWORK'] = index_data[ host_data['ITAM']['ID'] ]['HW_NETWORK'].replace(/^,/, '')
// for (ik in index_keys) {
// if (!index_data[ host_data['ITAM']['ID'] ].hasOwnProperty(index_keys[ik])) {
// console.log('MISSING: ' + index_keys[ik])
// index_data[ host_data['ITAM']['ID'] ][ index_keys[ik] ] = ''
// }
// }
// console.log(index_data[ host_data['ITAM']['ID'] ]['AM_ID'] + ' : ' + index_data[ host_data['ITAM']['ID'] ]['AM_HOSTNAME'])
// console.log('DATA: ' + JSON.stringify(index_data[ host_data['ITAM']['ID'] ], null, 2))
// console.log(Object.keys(index_data[ host_data['ITAM']['ID'] ]))
// Software Analysis
// console.log("Software Analysis")
// console.log(JSON.stringify(Object.keys(host_data['SOURCE']['SW']), null, 2))
// console.log(host_data['ITAM']['ID'])
// console.log(host_data['SOURCE']['NODEJS']['OS']['DISTRO'])
sw_index_data[ host_data['ITAM']['ID'] ] = {}
if (host_data['SOURCE'].hasOwnProperty("SYSTEM_PROFILER")) {
// console.log("SYSTEM_PROFILER")
// for (sw in host_data['SOURCE']['SYSTEM_PROFILER']['SPInstallHistoryDataType']) {
// console.log(' SPInstallHistoryDataType: ' + host_data['SOURCE']['SYSTEM_PROFILER']['SPInstallHistoryDataType'][sw]['_name'])
// }
if (host_data['SOURCE']['SYSTEM_PROFILER']['SPApplicationsDataType'].hasOwnProperty('Applications')) {
for (sw in host_data['SOURCE']['SYSTEM_PROFILER']['SPApplicationsDataType']['Applications']) {
// console.log('SW: ' + sw)
sw_idx = sw
sw_index_data[ host_data['ITAM']['ID'] ][sw_idx] = {}
sw_index_data[ host_data['ITAM']['ID'] ][sw_idx]['NAME'] = sw
if (host_data['SOURCE']['SYSTEM_PROFILER']['SPApplicationsDataType']['Applications'][sw].hasOwnProperty('Version')) {
sw_index_data[ host_data['ITAM']['ID'] ][sw_idx]['VERSION'] = host_data['SOURCE']['SYSTEM_PROFILER']['SPApplicationsDataType']['Applications'][sw]['Version']
} else {
sw_index_data[ host_data['ITAM']['ID'] ][sw_idx]['VERSION'] = host_data['SOURCE']['SYSTEM_PROFILER']['SPApplicationsDataType']['Applications'][sw]['Last Modified']
}
sw_index_data[ host_data['ITAM']['ID'] ][sw_idx]['KERNEL'] = host_data['SOURCE']['NODEJS']['OS']['KERNEL']
sw_index_data[ host_data['ITAM']['ID'] ][sw_idx]['ARCH'] = ''
if (host_data['SOURCE']['SYSTEM_PROFILER']['SPApplicationsDataType']['Applications'][sw_idx].hasOwnProperty("64-Bit (Intel)")) {
if (host_data['SOURCE']['SYSTEM_PROFILER']['SPApplicationsDataType']['Applications'][sw_idx]['64-Bit (Intel)'] == "Yes") {
sw_index_data[ host_data['ITAM']['ID'] ][sw_idx]['ARCH'] = 'Intel x64'
} else {
sw_index_data[ host_data['ITAM']['ID'] ][sw_idx]['ARCH'] = host_data['SOURCE']['SYSTEM_PROFILER']['SPApplicationsDataType']['Applications'][sw]['Kind']
}
} else {
sw_index_data[ host_data['ITAM']['ID'] ][sw_idx]['ARCH'] = host_data['SOURCE']['SYSTEM_PROFILER']['SPApplicationsDataType']['Applications'][sw]['Kind']
}
sw_index_data[ host_data['ITAM']['ID'] ][sw_idx]['INSTALL_DATE'] = host_data['SOURCE']['SYSTEM_PROFILER']['SPApplicationsDataType']['Applications'][sw]['Last Modified']
sw_index_data[ host_data['ITAM']['ID'] ][sw_idx]['ORIGIN'] = host_data['SOURCE']['SYSTEM_PROFILER']['SPApplicationsDataType']['Applications'][sw]['Signed by']
}
} else { // SYSTEM_PROFILER Supports JSON
for (sw in host_data['SOURCE']['SYSTEM_PROFILER']['SPApplicationsDataType']) {
// console.log('SW: ' + sw + ' ' + host_data['SOURCE']['SYSTEM_PROFILER']['SPApplicationsDataType'][sw]['_name'])
sw_idx = host_data['SOURCE']['SYSTEM_PROFILER']['SPApplicationsDataType'][sw]['_name']
sw_index_data[ host_data['ITAM']['ID'] ][sw_idx] = {}
sw_index_data[ host_data['ITAM']['ID'] ][sw_idx]['NAME'] = host_data['SOURCE']['SYSTEM_PROFILER']['SPApplicationsDataType'][sw]['_name']
if (host_data['SOURCE']['SYSTEM_PROFILER']['SPApplicationsDataType'][sw].hasOwnProperty('version')) {
sw_index_data[ host_data['ITAM']['ID'] ][sw_idx]['VERSION'] = host_data['SOURCE']['SYSTEM_PROFILER']['SPApplicationsDataType'][sw]['version']
} else {
sw_index_data[ host_data['ITAM']['ID'] ][sw_idx]['VERSION'] = host_data['SOURCE']['SYSTEM_PROFILER']['SPApplicationsDataType'][sw]['lastModified']
}
sw_index_data[ host_data['ITAM']['ID'] ][sw_idx]['KERNEL'] = host_data['SOURCE']['NODEJS']['OS']['KERNEL']
sw_index_data[ host_data['ITAM']['ID'] ][sw_idx]['ARCH'] = host_data['SOURCE']['SYSTEM_PROFILER']['SPApplicationsDataType'][sw]['arch_kind']
sw_index_data[ host_data['ITAM']['ID'] ][sw_idx]['INSTALL_DATE'] = host_data['SOURCE']['SYSTEM_PROFILER']['SPApplicationsDataType'][sw]['lastModified']
if (host_data['SOURCE']['SYSTEM_PROFILER']['SPApplicationsDataType'][sw].hasOwnProperty('signed_by')) {
sw_index_data[ host_data['ITAM']['ID'] ][sw_idx]['ORIGIN'] = JSON.stringify(host_data['SOURCE']['SYSTEM_PROFILER']['SPApplicationsDataType'][sw]['signed_by'])
// for (sdx in host_data['SOURCE']['SYSTEM_PROFILER']['SPApplicationsDataType'][sw]['signed_by']) {
// // console.log(sdx + ' ' + host_data['SOURCE']['SYSTEM_PROFILER']['SPApplicationsDataType'][sw]['signed_by'][sdx])
// if (sdx == 1) {
// sw_index_data[ host_data['ITAM']['ID'] ][sw_idx]['ORIGIN'] = host_data['SOURCE']['SYSTEM_PROFILER']['SPApplicationsDataType'][sw]['signed_by'][sdx]
// }
// }
} else if (host_data['SOURCE']['SYSTEM_PROFILER']['SPApplicationsDataType'][sw].hasOwnProperty('obtained_from')) {
sw_index_data[ host_data['ITAM']['ID'] ][sw_idx]['ORIGIN'] = host_data['SOURCE']['SYSTEM_PROFILER']['SPApplicationsDataType'][sw]['obtained_from']
} else {
sw_index_data[ host_data['ITAM']['ID'] ][sw_idx]['ORIGIN'] = ''
}
}
}
} else {
for (swsrc in host_data['SOURCE']['SW']) {
switch (swsrc) {
case 'DEB':
// console.log(swsrc)
for (sw in host_data['SOURCE']['SW'][swsrc]) {
sw_idx = sw
sw_index_data[ host_data['ITAM']['ID'] ][sw_idx] = {}
sw_index_data[ host_data['ITAM']['ID'] ][sw_idx]['NAME'] = sw
if (Object.keys(host_data['SOURCE']['SW'][swsrc][sw]['DPKG_LIST']).length > 0) {
sw_index_data[ host_data['ITAM']['ID'] ][sw_idx]['VERSION'] = host_data['SOURCE']['SW'][swsrc][sw]['DPKG_LIST']['VERSION']
sw_index_data[ host_data['ITAM']['ID'] ][sw_idx]['KERNEL'] = host_data['SOURCE']['NODEJS']['OS']['KERNEL']
sw_index_data[ host_data['ITAM']['ID'] ][sw_idx]['ARCH'] = host_data['SOURCE']['SW'][swsrc][sw]['DPKG_LIST']['ARCH']
} else if (Object.keys(host_data['SOURCE']['SW'][swsrc][sw]['APT_CACHE']).length > 0) {
sw_index_data[ host_data['ITAM']['ID'] ][sw_idx]['VERSION'] = host_data['SOURCE']['SW'][swsrc][sw]['APT_CACHE']['Version']
sw_index_data[ host_data['ITAM']['ID'] ][sw_idx]['KERNEL'] = host_data['SOURCE']['NODEJS']['OS']['KERNEL']
sw_index_data[ host_data['ITAM']['ID'] ][sw_idx]['ARCH'] = host_data['SOURCE']['SW'][swsrc][sw]['APT_CACHE']['Architecture']
}
if (Object.keys(host_data['SOURCE']['SW'][swsrc][sw]['APT_HISTORY']).length > 0) {
// console.log ("APT_HISTORY")
for (ah in host_data['SOURCE']['SW'][swsrc][sw]['APT_HISTORY']) {
// console.log(sw_idx + ' ' + ah + ' ' + host_data['SOURCE']['SW'][swsrc][sw]['APT_HISTORY'][ah]['EVENT'])
switch (host_data['SOURCE']['SW'][swsrc][sw]['APT_HISTORY'][ah]['EVENT']) {
case 'Install':
if (host_data['SOURCE']['SW'][swsrc][sw]['APT_HISTORY'][ah]['VERSION'] == sw_index_data[ host_data['ITAM']['ID'] ][sw_idx]['VERSION']) {
if (sw_index_data[ host_data['ITAM']['ID'] ][sw_idx]['INSTALL_DATE'] && (sw_index_data[ host_data['ITAM']['ID'] ][sw_idx]['INSTALL_DATE'] > ah)) {
sw_index_data[ host_data['ITAM']['ID'] ][sw_idx]['INSTALL_DATE'] = ah
} else {
sw_index_data[ host_data['ITAM']['ID'] ][sw_idx]['INSTALL_DATE'] = ah
}
}
break;
case 'Upgrade':
if (host_data['SOURCE']['SW'][swsrc][sw]['APT_HISTORY'][ah]['VERSION'] == sw_index_data[ host_data['ITAM']['ID'] ][sw_idx]['VERSION']) {
if (sw_index_data[ host_data['ITAM']['ID'] ][sw_idx]['INSTALL_DATE'] && (sw_index_data[ host_data['ITAM']['ID'] ][sw_idx]['INSTALL_DATE'] > ah)) {
sw_index_data[ host_data['ITAM']['ID'] ][sw_idx]['INSTALL_DATE'] = ah
} else {
sw_index_data[ host_data['ITAM']['ID'] ][sw_idx]['INSTALL_DATE'] = ah
}
}
break;
}
}
}
if (Object.keys(host_data['SOURCE']['SW'][swsrc][sw]['APT_CACHE']).length > 0) {
sw_index_data[ host_data['ITAM']['ID'] ][sw_idx]['ORIGIN'] = host_data['SOURCE']['SW'][swsrc][sw]['APT_CACHE']['Maintainer']
}
}
break;
case 'RPM':
// console.log(swsrc)
for (sw in host_data['SOURCE']['SW'][swsrc]) {
sw_idx = host_data['SOURCE']['SW'][swsrc][sw]['Name']
sw_index_data[ host_data['ITAM']['ID'] ][sw_idx] = {}
sw_index_data[ host_data['ITAM']['ID'] ][sw_idx]['NAME'] = host_data['SOURCE']['SW'][swsrc][sw]['Name']
sw_index_data[ host_data['ITAM']['ID'] ][sw_idx]['VERSION'] = host_data['SOURCE']['SW'][swsrc][sw]['Version']
sw_index_data[ host_data['ITAM']['ID'] ][sw_idx]['KERNEL'] = host_data['SOURCE']['NODEJS']['OS']['KERNEL']
sw_index_data[ host_data['ITAM']['ID'] ][sw_idx]['ARCH'] = host_data['SOURCE']['SW'][swsrc][sw]['Architecture']
sw_index_data[ host_data['ITAM']['ID'] ][sw_idx]['INSTALL_DATE'] = host_data['SOURCE']['SW'][swsrc][sw]['InstallDate']
sw_index_data[ host_data['ITAM']['ID'] ][sw_idx]['ORIGIN'] = host_data['SOURCE']['SW'][swsrc][sw]['Packager']
}
break;
case 'GET_ITEMPROPERTY':
// console.log(swsrc)
for (sw in host_data['SOURCE']['SW'][swsrc]) {
sw_idx = host_data['SOURCE']['SW'][swsrc][sw]['DisplayName']
// console.log(sw + ' : ' + sw_idx)
sw_index_data[ host_data['ITAM']['ID'] ][sw_idx] = {}
sw_index_data[ host_data['ITAM']['ID'] ][sw_idx]['NAME'] = host_data['SOURCE']['SW'][swsrc][sw]['DisplayName']
sw_index_data[ host_data['ITAM']['ID'] ][sw_idx]['VERSION'] = host_data['SOURCE']['SW'][swsrc][sw]['DisplayVersion']
sw_index_data[ host_data['ITAM']['ID'] ][sw_idx]['KERNEL'] = host_data['SOURCE']['NODEJS']['OS']['KERNEL']
if (host_data['SOURCE']['SW'][swsrc][sw]['InstallLocation']) {
sw_index_data[ host_data['ITAM']['ID'] ][sw_idx]['ARCH'] = host_data['SOURCE']['SW'][swsrc][sw]['InstallLocation']
} else {
sw_index_data[ host_data['ITAM']['ID'] ][sw_idx]['ARCH'] = ''
}
sw_index_data[ host_data['ITAM']['ID'] ][sw_idx]['INSTALL_DATE'] = host_data['SOURCE']['SW'][swsrc][sw]['DisplayVersion']
sw_index_data[ host_data['ITAM']['ID'] ][sw_idx]['ORIGIN'] = host_data['SOURCE']['SW'][swsrc][sw]['Publisher']
}
break;
default:
console.log('WARNING: Unknown Software Source: ' + swsrc)
}
}
}
} // END if (host_data['ITAM'].hasOwnProperty('SKQITAM_VERSION')) {
} // END for (hd in hostdirs) {
// Stats
console.log('---------- Generating Statistics ------------')
let kernel_map = {}
kernel_map['Linux'] = 'Linux'
kernel_map['Darwin'] = 'OS X'
kernel_map['Windows_NT'] = 'Windows'
let stats = {}
stats['HISTOGRAMS'] = {}
stats['HISTOGRAMS']['KERNEL'] = {}
stats['HISTOGRAMS']['OS'] = {}
stats['HISTOGRAMS']['OS_VERSIONS'] = {}
stats['HISTOGRAMS']['INSTALL_DATES_YYYY'] = {}
stats['HISTOGRAMS']['INSTALL_DATES_YYYY-MM-DD'] = {}
stats['HISTOGRAMS']['SW_APPLICATIONS'] = {}
stats['HISTOGRAMS']['SW_VERSIONS'] = {}
stats['HISTOGRAMS']['SW_INSTALL_DATES'] = {}
stats['HISTOGRAMS']['SW_AGE_DAYS'] = {}
stats['HISTOGRAMS']['SW_PER_APP_LATEST_VERSION'] = {}
stats['HISTOGRAMS']['SW_PER_HOST_LATEST_VERSION'] = {}
stats['HISTOGRAMS']['SW_VERSIONS_STATUS'] = {}
stats['HISTOGRAMS']['SW_PER_APP_LATEST_VERSION_SCORES'] = {}
stats['HISTOGRAMS']['SW_PER_HOST_LATEST_VERSION_SCORES'] = {}
for (h in index_data) {
let isd = skqlib.tell_time(index_data[h]['OS_INSTALL_DATE'])
if ( !stats['HISTOGRAMS']['INSTALL_DATES_YYYY'].hasOwnProperty(isd['UTC']['YYYY']) ) {
stats['HISTOGRAMS']['INSTALL_DATES_YYYY'][ isd['UTC']['YYYY'] ] = 0
}
stats['HISTOGRAMS']['INSTALL_DATES_YYYY'][ isd['UTC']['YYYY'] ]++
if ( !stats['HISTOGRAMS']['INSTALL_DATES_YYYY-MM-DD'].hasOwnProperty(isd['UTC']['YYYY-MM-DD']) ) {
stats['HISTOGRAMS']['INSTALL_DATES_YYYY-MM-DD'][ isd['UTC']['YYYY-MM-DD'] ] = 0
}
stats['HISTOGRAMS']['INSTALL_DATES_YYYY-MM-DD'][ isd['UTC']['YYYY-MM-DD'] ]++
if (!stats['HISTOGRAMS']['KERNEL'].hasOwnProperty(kernel_map [ index_data[h]['KERNEL'] ])) {
stats['HISTOGRAMS']['KERNEL'][ kernel_map [ index_data[h]['KERNEL'] ] ] = 0
}
stats['HISTOGRAMS']['KERNEL'][ kernel_map [ index_data[h]['KERNEL'] ] ]++
if (!stats['HISTOGRAMS']['OS'].hasOwnProperty(index_data[h]['OS'])) {
stats['HISTOGRAMS']['OS'][ index_data[h]['OS'] ] = 0
}
stats['HISTOGRAMS']['OS'][ index_data[h]['OS'] ]++
if (!stats['HISTOGRAMS']['OS_VERSIONS'].hasOwnProperty(String(index_data[h]['OS'])[0].toUpperCase() + String(index_data[h]['OS']).slice(1) + ' ' + index_data[h]['OS_VERSION'])) {
stats['HISTOGRAMS']['OS_VERSIONS'][ String(index_data[h]['OS'])[0].toUpperCase() + String(index_data[h]['OS']).slice(1) + ' ' + index_data[h]['OS_VERSION'] ] = 0
}
stats['HISTOGRAMS']['OS_VERSIONS'][ String(index_data[h]['OS'])[0].toUpperCase() + String(index_data[h]['OS']).slice(1) + ' ' + index_data[h]['OS_VERSION'] ]++
}
// Software Stats
let now = skqlib.tell_time()
let regx_swver = []
rx = 0
// regx_swver[rx++] = '/^(\d+)\.$/'
// regx_swver[rx++] = /^(\d+)[.:~](\d+)[.:~](\d+)[.:~](\d+)[+\-_:](\S+)$/
// regx_swver[rx++] = /^(\d+)[.:~](\d+)[.:~](\d+)[+\-_:](\S+)$/
// regx_swver[rx++] = /^(\d+)[.:~](\d+)[+\-_:](\S+)$/
// regx_swver[rx++] = /^(\d+)[+\-_:](\S+)$/
regx_swver[rx++] = /^(\d+)[\.\:\~](\d+)[\.\:\~](\d+)[\.\:\~](\d+)/
regx_swver[rx++] = /^(\d+)[\.\:\~](\d+)[\.\:\~](\d+)/
regx_swver[rx++] = /^(\d+)[\.\:\~](\d+)/
regx_swver[rx++] = /^(\d+)/
// console.log(JSON.stringify(regx_swver, null, 2))
let swver_status = {}
swver_status['MATCH'] = 0
swver_status['MISMATCH'] = 0
swver_status['MISSING'] = 0
swver_status['TOTAL'] = 0
for (h in sw_index_data) {
for (sw in sw_index_data[h]) {
swver_status['TOTAL']++
let swisd = {}
swisd['UTC'] = {}
swisd['UTC']['YYYY-MM-DD'] = 'YYYY-MM-DD'
if (sw_index_data[h][sw].hasOwnProperty('INSTALL_DATE')) {
swisd = skqlib.tell_time(sw_index_data[h][sw]['INSTALL_DATE'])
}
if (!stats['HISTOGRAMS']['SW_APPLICATIONS'].hasOwnProperty(sw)) {
stats['HISTOGRAMS']['SW_APPLICATIONS'][sw] = 0
}
stats['HISTOGRAMS']['SW_APPLICATIONS'][sw]++
// console.log(h + ' ' + sw + ' ' + swisd['UTC']['YYYY-MM-DD'])
if (!stats['HISTOGRAMS']['SW_INSTALL_DATES'].hasOwnProperty( swisd['UTC']['YYYY-MM-DD'] )) {
stats['HISTOGRAMS']['SW_INSTALL_DATES'][ swisd['UTC']['YYYY-MM-DD'] ] = 0
}
stats['HISTOGRAMS']['SW_INSTALL_DATES'][ swisd['UTC']['YYYY-MM-DD'] ]++
if (swisd['UTC']['YYYY-MM-DD'].match(/^\d{4}\-\d{2}\-\d{2}$/)) {
let sw_age_days = Math.round( (Number(now['UTC']['EPOCH']) - Number(swisd['UTC']['EPOCH'])) / (24*3600) )
if (!stats['HISTOGRAMS']['SW_AGE_DAYS'].hasOwnProperty( sw_age_days )) {
stats['HISTOGRAMS']['SW_AGE_DAYS'][ sw_age_days ] = 0
}
stats['HISTOGRAMS']['SW_AGE_DAYS'][ sw_age_days ]++
} else {
swage = 'UNKNOWN'
if (!stats['HISTOGRAMS']['SW_AGE_DAYS'].hasOwnProperty( swage )) {
stats['HISTOGRAMS']['SW_AGE_DAYS'][ swage ] = 0
}
stats['HISTOGRAMS']['SW_AGE_DAYS'][ swage ]++
}
if (!stats['HISTOGRAMS']['SW_VERSIONS'].hasOwnProperty(sw)) {
stats['HISTOGRAMS']['SW_VERSIONS'][sw] = {}
}
// VooDoo BUG:
// -------------
// 3c9f9ad652a4aa092fb0696e679d546e3d82b7a9a6bb5a80ac83acdaf2c6636d:NVM for Windows :{
// "NAME": "NVM for Windows ",
// "KERNEL": "Windows_NT",
// "ARCH": "C:\\Users\\cfosadmin\\AppData\\Roaming\\nvm\\",
// "ORIGIN": "Ecor Ventures LLC"
// }
// DEBUG: NAME => NVM for Windows
// DEBUG: VERSION => undefined
// DEBUG: KERNEL => Windows_NT
// DEBUG: ARCH => C:\Users\cfosadmin\AppData\Roaming\nvm\
// DEBUG: INSTALL_DATE => undefined
// DEBUG: ORIGIN => Ecor Ventures LLC
// DEBUG: VERSION true
// DEBUG: VERSION undefined
// DEBUG: Success Version NVM for Windows undefined
// console.log('-------------')
//
// console.log(h + ':' + sw + ':' + JSON.stringify(sw_index_data[h][sw], null, 2))
// for (k in sw_index_data[h][sw]) {
// console.log('DEBUG: ' + k + ' => ' + sw_index_data[h][sw][k])
// }
//
// console.log('DEBUG: VERSION ' + (sw_index_data[h][sw]['VERSION'] === undefined))
// console.log('DEBUG: VERSION ' + sw_index_data[h][sw]['VERSION'])
//
// if (sw_index_data[h][sw].hasOwnProperty("VERSION")) {
// console.log('DEBUG: Success Version ' + sw + ' ' + sw_index_data[h][sw]['VERSION'])
// } else {
// console.log('DEBUG: Failed Version')
// }
let sw_version = ''
let version_match = false
for (rx in regx_swver) {
regx = RegExp(regx_swver[rx])
// if (sw_index_data[h][sw].hasOwnProperty('VERSION')) {
if (!(sw_index_data[h][sw]['VERSION'] === undefined)) {
// console.log(JSON.stringify(sw_index_data[h][sw], null, 2))
// console.log(sw + ' REGX: ' + regx + ' ' + sw_index_data[h][sw]['VERSION'])
if (!version_match && (swver_mch = sw_index_data[h][sw]['VERSION'].match(regx))) {
// console.log(sw + ' ' + sw_index_data[h][sw]['VERSION'] + ' ' + rx + ': ' + regx + ' => ' + JSON.stringify(swver_mch, null, 2))
version_match = true
swver_status['MATCH']++
for (iv=1; iv<swver_mch.length; iv++) {
if (swver_mch[iv].match(/^\d+$/)) {
sw_version += swver_mch[iv] + '.'
}
}
}
} else {
// console.log("MISSING VERSION: \n" + h + "\n" + JSON.stringify(sw_index_data[h][sw], null, 2))
sw_version = 'NULL'
swver_status['MISSING']++
}
}
if (!version_match) {
// console.log("WARNING: Unmatched Version Pattern (" + sw_index_data[h][sw]['VERSION'] + ")")
sw_version = 'ERROR: ' + sw_index_data[h][sw]['VERSION']
swver_status['MISMATCH']++
}
sw_version = sw_version.replace(RegExp(/\.$/), '')
// console.log(sw + ' ' + sw_version)
if (!stats['HISTOGRAMS']['SW_VERSIONS'][sw].hasOwnProperty(sw_version)) {
stats['HISTOGRAMS']['SW_VERSIONS'][sw][ sw_version ] = []
}
stats['HISTOGRAMS']['SW_VERSIONS'][sw][ sw_version ]++
}
}
stats['HISTOGRAMS']['SW_VERSIONS_STATUS'] = swver_status
// console.log('swver_status: ' + "\n" + JSON.stringify(swver_status, null, 2))
let sorted_vers = []
for (h in sw_index_data) {
for (sw in sw_index_data[h]) {
// console.log(sw)
if (Object.keys(stats['HISTOGRAMS']['SW_VERSIONS'][sw]).length > 1) {
// console.log(JSON.stringify(stats['HISTOGRAMS']['SW_VERSIONS'][sw], null, 2))
// console.log(JSON.stringify(Object.keys(stats['HISTOGRAMS']['SW_VERSIONS'][sw]), null, 2))
sorted_vers = sort_versions(Object.keys(stats['HISTOGRAMS']['SW_VERSIONS'][sw]))
} else {
sorted_vers.push( Object.keys( stats['HISTOGRAMS']['SW_VERSIONS'][sw] )[0] )
}
// console.log(JSON.stringify(sorted_vers, null, 2))
let lastest_version = false
let regx = RegExp('^' + sorted_vers[ (sorted_vers.length-1) ].replace(/\./g, '\\.'))
// console.log(regx)
if (String(sw_index_data[h][sw]['VERSION']).match(regx)) {
lastest_version = true
}
// console.log(h + ' : ' + sw + ' ' + sw_index_data[h][sw]['VERSION'] + ' <=> ' + sorted_vers[ (sorted_vers.length-1) ] + ' UPTODATE: ' + lastest_version)
if (!stats['HISTOGRAMS']['SW_PER_APP_LATEST_VERSION'].hasOwnProperty(sw)) {
stats['HISTOGRAMS']['SW_PER_APP_LATEST_VERSION'][sw] = {}
stats['HISTOGRAMS']['SW_PER_APP_LATEST_VERSION'][sw]['UP_TO_DATE'] = 0
stats['HISTOGRAMS']['SW_PER_APP_LATEST_VERSION'][sw]['OUT_OF_DATE'] = 0
}
if (lastest_version) {
stats['HISTOGRAMS']['SW_PER_APP_LATEST_VERSION'][sw]['UP_TO_DATE']++
} else {
stats['HISTOGRAMS']['SW_PER_APP_LATEST_VERSION'][sw]['OUT_OF_DATE']++
}
if (!stats['HISTOGRAMS']['SW_PER_HOST_LATEST_VERSION'].hasOwnProperty(h)) {
stats['HISTOGRAMS']['SW_PER_HOST_LATEST_VERSION'][h] = {}
stats['HISTOGRAMS']['SW_PER_HOST_LATEST_VERSION'][h]['UP_TO_DATE'] = 0
stats['HISTOGRAMS']['SW_PER_HOST_LATEST_VERSION'][h]['OUT_OF_DATE'] = 0
}
if (lastest_version) {
stats['HISTOGRAMS']['SW_PER_HOST_LATEST_VERSION'][h]['UP_TO_DATE']++
} else {
stats['HISTOGRAMS']['SW_PER_HOST_LATEST_VERSION'][h]['OUT_OF_DATE']++
}
}
}
for (sw in stats['HISTOGRAMS']['SW_PER_APP_LATEST_VERSION']) {
stats['HISTOGRAMS']['SW_PER_APP_LATEST_VERSION'][sw]['UP_TO_DATE_SCORE'] = Number(stats['HISTOGRAMS']['SW_PER_APP_LATEST_VERSION'][sw]['UP_TO_DATE'])/(Number(stats['HISTOGRAMS']['SW_PER_APP_LATEST_VERSION'][sw]['UP_TO_DATE']) + Number(stats['HISTOGRAMS']['SW_PER_APP_LATEST_VERSION'][sw]['OUT_OF_DATE']))
for (scr=0; scr<=1; scr+=0.1) {
scridx = Number(scr).toPrecision(2)
if (!stats['HISTOGRAMS']['SW_PER_APP_LATEST_VERSION_SCORES'].hasOwnProperty(scridx)) {
stats['HISTOGRAMS']['SW_PER_APP_LATEST_VERSION_SCORES'][scridx] = 0
}
if ( (Number(scridx) <= stats['HISTOGRAMS']['SW_PER_APP_LATEST_VERSION'][sw]['UP_TO_DATE_SCORE']) && (stats['HISTOGRAMS']['SW_PER_APP_LATEST_VERSION'][sw]['UP_TO_DATE_SCORE'] < (Number(scridx)+0.1)) ) {
stats['HISTOGRAMS']['SW_PER_APP_LATEST_VERSION_SCORES'][scridx]++
}
}
}
for (h in stats['HISTOGRAMS']['SW_PER_HOST_LATEST_VERSION']) {
stats['HISTOGRAMS']['SW_PER_HOST_LATEST_VERSION'][h]['UP_TO_DATE_SCORE'] = Number(stats['HISTOGRAMS']['SW_PER_HOST_LATEST_VERSION'][h]['UP_TO_DATE'])/(Number(stats['HISTOGRAMS']['SW_PER_HOST_LATEST_VERSION'][h]['UP_TO_DATE']) + Number(stats['HISTOGRAMS']['SW_PER_HOST_LATEST_VERSION'][h]['OUT_OF_DATE']))
for (scr=0; scr<=1; scr+=0.1) {
scridx = Number(scr).toPrecision(2)
if (!stats['HISTOGRAMS']['SW_PER_HOST_LATEST_VERSION_SCORES'].hasOwnProperty(scridx)) {
stats['HISTOGRAMS']['SW_PER_HOST_LATEST_VERSION_SCORES'][scridx] = 0
}
if ( (Number(scridx) <= stats['HISTOGRAMS']['SW_PER_HOST_LATEST_VERSION'][h]['UP_TO_DATE_SCORE']) && (stats['HISTOGRAMS']['SW_PER_HOST_LATEST_VERSION'][h]['UP_TO_DATE_SCORE'] < (Number(scridx)+0.1)) ) {
stats['HISTOGRAMS']['SW_PER_HOST_LATEST_VERSION_SCORES'][scridx]++
}
}
}
// console.log(JSON.stringify(stats, null, 2))
// Save Data Files
console.log('---------- Writing Files ------------')
// console.log(JSON.stringify(index_data, null, 2))
console.log('WRITING: ' + index_data_file)
fs.writeFileSync(index_data_file, JSON.stringify(index_data, null, 2), 'utf8')
console.log('WRITING: ' + sw_index_data_file)
fs.writeFileSync(sw_index_data_file, JSON.stringify(sw_index_data, null, 2), 'utf8')
console.log('WRITING: ' + index_data_file.replace(/json$/, 'csv'))
fs.writeFileSync(index_data_file.replace(/json$/, 'csv'), index_data_to_csv(index_keys, index_data), 'utf8')
console.log('WRITING: ' + sw_index_data_file.replace(/json$/, 'csv'))
fs.writeFileSync(sw_index_data_file.replace(/json$/, 'csv'), sw_index_data_to_csv(sw_index_keys, sw_index_data), 'utf8')
let stats_file = path.join(__dirname, 'itam-data', 'proc', 'stats.json')
console.log('WRITING: ' + stats_file)
fs.writeFileSync(stats_file, JSON.stringify(stats, null, 2), 'utf8')
// Sikuliaq CSV Reports
console.log('WRITING: ' + path.join(__dirname, 'itam-data', 'reports', 'skq_appendix_d_hw.csv'))
fs.writeFileSync(path.join(__dirname, 'itam-data', 'reports', 'skq_appendix_d_hw.csv'), skq_index_data_to_app_d_hw_csv(index_keys, index_data), 'utf8')
console.log('WRITING: ' + path.join(__dirname, 'itam-data', 'reports', 'skq_appendix_d_sw.csv'))
fs.writeFileSync(path.join(__dirname, 'itam-data', 'reports', 'skq_appendix_d_sw.csv'), skq_index_data_to_app_d_sw_csv(sw_index_keys, sw_index_data), 'utf8')
function index_data_to_csv(keys, data) {
let csv = ""
for (k in keys) {
csv += '"' + keys[k] + '"'
if (k < (keys.length-1)) { csv += ","} else { csv += "\n" }
}
for (i in data) {
for (k in keys) {
if (data[i].hasOwnProperty(keys[k]) && data[i][ keys[k] ]) {
csv += '"' + data[i][ keys[k] ] + '"'
} else {
csv += '""'
}
if (k < (keys.length-1)) { csv += ","} else { csv += "\n" }
}
}
return csv
}
function sw_index_data_to_csv(keys, data) {
let csv = ""
keys.push('INSTALL_HOST_ID')
for (k in keys) {
csv += '"' + keys[k] + '"'
if (k < (keys.length-1)) { csv += ","} else { csv += "\n" }
}
for (h in data) {
for (i in data[h]) {
for (k in keys) {
if(keys[k] == "INSTALL_HOST_ID") {
csv += '"' + h + '"'
} else {
if (data[h][i].hasOwnProperty(keys[k]) && data[h][i][ keys[k] ]) {
csv += '"' + data[h][i][ keys[k] ] + '"'
} else {
csv += '""'
}
}
if (k < (keys.length-1)) { csv += ","} else { csv += "\n" }
}
}
}
return csv
}
function skq_index_data_to_app_d_sw_csv(keys, data) {
let csv = ''
let keymap = {}
keymap['AM_ID'] = 'Asset IDs'
keymap['NAME'] = 'Name of Software'
keymap['VERSION'] = 'Installed Version'
keymap['INSTALL_DATE'] = 'Date of Install'
let reverse_keymap = {}
for (k in keymap) { reverse_keymap[ keymap[k] ] = k }
// CSV Header
let hk = 0
for (k in keymap) {
csv += '"' + keymap[k] + '"'
if (hk < (Object.keys(keymap).length-1)) { csv += ","} else { csv += "\n" }
hk++
}
let apps = {}
for (amid in data) {
// console.log(amid)
// console.log(JSON.stringify(data[amid], null, 2))
for (sw in data[amid]) {
if (!apps.hasOwnProperty(data[amid][sw]['NAME'] + ':-:' + data[amid][sw]['VERSION'])) {
apps[ data[amid][sw]['NAME'] + ':-:' + data[amid][sw]['VERSION'] ] = {}
apps[ data[amid][sw]['NAME'] + ':-:' + data[amid][sw]['VERSION'] ]['Asset IDs'] = ''
apps[ data[amid][sw]['NAME'] + ':-:' + data[amid][sw]['VERSION'] ]['Name of Software'] = data[amid][sw]['NAME']
apps[ data[amid][sw]['NAME'] + ':-:' + data[amid][sw]['VERSION'] ]['Installed Version'] = data[amid][sw]['VERSION']
apps[ data[amid][sw]['NAME'] + ':-:' + data[amid][sw]['VERSION'] ]['Date of Install'] = ''
}
apps[ data[amid][sw]['NAME'] + ':-:' + data[amid][sw]['VERSION'] ]['Asset IDs'] += amid + ', '
if (data[amid][sw]['INSTALL_DATE']) {
let inst = skqlib.tell_time(data[amid][sw]['INSTALL_DATE'])
apps[ data[amid][sw]['NAME'] + ':-:' + data[amid][sw]['VERSION'] ]['Date of Install'] += inst['UTC']['YYYY-MM-DD'] + ', '
}
}
}
for (a in apps) {
for (k in apps[a]) {
if (k != 'Date of Install') {
csv += '"' + String(apps[a][k]).replace(RegExp(', $'), '') + '",'
} else {
csv += '"' + String(apps[a][k]).replace(RegExp(', $'), '') + '"' + "\n"
}
}
}
// console.log(JSON.stringify(apps, null, 2))
// console.log(JSON.stringify(Object.keys(apps), null, 2))
return csv
}
function skq_index_data_to_app_d_hw_csv(keys, data) {
// Sikuliaq Appendix D Hardware CSV
let keymap = {}
keymap['AM_HOSTNAME'] = 'Machine Name'
keymap['AM_ID'] = 'Asset ID'
keymap['HW_MAKE'] = 'Manufacturer'
keymap['HW_MODEL'] = 'Model Number'
keymap['HW_SERIAL_NUMBER'] = 'Serial Number'
keymap['OS'] = 'Operating System'
keymap['OS_INSTALL_DATE'] = 'Install Date'
keymap['SYSTEM_OWNER'] = 'Administrator/Custodian/POC'
let reverse_keymap = {}
for (k in keymap) { reverse_keymap[ keymap[k] ] = k }
reverse_keymap['Type of Equipment'] = 'ASSET_TYPE'
let appendix_d_hw_keys = [
"Type of Equipment",
"Machine Name",
"Asset ID",
"Manufacturer",
"Model Number",
"Serial Number",
"Operating System and/or Firmware Version",
"Install Date",
"Network",
"Internet Access",
"System Classification",
"Administrator/Custodian/POC"
]
let skq_network_regx = {}
skq_network_regx['Shrnet'] = RegExp(/^10\.0\.0\./)
skq_network_regx['Infrastructure'] = RegExp(/^10\.1\.0\./)
skq_network_regx['Core'] = RegExp(/^10\.2\.0\./)
skq_network_regx['Data'] = RegExp(/^10\.3\.0\./)
skq_network_regx['Video'] = RegExp(/^10\.4\.0\./)
skq_network_regx['Shipwide'] = RegExp(/^10\.5\./)
skq_network_regx['WAN_Stack'] = RegExp(/^199\.123\.165\./)
// skq_network_regx['CCTV'] = RegExp(/^10\.1\.0\./)
// skq_network_regx['IBS'] = RegExp(/^10\.1\.0\./)
// skq_network_regx['IAS'] = RegExp(/^10\.1\.0\./)
let skq_sys_class = {}
skq_sys_class['Shrnet'] = "IT-Inf"
skq_sys_class['Infrastructure'] = "IT-Inf"
skq_sys_class['Core'] = "IT-Sci"
skq_sys_class['Data'] = "IT-Data Aq"
skq_sys_class['Video'] = "IT-Inf"
skq_sys_class['Shipwide'] = "IT-end user"
skq_sys_class['WAN_Stack'] = "IT-WAN"
// "IT-LAN",
// "OT-Sci",
// "OT-Eng",
// "OT-Brdg"
let csv = ""
let data_csv = ""
// CSV Header
for (k in appendix_d_hw_keys) {
csv += '"' + appendix_d_hw_keys[k] + '"'
if (k < (appendix_d_hw_keys.length-1)) { csv += ","} else { csv += "\n" }
}
for (i in data) {
data_csv = ""
// console.log("App-D: " + i)
data[i]['ASSET_TYPE'] = 'Networked Computer'
for (k in appendix_d_hw_keys) {
// console.log(' ' + appendix_d_hw_keys[k] + ' ' + reverse_keymap[ appendix_d_hw_keys[k] ] + ' ' + data[i][ reverse_keymap[ appendix_d_hw_keys[k] ] ])
// console.log(JSON.stringify(reverse_keymap, null, 2))
switch (appendix_d_hw_keys[k]) {
case "Type of Equipment":
data_csv += '"Networked Computer"'
if (k < (appendix_d_hw_keys.length-1)) { data_csv += ","} else { data_csv += "\n" }
break;
case "Machine Name":
if (data[i].hasOwnProperty(reverse_keymap[ appendix_d_hw_keys[k] ]) && data[i][ reverse_keymap[ appendix_d_hw_keys[k] ] ]) {
data_csv += '"' + data[i][ reverse_keymap[ appendix_d_hw_keys[k] ] ] + '"'
} else {
data_csv += '""'
}
if (k < (appendix_d_hw_keys.length-1)) { data_csv += ","} else { data_csv += "\n" }
break;
case "Asset ID":
if (data[i].hasOwnProperty(reverse_keymap[ appendix_d_hw_keys[k] ]) && data[i][ reverse_keymap[ appendix_d_hw_keys[k] ] ]) {
data_csv += '"' + data[i][ reverse_keymap[ appendix_d_hw_keys[k] ] ] + '"'
} else {
data_csv += '""'
}
if (k < (appendix_d_hw_keys.length-1)) { data_csv += ","} else { data_csv += "\n" }
break;
case "Manufacturer":
if (data[i].hasOwnProperty(reverse_keymap[ appendix_d_hw_keys[k] ]) && data[i][ reverse_keymap[ appendix_d_hw_keys[k] ] ]) {
data_csv += '"' + data[i][ reverse_keymap[ appendix_d_hw_keys[k] ] ] + '"'
} else {
data_csv += '""'
}
if (k < (appendix_d_hw_keys.length-1)) {
data_csv += ","
} else {
data_csv += "\n"
}
break;
case "Model Number":
if (data[i].hasOwnProperty(reverse_keymap[ appendix_d_hw_keys[k] ]) && data[i][ reverse_keymap[ appendix_d_hw_keys[k] ] ]) {
data_csv += '"' + data[i][ reverse_keymap[ appendix_d_hw_keys[k] ] ] + '"'
} else {
data_csv += '""'
}
if (k < (appendix_d_hw_keys.length-1)) { data_csv += ","} else { data_csv += "\n" }
break;
case "Serial Number":
if (data[i].hasOwnProperty(reverse_keymap[ appendix_d_hw_keys[k] ]) && data[i][ reverse_keymap[ appendix_d_hw_keys[k] ] ]) {
data_csv += '"' + data[i][ reverse_keymap[ appendix_d_hw_keys[k] ] ] + '"'
} else {
data_csv += '""'
}
if (k < (appendix_d_hw_keys.length-1)) {
data_csv += ","
} else {
data_csv += "\n"
}
break;
case "Operating System and/or Firmware Version":
data_csv += '"' + data[i]['OS'] + ' (' + data[i]['OS_VERSION'] + ') ' + data[i]['OS_ARCH'] + '"'
if (k < (appendix_d_hw_keys.length-1)) { data_csv += ","} else { data_csv += "\n" }
break;
case "Install Date":
if (data[i].hasOwnProperty(reverse_keymap[ appendix_d_hw_keys[k] ]) && data[i][ reverse_keymap[ appendix_d_hw_keys[k] ] ]) {
data_csv += '"' + data[i][ reverse_keymap[ appendix_d_hw_keys[k] ] ] + '"'
} else {
data_csv += '""'
}
if (k < (appendix_d_hw_keys.length-1)) { data_csv += ","} else { data_csv += "\n" }
break;
case "Network":
net = false
for (n in skq_network_regx) {
// console.log(n)
if (!net) {
if (data[i]['IP_ADDR'].match(skq_network_regx[n])) {
net = true
data_csv += '"' + n + '"'
if (k < (appendix_d_hw_keys.length-1)) { data_csv += ","} else { data_csv += "\n" }
}
}
}
if (!net) {
data_csv += '"UNKNOWN"'
if (k < (appendix_d_hw_keys.length-1)) { data_csv += ","} else { data_csv += "\n" }
}
break;
case "Internet Access":
net = false
for (n in skq_network_regx) {
if (!net) {
if (data[i]['IP_ADDR'].match(skq_network_regx[n])) {
if (n == 'Shrnet' || n == 'Infrastructure' || n == 'Shipwide') {
net = true
data_csv += '"YES"'
if (k < (appendix_d_hw_keys.length-1)) { data_csv += ","} else { data_csv += "\n" }
}
}
}
}
if (!net) {
data_csv += '"NO"'
if (k < (appendix_d_hw_keys.length-1)) { data_csv += ","} else { data_csv += "\n" }
}
break;
case "System Classification":
net = false
for (n in skq_network_regx) {
if (!net) {
if (data[i]['IP_ADDR'].match(skq_network_regx[n])) {
net = true
data_csv += '"' + skq_sys_class[n] + '"'
if (k < (appendix_d_hw_keys.length-1)) { data_csv += ","} else { data_csv += "\n" }
}
}
}
if (!net) {
data_csv += '"UNKNOWN"'
if (k < (appendix_d_hw_keys.length-1)) { data_csv += ","} else { data_csv += "\n" }
}
break;
case "Administrator/Custodian/POC":
if (data[i].hasOwnProperty(reverse_keymap[ appendix_d_hw_keys[k] ]) && data[i][ reverse_keymap[ appendix_d_hw_keys[k] ] ]) {
data_csv += '"' + data[i][ reverse_keymap[ appendix_d_hw_keys[k] ] ] + '"'
} else {
data_csv += '""'
}
if (k < (appendix_d_hw_keys.length-1)) { data_csv += ","} else { data_csv += "\n" }
break;
default:
console.log('ERROR: Unknown Key' + appendix_d_hw_keys[k]);
process.exit(1)
}
}
// console.log("CSV: " + data_csv)
if (data_csv != "undefined") {
csv += data_csv
}
}
return csv
}
function sort_versions (version_array) {
// Takes in a array of semver (w.x.y.z) values and sort them numerically by version
// Supports up to 4 numeric version levels
let sorted = []
let version_obj = {}
for (v in version_array) {
if(version_split = String(version_array[v]).split(/\./)) {
// console.log(JSON.stringify(version_split, null, 2))
for (i=0; i<version_split.length; i++) {
// console.log(i + ' < ' + version_split.length + ' ' + version_array[v])
switch (i) {
case 0:
if (version_split.hasOwnProperty(0) && !version_obj.hasOwnProperty( version_split[0] )) {
version_obj[ version_split[0] ] = {}
}
case 1:
if (version_split.hasOwnProperty(1) && !version_obj[ version_split[0] ].hasOwnProperty( version_split[1] )) {
version_obj[ version_split[0] ][ version_split[1] ] = {}
}
case 2:
if (version_split.hasOwnProperty(2) && !version_obj[ version_split[0] ][ version_split[1] ].hasOwnProperty( version_split[2] )) {
version_obj[ version_split[0] ][ version_split[1] ][ version_split[2] ] = {}
}
case 3:
if (version_split.hasOwnProperty(3) && !version_obj[ version_split[0] ][ version_split[1] ][ version_split[2] ].hasOwnProperty( version_split[3] )) {
version_obj[ version_split[0] ][ version_split[1] ][ version_split[2] ][ version_split[3] ] = {}
}
break;
}
// console.log(i + JSON.stringify(version_obj, null, 2))
}
} else {
console.log('ERROR: Version Split Parser: ' + version_array[v])
}
}
// console.log(JSON.stringify(version_obj, null, 2))
for (v1 in version_obj) {
// console.log('ln ' + Object.keys(version_obj[v1]).length)
if (Object.keys(version_obj[v1]).length == 0) {
// console.log ('ver: ' + v1)
sorted.push(v1)
}
for (v2 in version_obj[v1]) {
if (Object.keys(version_obj[v1][v2]).length == 0) {
// console.log ('ver: ' + v1 + '.' + v2)
sorted.push(v1 + '.' + v2)
}
for (v3 in version_obj[v1][v2]) {
if (Object.keys(version_obj[v1][v2][v3]).length == 0) {
// console.log ('ver: ' + v1 + '.' + v2 + '.' + v3)
sorted.push(v1 + '.' + v2 + '.' + v3)
}
for (v4 in version_obj[v1][v2][v3]) {
if (Object.keys(version_obj[v1][v2][v3][v4]).length == 0) {
// console.log ('ver: ' + v1 + '.' + v2 + '.' + v3 + '.' + v4)
sorted.push(v1 + '.' + v2 + '.' + v3 + '.' + v4)
}
}
}
}
}
return sorted
}