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.
 
 
 

1398 lines
55 KiB

var path = require('path')
var fs = require('fs')
var os = require('os')
// const readline = require('readline')
var request = require("request")
const { v4: uuidv4 } = require('uuid');
const childProcess = require('child_process');
const isAdmin = require('is-admin')
const crypto = require('crypto')
var http = require('http')
let app_dir = path.join(os.userInfo().homedir, '.skqitam')
console.log()
if (os.type() == "Windows_NT") {
app_dir = path.join(os.userInfo().homedir, 'AppData', 'Local', 'skqitam')
}
// console.log (" AppDir: " + app_dir)
// GLOBAL CONFIG
let baseurlregx = RegExp('^http[s]?://')
let config_file = path.join(app_dir, 'skqitam-client-config.json')
process['CONFIG'] = {}
try {
process['CONFIG']['FILE'] = JSON.parse(fs.readFileSync(config_file, 'utf8'))
} catch (err) {
process['CONFIG']['FILE'] = {}
}
process['CONFIG']['GLOBAL'] = {}
process['CONFIG']['GLOBAL']['RUN_DIR'] = __dirname
process['CONFIG']['GLOBAL']['SERVER_BASE_URL'] = ''
if (process.argv[2] == "INIT" && process.argv[3].match(baseurlregx)) {
process['CONFIG']['FILE']['SERVER_BASE_URL'] = process.argv[3]
process['CONFIG']['GLOBAL']['SERVER_BASE_URL'] = process['CONFIG']['FILE']['SERVER_BASE_URL']
if (!process['CONFIG']['FILE'].hasOwnProperty('UUID')) {
process['CONFIG']['FILE']['UUID'] = uuidv4();
}
process['CONFIG']['GLOBAL']['UUID'] = process['CONFIG']['FILE']['UUID']
// console.log('WRITING: ' + config_file)
fs.writeFileSync(config_file, JSON.stringify(process['CONFIG']['FILE'], null, 2),'utf8')
} else {
process['CONFIG']['GLOBAL']['SERVER_BASE_URL'] = process['CONFIG']['FILE']['SERVER_BASE_URL']
}
process['CONFIG']['LOCAL'] = it_am_init()
// console.log (JSON.stringify(process['CONFIG'], null, 2))
// ------------ Collect System Data ------------ //
var am_data = {}
let ts = tell_time()
let starttime = ts['UTC']['EPOCH']
am_data['ITAM']= {}
am_data['ITAM']['HOSTNAME'] = process['CONFIG']['LOCAL']['HOST']['HOSTNAME']
if (process['CONFIG']['LOCAL']['HOST']['DNSNAME']) {
if ( am_data['ITAM']['HOSTNAME'] != process['CONFIG']['LOCAL']['HOST']['DNSNAME'] ) {
am_data['ITAM']['HOSTNAME'] = process['CONFIG']['LOCAL']['HOST']['DNSNAME']
}
}
am_data['ITAM']['ID'] = process['CONFIG']['LOCAL']['HOST']['HOST_ID']
am_data['ITAM']['UUID'] = process['CONFIG']['FILE']['UUID']
am_data['ITAM']['USERNAME'] = process['CONFIG']['LOCAL']['USER']['USERNAME']
am_data['ITAM']['APP_DIR'] = app_dir
am_data['ITAM']['SKQITAM_VERSION'] = process['CONFIG']['LOCAL']['PACKAGE']['version'] + ' ' + process['CONFIG']['LOCAL']['PACKAGE']['version_date']
am_data['ITAM']['STARTTIME'] = ts['UTC']['ISO8601'] + ' (UTC)'
am_data['SOURCE'] = {}
am_data['SOURCE']['NODEJS'] = {}
am_data['SOURCE']['DMIDECODE'] = {}
process['CONFIG']['DMIDECODE'] = {}
console.log ("")
console.log ("Sikuliaq IT Asset Manager Client")
console.log (" Version: " + process['CONFIG']['LOCAL']['PACKAGE']['version'] + ' ' + process['CONFIG']['LOCAL']['PACKAGE']['version_date'])
console.log (" Copyright: (C) 2021 University of Alaska Fairbanks - College of Fisheries and Ocean Sciences - R/V Sikuliaq")
console.log (" License: " + process['CONFIG']['LOCAL']['PACKAGE']['license'] + ' (https://opensource.org/licenses/ISC)')
console.log (" Author: John Haverlack (jehaverlack@alaska.edu)")
console.log ("")
console.log (" HOSTNAME: " + am_data['ITAM']['HOSTNAME'])
console.log (" LOCALHOST: " + process['CONFIG']['LOCAL']['HOST']['HOSTNAME'])
console.log (" ITAM ID: " + process['CONFIG']['LOCAL']['HOST']['HOST_ID'])
console.log (" USER: " + process['CONFIG']['LOCAL']['USER']['USERNAME'])
console.log (" HOMEDIR: " + process['CONFIG']['LOCAL']['USER']['HOMEDIR'])
console.log (" OS: " + process['CONFIG']['LOCAL']['OS']['DISTRO'] + ' (' + process['CONFIG']['LOCAL']['OS']['DISTRO_VERSION'] + ')' )
console.log (" Kern: " + process['CONFIG']['LOCAL']['OS']['TYPE'] + ' ' + process['CONFIG']['LOCAL']['OS']['RELEASE'] + ' ' + process['CONFIG']['LOCAL']['OS']['ARCH'])
// console.log (" CPU: " + JSON.stringify(os.cpus(), null, 2))
console.log (" CPU: " + os.cpus().length)
let mem_bytes = os.totalmem()
let mem_mb = Math.round(mem_bytes/(1024*1024))
console.log (" RAM: " + mem_mb + ' MB')
// console.log (" NET: " + JSON.stringify(os.networkInterfaces(), null, 2))
console.log (" ITAM SRV: " + process['CONFIG']['GLOBAL']['SERVER_BASE_URL'])
console.log (" ITAM DIR: " + am_data['ITAM']['APP_DIR'])
console.log (" TIME: " + am_data['ITAM']['STARTTIME'])
console.log ("")
// Optional Dependancies
if (process['CONFIG']['LOCAL']['OS']['PLATFORM'] == 'linux') {
try {
let stat_dmidecode = fs.lstatSync(path.join('/usr','sbin','dmidecode'))
// console.log(JSON.stringify(stat_dmidecode, null, 2))
try {
let dmidecode_datafile = fs.lstatSync(path.join(am_data['ITAM']['APP_DIR'], 'dmidcode.txt'))
// console.log(JSON.stringify(dmidecode_datafile, null, 2))
let data_dmidecode = fs.readFileSync(path.join(am_data['ITAM']['APP_DIR'], 'dmidcode.txt'), 'utf8')
// console.log(data_dmidecode)
let dmidecode_lines = String(data_dmidecode).split(/\n/)
let regx_dmidecode = RegExp(/^(\S+):\s+(\S+.*)/)
// console.log(JSON.stringify(dmidecode_lines, null, 2))
for (dmil in dmidecode_lines) {
if (dmch = dmidecode_lines[dmil].match(regx_dmidecode)) {
// process['CONFIG']['DMIDECODE'][ dmch[1] ] = dmch[2]
am_data['SOURCE']['DMIDECODE'][ dmch[1] ] = dmch[2]
}
}
// console.log(JSON.stringify(process['CONFIG']['DMIDECODE'] , null, 2))
// console.log(JSON.stringify(am_data['SOURCE']['DMIDECODE'], null, 2))
} catch (err2) {
console.log("MISSING: " + path.join(am_data['ITAM']['APP_DIR'], 'dmidcode.txt'))
console.log("\n#################################################################################")
console.log("OPTIONAL: Dmidecode is installed and can be run with sudo permission to collect\n additional hardware info on physical systems. To do so run the following\n command once and this re-run the skqitam-client.\n")
console.log("sudo " + path.join(am_data['ITAM']['APP_DIR'], 'skqitam-client', 'skqitam-dmidecode2txt.sh') + " " + path.join(am_data['ITAM']['APP_DIR'], 'dmidcode.txt'))
console.log("\n#################################################################################")
}
} catch (err1) {
console.log("\n#################################################################################")
console.log("OPTIONAL: Missing dmidcode. Dmidecode can collect additional hardware\n information but requires elevated permissions. To install dmidcode run:\n")
let sw_source_map = {}
sw_source_map['Debian GNU/Linux'] = 'DEB'
sw_source_map['Linux Mint'] = 'DEB'
sw_source_map['LinuxMint'] = 'DEB'
sw_source_map['Ubuntu'] = 'DEB'
sw_source_map['Raspbian GNU/Linux'] = 'DEB'
sw_source_map['CentOS Linux'] = 'RPM'
sw_source_map['CentOS'] = 'RPM'
switch (sw_source_map[process['CONFIG']['LOCAL']['OS']['DISTRO']]) {
case 'DEB':
console.log(" sudo apt install dmidcode")
break;
case 'RPM':
console.log(" sudo yum install dmidcode")
break;
default:
console.log("WARNING: Unknown DISTRO: " + process['CONFIG']['LOCAL']['OS']['DISTRO'])
}
console.log("\n#################################################################################")
}
}
// console.log (" Script: " + process.argv)
console.log ("Collecting Data: This may take serveral minutes .....")
console.log ("")
// console.log(JSON.stringify(am_data['SOURCE']['DMIDECODE'], null, 2))
// console.log (" User: " + JSON.stringify(os.userInfo(), null, 2))
// console.log (" Home: " + os.homedir())
// ------------ Collect System Data - Continued------------ //
// am_data['DATA_EVENT'] = {}
// am_data['DATA_EVENT']['TIMESTAMP'] = ts['UTC']['ISO8601']
am_data['SOURCE']['NODEJS']['HOST'] = {}
am_data['SOURCE']['NODEJS']['HOST']['HOSTNAME'] = process['CONFIG']['LOCAL']['HOST']['HOSTNAME']
am_data['SOURCE']['NODEJS']['HOST']['IP_ADDR'] = []
for (n in process['CONFIG']['LOCAL']['HOST']['HW']['NETWORK']) {
for (i in process['CONFIG']['LOCAL']['HOST']['HW']['NETWORK'][n]) {
if (!process['CONFIG']['LOCAL']['HOST']['HW']['NETWORK'][n][i]['internal'] && !process['CONFIG']['LOCAL']['HOST']['HW']['NETWORK'][n][i]['netmask'].match('ffff:ffff')) {
let ipaddr = process['CONFIG']['LOCAL']['HOST']['HW']['NETWORK'][n][i]
ipaddr['nic'] = n
am_data['SOURCE']['NODEJS']['HOST']['IP_ADDR'].push(ipaddr)
}
}
}
am_data['SOURCE']['NODEJS']['HW'] = {}
am_data['SOURCE']['NODEJS']['HW']['CPU'] = {}
am_data['SOURCE']['NODEJS']['HW']['CPU']['CORES'] = process['CONFIG']['LOCAL']['HOST']['HW']['CPUS'].length
am_data['SOURCE']['NODEJS']['HW']['CPU']['MODEL'] = process['CONFIG']['LOCAL']['HOST']['HW']['CPUS'][0]['model']
am_data['SOURCE']['NODEJS']['HW']['RAM_MEMORY'] = {}
am_data['SOURCE']['NODEJS']['HW']['RAM_MEMORY']['BYTES'] = process['CONFIG']['LOCAL']['HOST']['HW']['MEMORY_BYTES']
am_data['SOURCE']['NODEJS']['HW']['RAM_MEMORY']['MB'] = Math.round(Number(process['CONFIG']['LOCAL']['HOST']['HW']['MEMORY_BYTES'])/(1024*1024))
am_data['SOURCE']['NODEJS']['HW']['RAM_MEMORY']['GB'] = Math.round(Number(process['CONFIG']['LOCAL']['HOST']['HW']['MEMORY_BYTES'])/(1024*1024*1024))
am_data['SOURCE']['NODEJS']['HW']['NETWORK'] = process['CONFIG']['LOCAL']['HOST']['HW']['NETWORK']
am_data['SOURCE']['NODEJS']['OS'] = {}
am_data['SOURCE']['NODEJS']['OS']['DISTRO'] = process['CONFIG']['LOCAL']['OS']['DISTRO']
am_data['SOURCE']['NODEJS']['OS']['DISTRO_VERSION'] = process['CONFIG']['LOCAL']['OS']['DISTRO_VERSION']
am_data['SOURCE']['NODEJS']['OS']['PLATFORM'] = process['CONFIG']['LOCAL']['OS']['PLATFORM']
am_data['SOURCE']['NODEJS']['OS']['KERNEL'] = process['CONFIG']['LOCAL']['OS']['TYPE']
am_data['SOURCE']['NODEJS']['OS']['KERNEL_VERSION'] = process['CONFIG']['LOCAL']['OS']['RELEASE']
am_data['SOURCE']['NODEJS']['OS']['ARCH'] = process['CONFIG']['LOCAL']['OS']['ARCH']
am_data['SOURCE']['NODEJS']['OS']['ENDIAN'] = process['CONFIG']['LOCAL']['OS']['ENDIAN']
// Installed Software
let cmd_sw_list = ''
let sw_list = ''
let cmd_sw_list_map = {}
cmd_sw_list_map['Debian GNU/Linux'] = 'dpkg -l'
cmd_sw_list_map['Linux Mint'] = 'dpkg -l'
cmd_sw_list_map['LinuxMint'] = 'dpkg -l'
cmd_sw_list_map['Ubuntu'] = 'dpkg -l'
cmd_sw_list_map['Raspbian GNU/Linux'] = 'dpkg -l'
cmd_sw_list_map['CentOS Linux'] = 'rpm -qa'
cmd_sw_list_map['CentOS'] = 'rpm -qa'
// cmd_sw_list_map['Microsoft Windows'] = 'Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* | Select-Object InstallDate, DisplayVersion, Publisher, DisplayName, InstallLocation | Format-Table –AutoSize'
// cmd_sw_list_map['Microsoft Windows'] = 'Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*'
cmd_sw_list_map['Microsoft Windows'] = 'PowerShell.exe -command "Get-ItemProperty HKLM:\\Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\*"'
cmd_sw_list_map['macOS'] = 'system_profiler -json SPApplicationsDataType'
let sw_source_map = {}
sw_source_map['Debian GNU/Linux'] = 'DEB'
sw_source_map['Linux Mint'] = 'DEB'
sw_source_map['LinuxMint'] = 'DEB'
sw_source_map['Ubuntu'] = 'DEB'
sw_source_map['Raspbian GNU/Linux'] = 'DEB'
sw_source_map['CentOS Linux'] = 'RPM'
sw_source_map['CentOS'] = 'RPM'
// https://en.wikipedia.org/wiki/List_of_Microsoft_Windows_versions
let win_vers = [
"Microsoft Windows 10 Education",
"Microsoft Windows 10 Enterprise",
"Microsoft Windows 10 Enterprise LTSC (formerly LTSB)",
"Microsoft Windows 10 Home",
"Microsoft Windows 10 Pro",
"Microsoft Windows 10 Pro Education",
"Microsoft Windows 10 Pro for Workstations",
"Microsoft Windows 10 S",
"Microsoft Windows 11 Education",
"Microsoft Windows 11 Enterprise",
"Microsoft Windows 11 Home",
"Microsoft Windows 11 Pro",
"Microsoft Windows 11 Pro Education",
"Microsoft Windows 11 Pro for Workstations",
"Microsoft Windows 7 Enterprise",
"Microsoft Windows 7 Home Basic",
"Microsoft Windows 7 Home Premium",
"Microsoft Windows 7 Professional",
"Microsoft Windows 7 Starter",
"Microsoft Windows 7 Ultimate",
"Microsoft Windows 8",
"Microsoft Windows 8.1",
"Microsoft Windows 8.1 Enterprise",
"Microsoft Windows 8.1 Pro",
"Microsoft Windows 8.1 with Bing",
"Microsoft Windows 8 Enterprise",
"Microsoft Windows 8 Pro"
]
for (wv in win_vers) {
sw_source_map[ win_vers[wv] ] = 'GET_ITEMPROPERTY'
}
// console.log(JSON.stringify(sw_source_map, null, 2))
sw_source_map['macOS'] = 'SYSTEM_PROFILER'
sw_source_map['Mac OS X'] = 'SYSTEM_PROFILER'
am_data['SOURCE']['SW'] = {}
switch (process['CONFIG']['LOCAL']['OS']['PLATFORM']) {
case 'linux':
switch (sw_source_map[ process['CONFIG']['LOCAL']['OS']['DISTRO'] ]) {
case 'DEB':
am_data['SOURCE']['SW'][ sw_source_map[ process['CONFIG']['LOCAL']['OS']['DISTRO'] ] ] = dpkg_list_to_json( childProcess.execSync(cmd_sw_list_map[ process['CONFIG']['LOCAL']['OS']['DISTRO'] ], { encoding: 'utf8' }) )
break;
case 'RPM':
am_data['SOURCE']['SW'][ sw_source_map[ process['CONFIG']['LOCAL']['OS']['DISTRO'] ] ] = rpm_list_to_json( childProcess.execSync(cmd_sw_list_map[ process['CONFIG']['LOCAL']['OS']['DISTRO'] ], { encoding: 'utf8' }) )
break;
default:
console.log('ERROR: Unsupported Distribution: ' + process['CONFIG']['LOCAL']['OS']['DISTRO'])
process.exit(1)
}
switch (process['CONFIG']['LOCAL']['OS']['DISTRO']) {
case 'Raspbian GNU/Linux':
let cmd_rpi_hw = 'cat /proc/device-tree/model'
try {
am_data['SOURCE']['RASPBERRY_PI_MODEL'] = String(childProcess.execSync(cmd_rpi_hw, { encoding: 'utf8' })).replace('\u0000', '')
} catch (err) {
console.log("WARNING: Could not run: " + cmd_rpi_hw + "\n" + err)
}
cmd_rpi_hw = "cat /proc/cpuinfo | grep Serial | cut -d ' ' -f 2"
try {
am_data['SOURCE']['RASPBERRY_SERIALNUMBER'] = String(childProcess.execSync(cmd_rpi_hw, { encoding: 'utf8' })).replace(/\n/, '')
} catch (err) {
console.log("WARNING: Could not run: " + cmd_rpi_hw + "\n" + err)
}
break;
}
// Facter
try {
let bin_facter = childProcess.execSync('which facter', { encoding: 'utf8' })
try {
am_data['SOURCE']['FACTER'] = {}
facter_lines = String(childProcess.execSync(bin_facter, { encoding: 'utf8' })).split(/\n/)
facter_regx = RegExp(/^(\S+.*)\s+\=\>\s+(\S+.*)/)
for (fl in facter_lines) {
if (mch = facter_lines[fl].match(facter_regx)) {
if (! mch[1].match(/key/)) {
am_data['SOURCE']['FACTER'][ mch[1] ] = mch[2]
}
}
}
} catch (err) {
console.log ("WARNING: Could not run: " + bin_facter)
}
} catch (err) {
// Do Nothing
}
// Users
am_data['SOURCE']['ETC_PASSWD'] = {}
try {
let etc_passwd = String(fs.readFileSync(path.join('/etc', 'passwd'), 'utf8')).split(/\n/)
let regx_etc_passwd = RegExp(/^(\S+):(\S+):(\S+):(\S+):(.*):(\S+):(\S+)/)
for (ep in etc_passwd) {
if (epmch = etc_passwd[ep].match(regx_etc_passwd)) {
am_data['SOURCE']['ETC_PASSWD'][epmch[1]] = {}
am_data['SOURCE']['ETC_PASSWD'][epmch[1]]['USERNAME'] = epmch[1]
am_data['SOURCE']['ETC_PASSWD'][epmch[1]]['PASSWORD'] = epmch[2]
am_data['SOURCE']['ETC_PASSWD'][epmch[1]]['UID'] = epmch[3]
am_data['SOURCE']['ETC_PASSWD'][epmch[1]]['GID'] = epmch[4]
am_data['SOURCE']['ETC_PASSWD'][epmch[1]]['GECOS'] = epmch[5]
am_data['SOURCE']['ETC_PASSWD'][epmch[1]]['HOME'] = epmch[6]
am_data['SOURCE']['ETC_PASSWD'][epmch[1]]['SHELL'] = epmch[7]
}
}
} catch (e) {
}
// HOME DIRS
am_data['SOURCE']['HOME_DIRS'] = {}
try {
am_data['SOURCE']['HOME_DIRS'] = fs.readdirSync(path.join("/home"))
} catch (e) {
// Do Nothing
}
break;
case 'darwin':
am_data['SOURCE']['SYSTEM_PROFILER'] = {}
// am_data['SOURCE']['SYSTEM_PROFILER']['SW'] = JSON.parse(childProcess.execSync(cmd_sw_list_map[ process['CONFIG']['LOCAL']['OS']['DISTRO'] ], { encoding: 'utf8' }))
let sysprof_type = ['SPHardwareDataType', 'SPInstallHistoryDataType', 'SPLegacySoftwareDataType', 'SPApplicationsDataType', 'SPNetworkLocationDataType', 'SPSoftwareDataType']
// Check for JSON Unsupported
let has_json = childProcess.execSync('system_profiler -h 2>&1 |grep json |tail -n 1', { encoding: 'utf8' })
// console.log("Debug : " + has_json)
for (st in sysprof_type) {
if (has_json) {
let cmd_sys_prof = 'system_profiler -json ' + sysprof_type[st]
try {
am_data['SOURCE']['SYSTEM_PROFILER'][ sysprof_type[st] ] = JSON.parse(childProcess.execSync(cmd_sys_prof, { encoding: 'utf8' }))[ sysprof_type[st] ]
} catch (err) {
console.log("WARNING: Could not run: " + cmd_sys_prof + "\n" + err)
}
} else {
let cmd_sys_prof = 'system_profiler ' + sysprof_type[st]
try {
am_data['SOURCE']['SYSTEM_PROFILER'][ sysprof_type[st] ] = sysprof2json(childProcess.execSync(cmd_sys_prof, { encoding: 'utf8' }))
} catch (err) {
console.log("WARNING: Could not run: " + cmd_sys_prof + "\n" + err)
}
}
}
// HOME DIRS
am_data['SOURCE']['HOME_DIRS'] = {}
try {
am_data['SOURCE']['HOME_DIRS'] = fs.readdirSync(path.join("/Users"))
} catch (e) {
// Do Nothing
}
break;
case 'win32': // WIndows 10
// console.log('Platform: ' + process['CONFIG']['LOCAL']['OS']['PLATFORM'])
// console.log('Distro: ' + process['CONFIG']['LOCAL']['OS']['DISTRO'] + '(' + process['CONFIG']['LOCAL']['OS']['DISTRO_VERSION'] + ')')
// console.log (' Testing: ' + cmd_sw_list_map['Microsoft Windows'])
wincmd = 'systeminfo'
sys_info_regx = RegExp(/^(\S+.*):\s+(\S+.*)/)
sys_info_regx2 = RegExp(/^\s(\S+.*)/) // BROKEN FIXME
sys_info = {}
let last_fld = ''
try {
line = String(childProcess.execSync(wincmd, { encoding: 'utf8' })).split(/\r\n/)
for (l in line) {
if (mch = line[l].match(sys_info_regx)) {
sys_info[ mch[1] ] = mch[2]
last_fld = mch[1]
} else if (mch = line[l].match(sys_info_regx2)) {
console.log(last_fld)
sys_info[ last_fld ] += "\n" + mch[1]
}
}
am_data['SOURCE']['SYSTEMINFO'] = sys_info
// console.log (JSON.stringify(line, null, 2))
} catch (err) {
console.log('ERROR: Could not run: ' + wincmd + "\n" + err)
process.exit(1)
}
// https://www.computerhope.com/wmic.htm
wincmd = 'wmic bios get serialnumber'
try {
am_data['SOURCE']['WMIC_SERIALNUMBER'] = String(childProcess.execSync(wincmd, { encoding: 'utf8' })).replace(/\r\r\n/g, ' ').replace(/SerialNumber\s+/, '').replace(/\s+$/, '')
} catch (err) {
console.log('ERROR: Could not run: ' + wincmd + "\n" + err)
process.exit(1)
}
let get_item_prop_regx1 = RegExp(/^(\S.*\S)\s+:\s+(\S.*)/)
let get_item_prop_regx2 = RegExp(/^(\S.*\S)\s+:/)
try {
get_item_property = String(childProcess.execSync(cmd_sw_list_map['Microsoft Windows'], { encoding: 'utf8' })).split(/\r\n/)
let win_sw_list = {}
for (gip=0; gip<get_item_property.length; gip++) {
if (get_item_property[gip]) {
// console.log ('DEBUG FOR: [' + get_item_property[gip] + ']')
win_sw_item = {}
while ( get_item_property[gip]) {
// console.log ('DEBUG WHILE: [' + get_item_property[gip] + ']')
if (mch = get_item_property[gip].match(get_item_prop_regx1)) {
win_sw_item[ mch[1] ] = mch[2]
}
win_sw_list[ win_sw_item['DisplayName'] ] = win_sw_item
gip++
}
}
}
am_data['SOURCE']['SW'][ sw_source_map[ process['CONFIG']['LOCAL']['OS']['DISTRO'] ] ] = win_sw_list
} catch (err) {
console.log('ERROR: Could not run: ' + cmd_sw_list_map['Microsoft Windows'] + "\n" + err)
process.exit(1)
}
// HOME DIRS
am_data['SOURCE']['HOME_DIRS'] = {}
try {
am_data['SOURCE']['HOME_DIRS'] = fs.readdirSync(path.join("C:", "Users"))
} catch (e) {
// Do Nothing
}
break;
// case 'win64':
// // console.log('Platform: ' + process['CONFIG']['LOCAL']['OS']['PLATFORM'])
// // console.log('Distro: ' + process['CONFIG']['LOCAL']['OS']['DISTRO'] + '(' + process['CONFIG']['LOCAL']['OS']['DISTRO_VERSION'] + ')')
//
//
// // console.log (get_item_property)
//
// am_data['SOURCE']['SW'][ sw_source_map[ process['CONFIG']['LOCAL']['OS']['DISTRO'] ] ] = {}
// break;
default:
console.log('ERROR: Unsupported Platform: ' + process['CONFIG']['LOCAL']['OS']['PLATFORM'])
process.exit(1)
}
am_data['SOURCE']['OS_INSTALL_DATE'] = ''
// console.log("DISTO: " + sw_source_map[ process['CONFIG']['LOCAL']['OS']['DISTRO'] ]);
switch (sw_source_map[ process['CONFIG']['LOCAL']['OS']['DISTRO'] ]) {
case 'DEB':
try {
let stat_varloginst = fs.lstatSync(path.join('/var','log','installer'))
// console.log(JSON.stringify(stat_varloginst, null, 2));
am_data['SOURCE']['OS_INSTALL_DATE'] = stat_varloginst['mtime']
} catch (e) {
// Best guess method
let insttime = '2500-01-01 00:00:00'
for (pkg in am_data['SOURCE']['SW']['DEB']) {
for (pkghist in am_data['SOURCE']['SW']['DEB'][pkg]['APT_HISTORY']) {
if (pkghist < insttime) {
insttime = pkghist
}
}
}
if (insttime != '2500-01-01 00:00:00') {
am_data['SOURCE']['OS_INSTALL_DATE'] = insttime
}
}
break;
case 'RPM':
for (rpm in am_data['SOURCE']['SW']['RPM']) {
if (am_data['SOURCE']['SW']['RPM'][rpm]['Name'] == 'basesystem') {
if (am_data['SOURCE']['SW']['RPM'][rpm].hasOwnProperty('InstallDate')) {
am_data['SOURCE']['OS_INSTALL_DATE'] = am_data['SOURCE']['SW']['RPM'][rpm]['InstallDate']
}
}
}
break;
case 'SYSTEM_PROFILER':
try {
let install_log_lines = String(fs.readFileSync(path.join('/var','log','install.log'), 'utf8')).split(/\n/)
// console.log(JSON.stringify(install_log_lines, null, 2))
let regx_install_log = RegExp(/^(\S+)/)
if (ilmch = install_log_lines[0].match(regx_install_log)) {
am_data['SOURCE']['OS_INSTALL_DATE'] = ilmch[1]
}
} catch (e) {
console.log("WARNING: Cannot read /var/log/install.log")
// Do Nothing
}
break;
case 'GET_ITEMPROPERTY':
// console.log(JSON.stringify(am_data['SOURCE']['SYSTEMINFO'], null, 2))
if (am_data['SOURCE'].hasOwnProperty('SYSTEMINFO')) {
am_data['SOURCE']['OS_INSTALL_DATE'] = am_data['SOURCE']['SYSTEMINFO']['Original Install Date']
}
break;
}
am_data['SOURCE']['OS_INSTALL_ISO_DATE'] = ''
if (am_data['SOURCE']['OS_INSTALL_DATE']) {
let instdate_ts = tell_time(am_data['SOURCE']['OS_INSTALL_DATE'])
am_data['SOURCE']['OS_INSTALL_ISO_DATE'] = instdate_ts['UTC']['ISO8601']
}
ts = tell_time()
am_data['ITAM']['ENDTIME'] = ts['UTC']['ISO8601']
am_data['ITAM']['ELAPSED_SEC'] = (Number(ts['UTC']['EPOCH']) - starttime)
console.log ("\nRuntime: " + Math.round(am_data['ITAM']['ELAPSED_SEC']) + ' seconds')
try {
fs.writeFileSync(path.join(am_data['ITAM']['APP_DIR'], 'skqitam-data.json'), JSON.stringify(am_data, null, 2), 'utf8')
console.log ('Local Copy Saved: ' + path.join(am_data['ITAM']['APP_DIR'], 'skqitam-data.json'))
} catch (e) {
console.log("ERROR: Could not save local copy: " + path.join(am_data['ITAM']['APP_DIR'], 'skqitam-data.json'));
}
iatm_upload_data(am_data)
// ------------ Functions Libraries --------------------//
function rpm_list_to_json(rpm_list) {
let json_obj = []
let lines = rpm_list.split(/\n/)
let rpm_info_regx1 = RegExp(/^(\S+\s\S+)\s+:\s+(\S+.*\S+)\s{3,40}(\S+\s\S+):\s+(\S.*)/)
let rpm_info_regx2 = RegExp(/^(\S.*\S)\s+:\s+(\S.*\S+)\s{3,40}(\S.*\S):\s+(\S.*)/)
let rpm_info_regx3 = RegExp(/^(\S.*\S):\s+(\S.*\S+)\s{3,40}(\S.*\S):\s+(\S.*)/)
let rpm_info_regx4 = RegExp(/^(\S+)\s+:\s+(\S+)\s{3,40}(\S+):\s+(\S.*)/)
let rpm_info_regx5 = RegExp(/^(\S.*\S)\s+:\s+(\S.*)/)
let rpm_info_regx6 = RegExp(/^(\S.*\S):\s+(\S.*)/)
for (l in lines) {
if (lines[l]) {
cmd_rpm_info = 'rpm -qi ' + lines[l]
let rpm_info = childProcess.execSync(cmd_rpm_info, { encoding: 'utf8' })
let rpm_info_lines = rpm_info.split(/\n/)
let pkg = {}
for (rl in rpm_info_lines) {
if (mch = rpm_info_lines[rl].match(rpm_info_regx1)) {
pkg[ mch[1].replace(/\s+/, '') ] = mch[2]
pkg[ mch[3].replace(/\s+/, '') ] = mch[4]
} else if (mch = rpm_info_lines[rl].match(rpm_info_regx2)) {
pkg[ mch[1].replace(/\s+/, '') ] = mch[2]
pkg[ mch[3].replace(/\s+/, '') ] = mch[4]
} else if (mch = rpm_info_lines[rl].match(rpm_info_regx3)) {
pkg[ mch[1].replace(/\s+/, '') ] = mch[2]
pkg[ mch[3].replace(/\s+/, '') ] = mch[4]
} else if (mch = rpm_info_lines[rl].match(rpm_info_regx4)) {
pkg[ mch[1].replace(/\s+/, '') ] = mch[2]
pkg[ mch[3].replace(/\s+/, '') ] = mch[4]
} else if (mch = rpm_info_lines[rl].match(rpm_info_regx5)) {
pkg[ mch[1].replace(/\s+/, '') ] = mch[2]
} else if (mch = rpm_info_lines[rl].match(rpm_info_regx6)) {
pkg[ mch[1].replace(/\s+/, '') ] = mch[2]
} else {
// console.log('WARNING: Could not parse RPM package info for ' + lines[l] + "\n" + rpm_info_lines[rl])
}
}
json_obj.push(pkg)
}
}
return json_obj
}
function dpkg_list_to_json(dpkg_list) {
let json_obj = {}
let lines = dpkg_list.split(/\n/)
let dpkg_list_regx = RegExp(/(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S.*)/)
let pkg_info_regx = RegExp(/^(.*):\s+(.*)/)
// let pkg_name_regx = RegExp(/^(.*):(.*)/)
process.stdout.write('Processing Apt Pkgs: [0/' + lines.length + '] 0 % ')
let apt_history = apt_history_to_json()
for (pkg_name in apt_history) {
json_obj[pkg_name] = {}
json_obj[pkg_name]['DPKG_LIST'] = {}
json_obj[pkg_name]['APT_HISTORY'] = apt_history[pkg_name]
json_obj[pkg_name]['APT_CACHE'] = {}
}
// Collect Package Meta Data
for (l in lines) {
if ( (l % 10) == 0 ) {
process.stdout.clearLine();
process.stdout.cursorTo(0);
process.stdout.write('Processing Apt Pkgs: [' + l + '/' + lines.length + '] ' + Math.round(100 * l / Number(lines.length)) + ' % ')
}
if (mch = lines[l].match(dpkg_list_regx)) {
if (mch[1] != "||/") {
let pkg_name_split = String(mch[2]).split(':')
let pkg_name = pkg_name_split[0]
// console.log (JSON.stringify(pkg_name_split))
let pkg = {}
pkg['STATUS'] = mch[1]
pkg['NAME'] = mch[2]
pkg['VERSION'] = mch[3]
pkg['ARCH'] = mch[4]
pkg['DESCRIPTION'] = mch[5]
// console.log (pkg['SW_NAME'])
// console.log(pkg_name)
if (! json_obj.hasOwnProperty(pkg_name)) {
json_obj[pkg_name] = {}
json_obj[pkg_name]['DPKG_LIST'] = {}
json_obj[pkg_name]['APT_HISTORY'] = {}
json_obj[pkg_name]['APT_CACHE'] = {}
}
json_obj[pkg_name]['DPKG_LIST'] = pkg
let cmd_pkg_info = 'apt-cache show ' + pkg['NAME']
try {
let pkg_info_lines = String(childProcess.execSync(cmd_pkg_info, { encoding: 'utf8' })).split(/\n/)
// pkg['APT_CACHE'] = {}
for (pl in pkg_info_lines) {
if (pmch = pkg_info_lines[pl].match(pkg_info_regx)) {
json_obj[pkg_name]['APT_CACHE'][ pmch[1] ] = pmch[2]
}
}
} catch (err) {
console.log ('WARNING: Failed to run: ' + cmd_pkg_info + "\n" + err)
}
// json_obj.push(pkg)
}
}
// console.log(JSON.stringify(pkg, null, 2))
}
// console.log(JSON.stringify(json_obj, null, 2))
return json_obj
// return {}
}
function apt_history_to_json() {
let apt_history_obj = {}
let pkg_list = {}
let apt_history_regx = RegExp(/^(.*):\s+(.*)/)
// Extract Apt Log - /var/log/apt/history.log.*.gz
let cmc_extract_apt_history = 'zcat /var/log/apt/history.log.*.gz > /var/tmp/apt-history.log'
let cmc_append_apt_history = 'cat /var/log/apt/history.log >> /var/tmp/apt-history.log'
try {
childProcess.execSync(cmc_extract_apt_history, { encoding: 'utf8' })
} catch (err) {
console.log('ERROR: Failed to Extract Apt Log History ' + err)
}
try {
childProcess.execSync(cmc_append_apt_history, { encoding: 'utf8' })
let apt_history_log = fs.readFileSync(path.join('/var', 'tmp', 'apt-history.log'), 'utf8').split(/\n/)
for (ahl=0; ahl<apt_history_log.length; ahl++) {
// console.log ('DEBUG: ' + ahl + ' ' + apt_history_log[ahl])
// console.log ('DEBUG: ' + apt_history_log.length)
if (ahmch = apt_history_log[ahl].match(apt_history_regx)) {
// console.log ('DEBUG: ' + ahl + ' ' + apt_history_log[ahl])
if (ahmch[1] == 'Start-Date' ) {
let apt_history_event = {}
// console.log ('DEBUG: ' + ahl + ' ' + apt_history_log[ahl])
while ( (ahmch[1] != 'End-Date') && (ahl < apt_history_log.length)) {
if (ahmch = apt_history_log[ahl++].match(apt_history_regx)) {
// console.log ('DEBUG: ' + ahl++ + ' ' + ahmch[1] + ' ' + ahmch[2])
apt_history_event[ ahmch[1] ] = ahmch[2]
} else {
ahmch = ['NULL']
}
}
// console.log(JSON.stringify(apt_history_event, null, 2))
for (k in Object.keys(apt_history_event)) {
// console.log (Object.keys(apt_history_event)[k])
switch (Object.keys(apt_history_event)[k]) {
case 'Start-Date':
// Do Nothing
break;
case 'End-Date':
// Do Nothing
break;
case 'Commandline':
// Do Nothing
break;
case 'Requested-By':
// Do Nothing
break;
case 'Purge':
// Do Nothing
break;
case 'Install':
pkg_list = apt_history_event[ Object.keys(apt_history_event)[k] ].split('), ')
// console.log(JSON.stringify(pkg_list, null, 2))
for (pkl in pkg_list) {
// console.log ('DEBUG: ' + pkg_list[pkl])
if (pkg_meta1 = String(pkg_list[pkl].replace(/\)$/, '')).split(' (')) {
// console.log('META1' + JSON.stringify(pkg_meta1, null, 2))
if (pkg_meta2 = String(pkg_meta1[0]).split(':')) { // Pkg Name : Arch
// console.log('META2' + JSON.stringify(pkg_meta2, null, 2))
if (! apt_history_obj.hasOwnProperty(pkg_meta2[0])) { apt_history_obj[ pkg_meta2[0] ] = {} }
apt_history_obj[ pkg_meta2[0] ][apt_history_event['Start-Date']] = {}
apt_history_obj[ pkg_meta2[0] ][apt_history_event['Start-Date']]['EVENT'] = Object.keys(apt_history_event)[k]
apt_history_obj[ pkg_meta2[0] ][apt_history_event['Start-Date']]['ARCH'] = pkg_meta2[1]
if (pkg_meta3 = String(pkg_meta1[1]).split(', ')) { // Version, Status
// console.log('META3' + JSON.stringify(pkg_meta3, null, 2))
apt_history_obj[ pkg_meta2[0] ][apt_history_event['Start-Date']]['VERSION'] = pkg_meta3[0]
} else {
console.log("WARNING: META3 MisMatch")
}
} else {
console.log("WARNING: META2 MisMatch")
}
} else {
console.log("WARNING: META1 MisMatch")
}
// if (pkmch = pkg_list[p].match())
}
break;
case 'Remove':
// pkg_list = apt_history_event[ Object.keys(apt_history_event)[k] ].split('), ')
// // console.log(JSON.stringify(pkg_list, null, 2))
// for (pkl in pkg_list) {
// // console.log ('DEBUG: ' + pkg_list[pkl])
// if (pkg_meta1 = String(pkg_list[pkl].replace(/\)$/, '')).split(' (')) {
// // console.log('META1' + JSON.stringify(pkg_meta1, null, 2))
// if (pkg_meta2 = String(pkg_meta1[0]).split(':')) { // Pkg Name : Arch
// // console.log('META2' + JSON.stringify(pkg_meta2, null, 2))
// if (! apt_history_obj.hasOwnProperty(pkg_meta2[0])) { apt_history_obj[ pkg_meta2[0] ] = {} }
// apt_history_obj[ pkg_meta2[0] ][apt_history_event['Start-Date']] = {}
// apt_history_obj[ pkg_meta2[0] ][apt_history_event['Start-Date']]['EVENT'] = Object.keys(apt_history_event)[k]
// apt_history_obj[ pkg_meta2[0] ][apt_history_event['Start-Date']]['ARCH'] = pkg_meta2[1]
//
// if (pkg_meta3 = String(pkg_meta1[1]).split(', ')) { // Version, Status
// // console.log('META3' + JSON.stringify(pkg_meta3, null, 2))
// apt_history_obj[ pkg_meta2[0] ][apt_history_event['Start-Date']]['VERSION'] = pkg_meta3[0]
//
// } else {
// console.log("WARNING: META3 MisMatch")
// }
// } else {
// console.log("WARNING: META2 MisMatch")
// }
//
// } else {
// console.log("WARNING: META1 MisMatch")
// }
// }
break;
case 'Upgrade':
pkg_list = apt_history_event[ Object.keys(apt_history_event)[k] ].split('), ')
// console.log(JSON.stringify(pkg_list, null, 2))
for (pkl in pkg_list) {
// console.log ('DEBUG: ' + pkg_list[pkl])
if (pkg_meta1 = String(pkg_list[pkl].replace(/\)$/, '')).split(' (')) {
// console.log('META1' + JSON.stringify(pkg_meta1, null, 2))
if (pkg_meta2 = String(pkg_meta1[0]).split(':')) { // Pkg Name : Arch
// console.log('META2' + JSON.stringify(pkg_meta2, null, 2))
if (! apt_history_obj.hasOwnProperty(pkg_meta2[0])) { apt_history_obj[ pkg_meta2[0] ] = {} }
apt_history_obj[ pkg_meta2[0] ][apt_history_event['Start-Date']] = {}
apt_history_obj[ pkg_meta2[0] ][apt_history_event['Start-Date']]['EVENT'] = Object.keys(apt_history_event)[k]
apt_history_obj[ pkg_meta2[0] ][apt_history_event['Start-Date']]['ARCH'] = pkg_meta2[1]
if (pkg_meta3 = String(pkg_meta1[1]).split(', ')) { // Version, Status
// console.log('META3' + JSON.stringify(pkg_meta3, null, 2))
apt_history_obj[ pkg_meta2[0] ][apt_history_event['Start-Date']]['VERSION'] = pkg_meta3[0]
} else {
console.log("WARNING: META3 MisMatch")
}
} else {
console.log("WARNING: META2 MisMatch")
}
} else {
console.log("WARNING: META1 MisMatch")
}
}
break;
case 'Reinstall':
pkg_list = apt_history_event[ Object.keys(apt_history_event)[k] ].split('), ')
// console.log(JSON.stringify(pkg_list, null, 2))
for (pkl in pkg_list) {
// console.log ('DEBUG: ' + pkg_list[pkl])
if (pkg_meta1 = String(pkg_list[pkl].replace(/\)$/, '')).split(' (')) {
// console.log('META1' + JSON.stringify(pkg_meta1, null, 2))
if (pkg_meta2 = String(pkg_meta1[0]).split(':')) { // Pkg Name : Arch
// console.log('META2' + JSON.stringify(pkg_meta2, null, 2))
if (! apt_history_obj.hasOwnProperty(pkg_meta2[0])) { apt_history_obj[ pkg_meta2[0] ] = {} }
apt_history_obj[ pkg_meta2[0] ][apt_history_event['Start-Date']] = {}
apt_history_obj[ pkg_meta2[0] ][apt_history_event['Start-Date']]['EVENT'] = Object.keys(apt_history_event)[k]
apt_history_obj[ pkg_meta2[0] ][apt_history_event['Start-Date']]['ARCH'] = pkg_meta2[1]
if (pkg_meta3 = String(pkg_meta1[1]).split(', ')) { // Version, Status
// console.log('META3' + JSON.stringify(pkg_meta3, null, 2))
apt_history_obj[ pkg_meta2[0] ][apt_history_event['Start-Date']]['VERSION'] = pkg_meta3[0]
} else {
console.log("WARNING: META3 MisMatch")
}
} else {
console.log("WARNING: META2 MisMatch")
}
} else {
console.log("WARNING: META1 MisMatch")
}
}
break;
case 'Error':
// Do Nothing
break;
default:
console.log('WARNING: Unknown apt-history Event: ' + Object.keys(apt_history_event)[k])
}
}
}
}
}
} catch (err) {
console.log('ERROR: Failed to Append Apt Log History ' + err)
process.exit(1)
}
// console.log (JSON.stringify(apt_history_obj, null, 2))
return apt_history_obj
}
function iatm_upload_data(data) {
// console.log (JSON.stringify(data, null, 2))
itam_upload_url = process['CONFIG']['GLOBAL']['SERVER_BASE_URL'] + '/api/upload/?ITAM_DATA=' + encodeURIComponent(JSON.stringify(data))
console.log ('Data Payload: ' + itam_upload_url.length + ' Bytes')
request({
url: itam_upload_url
}, function (error, response, body) {
if (!error && response.statusCode === 200) {
// console.log (JSON.stringify(data, null, 2))
// console.log (encodeURIComponent(JSON.stringify(data)))
if (body) {
console.log ('Data Upload: SUCCESS')
} else {
console.log ('Data Upload: FAILED')
}
} else {
console.log ('ERROR: Failed to upload data' )
}
})
}
function it_am_init() {
let config = {}
// Admin Permission Test
if (running_as_admin() && !process['CONFIG']['RUN_AS_ADMIN']) {
console.log('WARNING: Cannot run with Administrative Permissions')
process.exit(1)
}
// Static Parameters
config['OS'] = {}
config['OS']['ARCH'] = process.arch
config['OS']['ENDIAN'] = os.endianness()
config['OS']['PLATFORM'] = os.platform()
config['OS']['RELEASE'] = os.release()
config['OS']['TYPE'] = os.type()
config['OS']['EOL'] = os.EOL
config['OS']['PATHSEP'] = path.sep
config['PROC'] = {}
config['PROC']['PID'] = process.pid
config['PROC']['RUN_DIR'] = process['CONFIG']['GLOBAL']['RUN_DIR']
config['PROC']['CWD'] = process.cwd()
config['PROC']['ARCH'] = process.arch
config['PROC']['PLATFORM'] = process.platform
config['PROC']['VERSIONS'] = process.versions
config['PROC']['ARGV'] = process.argv
config['PROC']['EXECPATH'] = process.execPath
//config['PROC']['ENV'] = process.env
config['HOST'] = {}
config['HOST']['HOSTNAME'] = os.hostname()
config['HOST']['DNSNAME'] = ''
config['HOST']['HOST_ID'] = ''
config['HOST']['HW'] = {}
config['HOST']['HW']['CPUS'] = os.cpus()
for (c in config['HOST']['HW']['CPUS']) { delete config['HOST']['HW']['CPUS'][c]['times'] }
if(!config['HOST']['HW'].hasOwnProperty('CPU_CORES')) {
config['HOST']['HW']['CPU_CORES'] = config['HOST']['HW']['CPUS'].length
config['HOST']['HW']['CPU_MODEL'] = config['HOST']['HW']['CPUS'][0]['model']
}
config['HOST']['HW']['MEMORY_BYTES'] = os.totalmem()
config['HOST']['HW']['NETWORK'] = os.networkInterfaces()
config['HOST']['NETWORK'] = {}
config['HOST']['NETWORK']['IP_ADDR'] = {}
config['HOST']['NETWORK']['IP_ADDR']['IPv4'] = []
config['HOST']['NETWORK']['IP_ADDR']['IPv6'] = []
for (n in config['HOST']['HW']['NETWORK']) {
for (i in config['HOST']['HW']['NETWORK'][n]) {
if (!config['HOST']['HW']['NETWORK'][n][i]['internal'] && !config['HOST']['HW']['NETWORK'][n][i]['netmask'].match('ffff:ffff')) {
config['HOST']['NETWORK']['IP_ADDR'][ config['HOST']['HW']['NETWORK'][n][i]["family"] ].push(config['HOST']['HW']['NETWORK'][n][i]["address"])
}
}
}
if (config['PROC']['PLATFORM'] == 'linux' || config['PROC']['PLATFORM'] == 'darwin') {
for (ip in config['HOST']['NETWORK']['IP_ADDR']['IPv4']) {
try {
let cmd_host_lookup = 'host ' + config['HOST']['NETWORK']['IP_ADDR']['IPv4'][ip]
// console.log ('DEBUG HOST: ' + cmd_host_lookup )
let host_regx = RegExp(/domain name pointer\s+(\S+)\.\S+$/)
let host_lines = String(childProcess.execSync(cmd_host_lookup, { encoding: 'utf8' })).split(/\n/)
if (hmch = host_lines[0].match(host_regx)) {
config['HOST']['DNSNAME'] = hmch[1].replace(/\.\S+$/, '')
}
} catch (e) {
try {
let cmd_nslookup = 'nslookup ' + config['HOST']['NETWORK']['IP_ADDR']['IPv4'][ip]
console.log ('DEBUG NSLOOKUP: ' + cmd_nslookup )
let nslookup_regx = RegExp(/nslookup_regx\s+(\S+)\.\S+$/)
let nslookup_lines = String(childProcess.execSync(cmd_nslookup, { encoding: 'utf8' })).split(/\n/)
if (hmch = nslookup_lines[3].match(nslookup_regx)) {
config['HOST']['DNSNAME'] = hmch[1].replace(/\.\S+$/, '')
}
} catch (e) {
// Do Nothing
}
}
}
} else if (config['PROC']['PLATFORM'] == 'win32') {
// Figure out Windows NSLOOKUP
}
config['USER'] = {}
config['USER']['USERNAME'] = os.userInfo().username
config['USER']['HOMEDIR'] = os.userInfo().homedir
// Load ABL App Configuration Parameters
config['PACKAGE'] = JSON.parse(fs.readFileSync(path.join(config['PROC']['RUN_DIR'],'package.json'), 'utf8'))
get_abl_id(config)
// console.log (JSON.stringify(config, null, 2))
return config
}
exports.it_am_init = it_am_init
function running_as_admin() { // Code Source: ABL Rolecall (http://appliedbitlogistics.io/)
let admin_perms = false
switch(os.platform()) {
case "linux":
if (os.userInfo['username'] == 'root' || os.userInfo()['uid'] == 0) {
admin_perms = true
}
break
case "darwin":
if (os.userInfo()['username'] == 'root' || os.userInfo()['uid'] == 0) {
admin_perms = true
}
break
case "win32":
let isAdmin = require('is-admin')
isAdmin().then(elevated => {
if (elevated) {
admin_perms = true
}
})
break
}
return admin_perms
}
function get_abl_id (cfg) { // Code Source: ABL Rolecall (http://appliedbitlogistics.io/)
// ABL ID
let abl_id = {}
switch (cfg['OS']['PLATFORM']) {
case 'linux':
// console.log(JSON.stringify(cfg, null, 2))
let mac = ''
for (nic in cfg['HOST']['HW']['NETWORK']) {
// console.log("NIC: " + nic)
if (!mac && nic != 'lo') {
mac = cfg['HOST']['HW']['NETWORK'][nic][0]['mac']
}
}
try {
fs.accessSync('/var/lib/dbus/machine-id', fs.constants.R_OK);
idbase = mac + fs.readFileSync('/var/lib/dbus/machine-id', 'utf8').replace(/\n$/, '')
cfg['HOST']['HOST_ID'] = crypto.createHash('sha256').update(idbase).digest('hex')
// console.log("ID BASE: " + idbase)
} catch (err) {
try {
fs.accessSync('/etc/machine-id', fs.constants.R_OK);
idbase = mac + fs.readFileSync('/etc/machine-id', 'utf8').replace(/\n$/, '')
cfg['HOST']['HOST_ID'] = crypto.createHash('sha256').update(idbase).digest('hex')
// console.log("ID BASE: " + idbase)
} catch (err) {
console.error('ERROR: Missing: /var/lib/dbus/machine-id and /etc/machine-id');
// CENTOS 6 ID - or other old os without a hardware ID
if (! cfg['HOST'].hasOwnProperty('HOST_ID') || !cfg['HOST']['HOST_ID']) {
cfg['HOST']['HOST_ID'] = crypto.createHash('sha256').update(String(process['CONFIG']['FILE']['UUID']).replace(/\n$/, '')).digest('hex')
}
}
}
try {
fs.accessSync('/etc/lsb-release', fs.constants.R_OK);
let line = fs.readFileSync('/etc/lsb-release', 'utf8').split(/\n/)
for (l in line) {
if (mch = line[l].match(/^DISTRIB_ID=(.*)$/)) {
cfg['OS']['DISTRO'] = mch[1].replace(/\"/g, '')
} else if (mch = line[l].match(/^DISTRIB_RELEASE=(.*)$/)) {
cfg['OS']['DISTRO_VERSION'] = mch[1].replace(/\"/g, '')
}
}
} catch (err) {
// console.log('WARNING: Missing /etc/lsb-release')
}
try {
fs.accessSync('/etc/os-release', fs.constants.R_OK);
let line = fs.readFileSync('/etc/os-release', 'utf8').split(/\n/)
for (l in line) {
if (mch = line[l].match(/^NAME=(.*)$/)) {
cfg['OS']['DISTRO'] = mch[1].replace(/\"/g, '')
} else if (mch = line[l].match(/^VERSION_ID=(.*)$/)) {
cfg['OS']['DISTRO_VERSION'] = mch[1].replace(/\"/g, '')
}
}
} catch(err) {
// console.log('WARNING: Missing /etc/os-release')
}
// /etc/debian
try {
fs.accessSync('/etc/centos-release', fs.constants.R_OK);
let rx = /(.*)\srelease\s([0-9\.]+)\s(.*)/
let cr = fs.readFileSync('/etc/centos-release', 'utf8').match(rx)
// console.log (JSON.stringify(cr, null, 2))
cfg['OS']['DISTRO'] = cr[1]
cfg['OS']['DISTRO_VERSION'] = cr[2]
} catch(err) {
// console.log('WARNING: Missing /etc/os-release')
}
break;
case 'darwin':
let osxcmd = 'ioreg -rd1 -c IOPlatformExpertDevice | grep IOPlatformUUID|cut -d ' + "'" + '"' + "'" + ' -f4'
cfg['HOST']['HOST_ID'] = crypto.createHash('sha256').update(childProcess.execSync(osxcmd, { encoding: 'utf8' }).replace(/\n$/, '')).digest('hex')
osxcmd = 'sw_vers -productName'
cfg['OS']['DISTRO'] = childProcess.execSync(osxcmd, { encoding: 'utf8' }).replace(/\n$/, '')
osxcmd = 'sw_vers -productVersion'
cfg['OS']['DISTRO_VERSION'] = childProcess.execSync(osxcmd, { encoding: 'utf8' }).replace(/\n$/, '')
break;
case 'win32':
let wincmd = 'Reg Query "HKLM\\SOFTWARE\\Microsoft\\Cryptography"'
let machid = childProcess.execSync(wincmd, { encoding: 'utf8' })
let line = machid.split(/\n/)
for (l in line) {
if (mch = line[l].match(/MachineGuid\s+\S+\s+(\S+)/)) {
let mchguid = mch[1]
let sncmd = 'wmic bios get serialnumber'
try {
let sn = String(childProcess.execSync(sncmd, { encoding: 'utf8' })).replace(/\r\r\n/g, ' ').replace(/SerialNumber\s+/, '').replace(/\s+$/, '')
// console.log ("ID BASE: " + mchguid + sn)
cfg['HOST']['HOST_ID'] = crypto.createHash('sha256').update(mchguid + sn).digest('hex')
} catch (err) {
console.log('ERROR: Could not run: ' + sncmd + "\n" + err)
process.exit(1)
}
}
}
wincmd = 'systeminfo'
line = childProcess.execSync(wincmd, { encoding: 'utf8' }).split(/\r\n/)
for (l in line) {
if (mch = line[l].match(/^OS\s+Name:\s+(.*\S)/)) {
cfg['OS']['DISTRO'] = mch[1]
} else if (mch = line[l].match(/^OS\s+Version:\s+(\S+)/)) {
cfg['OS']['DISTRO_VERSION'] = mch[1]
}
}
break;
default:
}
return abl_id
}
function sysprof2json (sysproftxt) {
let sysprof_json = {}
if (sysproftxt) {
let lines = sysproftxt.split(/\n/)
let lv = -1
let level = 0
let regx_level = []
let regx_keyval = []
let lkey = []
regx_level[0] = RegExp(/^(\S.*):$/)
regx_level[1] = RegExp(/^\s{4}(\S.*):$/)
regx_level[2] = RegExp(/^\s{6}(\S.*):$/)
regx_level[3] = RegExp(/^\s{8}(\S.*):$/)
regx_level[4] = RegExp(/^\s{10}(\S.*):$/)
regx_level[5] = RegExp(/^\s{14}(\S.*):$/)
regx_keyval[0] = RegExp(/^(\S.*\S):\s+(\S+.*)$/)
regx_keyval[1] = RegExp(/^\s{4}(\S.*\S):\s+(\S+.*)$/)
regx_keyval[2] = RegExp(/^\s{6}(\S.*\S):\s+(\S+.*)$/)
regx_keyval[3] = RegExp(/^\s{8}(\S.*\S):\s+(\S+.*)$/)
regx_keyval[4] = RegExp(/^\s{10}(\S.*\S):\s+(\S+.*)$/)
regx_keyval[5] = RegExp(/^\s{14}(\S.*\S):\s+(\S+.*)$/)
for (l in lines) {
if (mch = lines[l].match(regx_level[0])) {
lkey[0] = mch[1]
level = 0
sysprof_json[ lkey[0] ] = {}
} else if (mch = lines[l].match(regx_level[1])) {
lkey[1] = mch[1]
level = 1
sysprof_json[ lkey[0] ][ lkey[1] ] = {}
} else if (mch = lines[l].match(regx_level[2])) {
lkey[2] = mch[1]
level = 2
sysprof_json[ lkey[0] ][ lkey[1] ][ lkey[2] ] = {}
} else if (mch = lines[l].match(regx_level[3])) {
lkey[3] = mch[1]
level = 3
sysprof_json[ lkey[0] ][ lkey[1] ][ lkey[2] ][ lkey[3] ] = {}
} else if (mch = lines[l].match(regx_level[4])) {
lkey[4] = mch[1]
level = 4
sysprof_json[ lkey[0] ][ lkey[1] ][ lkey[2] ][ lkey[3] ][ lkey[4] ] = {}
} else if (mch = lines[l].match(regx_level[5])) {
lkey[5] = mch[1]
level = 5
sysprof_json[ lkey[0] ][ lkey[1] ][ lkey[2] ][ lkey[3] ][ lkey[4] ][ lkey[5] ] = {}
} else if (mch = lines[l].match(regx_keyval[0])) {
sysprof_json[ mch[1] ] = mch[2]
} else if (mch = lines[l].match(regx_keyval[1])) {
sysprof_json[ lkey[0 ] ][ mch[1] ] = mch[2]
} else if (mch = lines[l].match(regx_keyval[2])) {
sysprof_json[ lkey[0] ][ lkey[1] ][ mch[1] ] = mch[2]
} else if (mch = lines[l].match(regx_keyval[3])) {
sysprof_json[ lkey[0] ][ lkey[1] ][ lkey[2] ][ mch[1] ] = mch[2]
} else if (mch = lines[l].match(regx_keyval[4])) {
sysprof_json[ lkey[0] ][ lkey[1] ][ lkey[2] ][ lkey[3] ][ mch[1] ] = mch[2]
} else if (mch = lines[l].match(regx_keyval[5])) {
sysprof_json[ lkey[0] ][ lkey[1] ][ lkey[2] ][ lkey[2] ][ lkey[4] ][ mch[1] ] = mch[2]
}
}
}
return sysprof_json
}
function tell_time (ts) {
var timeds = {} // Time Data Structure
var time = new Date()
if(ts) {
if(String(ts).match(/^\d+$/)) {
time = new Date(ts*1000)
} else {
time = new Date(ts)
}
}
timeds['LOCAL'] = {}
timeds['LOCAL']['YYYY'] = '' + time.getFullYear() + ''
if(time.getMonth() < 9) {
timeds['LOCAL']['MM'] = '0' + (time.getMonth() + 1) + ''
}else {
timeds['LOCAL']['MM'] = '' + (time.getMonth() + 1) + ''
}
if(time.getDate() <= 9) {
timeds['LOCAL']['DD'] = '0' + time.getDate() + ''
}else {
timeds['LOCAL']['DD'] = '' + time.getDate() + ''
}
if(time.getHours() <= 9) {
timeds['LOCAL']['hh'] = '0' + time.getHours() + '';
}else {
timeds['LOCAL']['hh'] = '' + time.getHours() + '';
}
if(time.getMinutes() <= 9) {
timeds['LOCAL']['mm'] = '0' + time.getMinutes() + '';
}else {
timeds['LOCAL']['mm'] = '' + time.getMinutes() + '';
}
if(time.getSeconds() <= 9) {
timeds['LOCAL']['ss'] = '0' + time.getSeconds() + '';
}else {
timeds['LOCAL']['ss'] = '' + time.getSeconds() + '';
}
timeds['LOCAL']['ms'] = time.getMilliseconds()
timeds['LOCAL']['YYYY-MM-DD'] = timeds['LOCAL']['YYYY'] + '-' + timeds['LOCAL']['MM'] + '-' + timeds['LOCAL']['DD'];
timeds['LOCAL']['hh:mm:ss'] = timeds['LOCAL']['hh'] + ':' + timeds['LOCAL']['mm'] + ':' + timeds['LOCAL']['ss'];
timeds['LOCAL']['YYYY-MM-DD hh:mm:ss'] = timeds['LOCAL']['YYYY-MM-DD'] + ' ' + timeds['LOCAL']['hh:mm:ss'];
timeds['LOCAL']['DOW'] = time.getDay();
// timeds['LOCAL']['DOY'] = '';
timeds['LOCAL']['WOY'] = get_week_of_year(time)[1] + 1;
timeds['LOCAL']['TZONE'] = time.getTimezoneOffset()/60;
timeds['UTC'] = {};
timeds['UTC']['YYYY'] = '' + time.getUTCFullYear() + '';
if(time.getUTCMonth() < 9) {
timeds['UTC']['MM'] = '0' + (time.getUTCMonth() + 1) + '';
}else {
timeds['UTC']['MM'] = '' + (time.getUTCMonth() + 1) + '';
}
if(time.getUTCDate() <= 9) {
timeds['UTC']['DD'] = '0' + time.getUTCDate() + '';
}else {
timeds['UTC']['DD'] = '' + time.getUTCDate() + '';
}
if(time.getUTCHours() <= 9) {
timeds['UTC']['hh'] = '0' + time.getUTCHours() + '';
}else {
timeds['UTC']['hh'] = '' + time.getUTCHours() + '';
}
if(time.getUTCMinutes() <= 9) {
timeds['UTC']['mm'] = '0' + time.getUTCMinutes() + '';
}else {
timeds['UTC']['mm'] = '' + time.getUTCMinutes() + '';
}
if(time.getUTCSeconds() <= 9) {
timeds['UTC']['ss'] = '0' + time.getUTCSeconds() + '';
}else {
timeds['UTC']['ss'] = '' + time.getUTCSeconds() + '';
}
timeds['UTC']['ms'] = time.getUTCMilliseconds()
timeds['UTC']['YYYY-MM-DD'] = timeds['UTC']['YYYY'] + '-' + timeds['UTC']['MM'] + '-' + timeds['UTC']['DD'];
timeds['UTC']['hh:mm:ss'] = timeds['UTC']['hh'] + ':' + timeds['UTC']['mm'] + ':' + timeds['UTC']['ss'];
timeds['UTC']['YYYY-MM-DD hh:mm:ss'] = timeds['UTC']['YYYY-MM-DD'] + ' ' + timeds['UTC']['hh:mm:ss'];
timeds['UTC']['ISO8601'] = timeds['UTC']['YYYY-MM-DD'] + 'T' + timeds['UTC']['hh:mm:ss'] + 'Z'
timeds['UTC']['TZONE'] = 0;
timeds['UTC']['DOW'] = time.getUTCDay();
timeds['UTC']['WOY'] = get_week_of_year(time)[1];
timeds['UTC']['EPOCH_MS'] = time.getTime();
timeds['UTC']['EPOCH'] = timeds['UTC']['EPOCH_MS']/1000;
timeds['UTC']['TIMESTAMP'] = Math.round(timeds['UTC']['EPOCH'])
timeds['UTC']['DOW'] = time.getUTCDay();
//timeds['UTC']['WOY'] = get_week_of_year(Date(timeds['UTC']['TIMESTAMP']))[1];
timeds['LOCAL']['TIMESTAMP'] = timeds['UTC']['TIMESTAMP'] - timeds['LOCAL']['TZONE'] * 3600
return timeds;
}
exports.tell_time = tell_time
function get_week_of_year( d ) {
https://stackoverflow.com/questions/6117814/get-week-of-year-in-javascript-like-in-php
// Copy date so don't modify original
d = new Date(Date.UTC(d.getFullYear(), d.getMonth(), d.getDate()));
// Set to nearest Thursday: current date + 4 - current day number
// Make Sunday's day number 7
d.setUTCDate(d.getUTCDate() + 4 - (d.getUTCDay()||7));
// Get first day of year
var yearStart = new Date(Date.UTC(d.getUTCFullYear(),0,1));
// Calculate full weeks to nearest Thursday
var weekNo = String(Math.ceil(( ( (d - yearStart) / 86400000) + 1)/7));
// Return array of year and week number
if (weekNo <= 9) {
weekNo = '0' + weekNo
}
return [d.getUTCFullYear(), weekNo]
}
exports.get_week_of_year = get_week_of_year