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
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
|