Skip to content

Commit

Permalink
Merge pull request #223 from open-amt-cloud-toolkit/mosquitto2
Browse files Browse the repository at this point in the history
feat(mqtt): adds event logging to mps
  • Loading branch information
rsdmike committed Jun 14, 2021
2 parents 61cc964 + 8561867 commit 51e07d0
Show file tree
Hide file tree
Showing 16 changed files with 357 additions and 2 deletions.
1 change: 1 addition & 0 deletions .mpsrc
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"web_admin_password": "",
"vault_address": "http://localhost:8200",
"vault_token": "myroot",
"mqtt_address": "",
"secrets_path": "secret/data/",
"cert_format" : "file",
"data_path" : "../private/data.json",
Expand Down
8 changes: 7 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { parseValue } from './utils/parseEnvValue'
import rc from 'rc'
import { Environment } from './utils/Environment'
import { DeviceDb } from './db/device'
import { MqttProvider } from './utils/mqttProvider'
import { AuthDbProvider } from './utils/AuthDbProvider'
try {
// To merge ENV variables. consider after lowercasing ENV since our config keys are lowercase
Expand All @@ -44,6 +45,10 @@ try {
log.silly(`Updated config... ${JSON.stringify(config, null, 2)}`)
Environment.Config = config

// MQTT Connection
const mqtt: MqttProvider = new MqttProvider(config)
mqtt.connectBroker()

// DB initialization
const deviceDb = new DeviceDb()
const db: IDbProvider = new AuthDbProvider(new SecretManagerService(config, log), deviceDb, log, config)
Expand All @@ -54,6 +59,7 @@ try {
process.on(signal, () => {
console.log('signal received :', signal)
deviceDb.clearInstanceStatus(Environment.Config.instance_name)
mqtt.endBroker()
if (signal !== 'exit') {
setTimeout(() => process.exit(), 1000)
}
Expand Down Expand Up @@ -96,7 +102,7 @@ try {

log.info('certs loaded..')

const mps = new MPSMicroservice(config, db, certs)
const mps = new MPSMicroservice(config, db, certs, mqtt)
mps.start()
}
} catch (error) {
Expand Down
1 change: 1 addition & 0 deletions src/models/Config.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export interface configType {
cert_format: string
vault_address?: string
vault_token?: string
mqtt_address?: string
debug_level: number
jwt_secret: string
jwt_issuer: string
Expand Down
8 changes: 8 additions & 0 deletions src/models/models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,11 @@ export interface AMTCredential {
amtuser: string
amtpass: string
}
export type eventType = 'request' | 'success' | 'fail'
export interface OpenAMTEvent {
type: eventType
message: string
methods: string[]
guid: string
timestamp: number
}
6 changes: 5 additions & 1 deletion src/mpsMicroservice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import { IDbProvider } from './models/IDbProvider'
import { DeviceDb } from './db/device'
import { Device } from './models/models'
import { Environment } from './utils/Environment'
import { MqttProvider } from './utils/mqttProvider'

export class MPSMicroservice {
mpsserver: MPSServer
webserver: WebServer
Expand All @@ -20,12 +22,14 @@ export class MPSMicroservice {
mpsComputerList = {}
db: IDbProvider
deviceDb: DeviceDb
constructor (config: configType, db: IDbProvider, certs: certificatesType) {
mqtt: MqttProvider
constructor (config: configType, db: IDbProvider, certs: certificatesType, mqtt?: MqttProvider) {
try {
this.config = config
this.debugLevel = config.debug_level
this.db = db
this.certs = certs
this.mqtt = mqtt
} catch (e) {
log.error(`Exception in MPS Microservice: ${e}`)
}
Expand Down
6 changes: 6 additions & 0 deletions src/routes/amt/auditLog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,20 +26,26 @@ export async function auditLog (req: Request, res: Response): Promise<void> {
const amtstack = req.amtFactory.getAmtStack(guid, amtPort, cred[0], cred[1], 0)
const startIndex: number = queryParams.startIndex == null ? 0 : queryParams.startIndex >= 1 ? queryParams.startIndex : 0

req.mpsService.mqtt.publishEvent('request', ['AMT_AuditLog'], 'Audit Log Requested', guid)

amtstack.GetAuditLogChunks(startIndex, (stack, responses, status) => {
stack.wsman.comm.socket.sendchannelclose()
if (status === 200) {
req.mpsService.mqtt.publishEvent('success', ['AMT_AuditLog'], 'Sent Audit Log', guid)
res.status(200).json(responses).end()
} else {
log.error(`Power Action failed during GETAudit log for guid : ${guid}.`)
req.mpsService.mqtt.publishEvent('fail', ['AMT_AuditLog'], 'Audit Log Not Found', guid)
res.status(404).json(ErrorResponse(status, `Power Action failed during GETAudit log for guid : ${guid}.`)).end()
}
})
} else {
req.mpsService.mqtt.publishEvent('fail', ['AMT_AuditLog'], 'Device Not Found', guid)
res.status(404).json(ErrorResponse(404, `guid : ${guid}`, 'device')).end()
}
} catch (error) {
log.error(`Exception in AMT AuditLog : ${error}`)
req.mpsService.mqtt.publishEvent('fail', ['AMT_AuditLog'], 'Internal Service Error')
res.status(500).json(ErrorResponse(500, 'Request failed during AMT AuditLog.')).end()
}
}
6 changes: 6 additions & 0 deletions src/routes/amt/eventLog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,26 @@ export async function eventLog (req: Request, res: Response): Promise<void> {
if (ciraconn && ciraconn.readyState === 'open') {
const cred = await req.mpsService.db.getAmtPassword(guid)
const amtstack = req.amtFactory.getAmtStack(guid, amtPort, cred[0], cred[1], 0)
req.mpsService.mqtt.publishEvent('request', ['AMT_EventLog'], 'Event Log Requested', guid)

amtstack.GetMessageLog(function (stack, responses, tag, status) {
stack.wsman.comm.socket.sendchannelclose()
if (status === 200) {
req.mpsService.mqtt.publishEvent('success', ['AMT_EventLog'], 'Sent Event Log', guid)
res.status(200).json(responses).end()
} else {
log.error(`Failed during GET MessageLog guid : ${guid}.`)
req.mpsService.mqtt.publishEvent('fail', ['AMT_EventLog'], 'Failed to Get Event Log', guid)
res.status(status).json(ErrorResponse(status, `Failed during GET MessageLog guid : ${guid}.`)).end()
}
})
} else {
req.mpsService.mqtt.publishEvent('fail', ['AMT_EventLog'], 'Device Not Found', guid)
res.status(404).json(ErrorResponse(404, `guid : ${guid}`, 'device')).end()
}
} catch (error) {
log.error(`Exception in AMT EventLog: ${error}`)
req.mpsService.mqtt.publishEvent('fail', ['AMT_EventLog'], 'Internal Server Error')
res.status(500).json(ErrorResponse(500, 'Request failed during AMT EventLog.')).end()
}
}
6 changes: 6 additions & 0 deletions src/routes/amt/generalSettings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,26 @@ export async function generalSettings (req: Request, res: Response): Promise<voi
if (ciraconn) {
const cred = await req.mpsService.db.getAmtPassword(guid)
const amtstack = req.amtFactory.getAmtStack(guid, amtPort, cred[0], cred[1], 0)
req.mpsService.mqtt.publishEvent('request', ['AMT_GeneralSettings'], 'General Settings Requested', guid)

await amtstack.Get('AMT_GeneralSettings', (obj, name, response, status) => {
obj.wsman.comm.socket.sendchannelclose()
if (status === 200) {
req.mpsService.mqtt.publishEvent('success', ['AMT_GeneralSettings'], 'Sent General Settings', guid)
res.status(200).json(response).end()
} else {
log.error(`Request failed during GET AMT_GeneralSettings for guid : ${guid}.`)
req.mpsService.mqtt.publishEvent('fail', ['AMT_GeneralSettings'], 'Failed to Get General Settings', guid)
res.status(status).json(ErrorResponse(status, `Request failed during GET AMT_GeneralSettings for guid : ${guid}.`)).end()
}
}, 0, 1)
} else {
req.mpsService.mqtt.publishEvent('fail', ['AMT_GeneralSettings'], 'Device Not Found', guid)
res.status(404).json(ErrorResponse(404, `guid : ${guid}`, 'device')).end()
}
} catch (error) {
log.error(`Exception in AMT GeneralSettings: ${error}`)
req.mpsService.mqtt.publishEvent('fail', ['AMT_GeneralSettings'], 'Internal Server Error')
res.status(500).json(ErrorResponse(500, 'Request failed during AMT GeneralSettings.')).end()
}
}
5 changes: 5 additions & 0 deletions src/routes/amt/getAMTFeatures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ export async function getAMTFeatures (req: Request, res: Response): Promise<void
const guid = req.params.guid
const ciraconn = req.mpsService.mpsserver.ciraConnections[guid]
if (ciraconn && ciraconn.readyState === 'open') {
req.mpsService.mqtt.publishEvent('request', ['AMT_GetFeatures'], 'Get AMT Features Requested', guid)

const cred = await req.mpsService.db.getAmtPassword(guid)
const amtstack = req.amtFactory.getAmtStack(guid, amtPort, cred[0], cred[1], 0)
const wsmanResponse = await AMTFeatures.getAMTFeatures(amtstack, payload)
Expand All @@ -39,16 +41,19 @@ export async function getAMTFeatures (req: Request, res: Response): Promise<void
const value = optServiceRes[AMTFeaturesConst.AMT_USER_CONSENT]
userConsent = Object.keys(UserConsentOptions).find(key => UserConsentOptions[key] === value)

req.mpsService.mqtt.publishEvent('success', ['AMT_GetFeatures'], 'Get AMT Features', guid)
res.status(200).json({ userConsent: userConsent, redirection: redir, KVM: kvm, SOL: sol, IDER: ider }).end()
}
} else {
req.mpsService.mqtt.publishEvent('fail', ['AMT_GetFeatures'], 'Device Not Found', guid)
res.status(404).json(ErrorResponse(404, `guid : ${guid}`, 'device')).end()
}
} catch (error) {
log.error(`Exception in get AMT Features: ${error}`)
if (error instanceof MPSValidationError) {
return res.status(error.status || 400).json(ErrorResponse(error.status || 400, error.message)).end()
} else {
req.mpsService.mqtt.publishEvent('fail', ['AMT_GetFeatures'], 'Internal Server Error')
return res.status(500).json(ErrorResponse(500, 'Request failed during get AMT Features.')).end()
}
}
Expand Down
6 changes: 6 additions & 0 deletions src/routes/amt/hardwareInfo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,23 +16,29 @@ export async function hardwareInfo (req: Request, res: Response): Promise<void>
if (ciraconn && ciraconn.readyState === 'open') {
const cred = await req.mpsService.db.getAmtPassword(guid)
const amtstack = req.amtFactory.getAmtStack(guid, amtPort, cred[0], cred[1], 0)
req.mpsService.mqtt.publishEvent('request', ['AMT_HardwareInfo'], 'Hardware Information Requested', guid)

amtstack.BatchEnum('', ['*CIM_ComputerSystemPackage',
'CIM_SystemPackaging', '*CIM_Chassis', 'CIM_Chip', '*CIM_Card', '*CIM_BIOSElement',
'CIM_Processor', 'CIM_PhysicalMemory', 'CIM_MediaAccessDevice', 'CIM_PhysicalPackage'],
(stack, name, responses, status) => {
stack.wsman.comm.socket.sendchannelclose()
if (status !== 200) {
log.error(`Request failed during AMTHardware Information BatchEnum Exec for guid : ${guid}.`)
req.mpsService.mqtt.publishEvent('fail', ['AMT_HardwareInfo'], 'Failed to Get Hardware Information', guid)
return res.status(status).json(ErrorResponse(status, `Request failed during AMTHardware Information BatchEnum Exec for guid : ${guid}.`)).end()
} else {
req.mpsService.mqtt.publishEvent('success', ['AMT_HardwareInfo'], 'Sent Hardware Information', guid)
res.status(status).json(responses).end()
}
})
} else {
req.mpsService.mqtt.publishEvent('fail', ['AMT_HardwareInfo'], 'Device Not Found', guid)
res.status(404).json(ErrorResponse(404, `guid : ${guid}`, 'device')).end()
}
} catch (error) {
log.error(`Exception in AMT HardwareInformation : ${error}`)
req.mpsService.mqtt.publishEvent('fail', ['AMT_HardwareInfo'], 'Interanl Server Error')
res.status(500).json(ErrorResponse(500, 'Request failed during AMTHardware Information.')).end()
}
}
3 changes: 3 additions & 0 deletions src/routes/amt/powerAction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,12 @@ export async function powerAction (req: Request, res: Response): Promise<void> {
const amtstack = req.amtFactory.getAmtStack(guid, amtPort, cred[0], cred[1], 0)
getBootData(guid, payload.action, payload.useSOL, amtstack, req, res)
} else {
req.mpsService.mqtt.publishEvent('fail', ['AMT_BootSettingData'], 'Device Not Found', guid)
res.status(404).json(ErrorResponse(404, `guid : ${guid}`, 'device')).end()
}
} catch (error) {
log.error(`Exception in Power action : ${error}`)
req.mpsService.mqtt.publishEvent('fail', ['AMT_BootSettingData'], 'Internal Server Error')
res.status(500).json(ErrorResponse(500, 'Request failed during AMT Power action execution.')).end()
}
}
Expand Down Expand Up @@ -171,6 +173,7 @@ function powerStateChange (uuid, action, amtstack, req, res): void {
stack.wsman.comm.socket.sendchannelclose()
if (status === 200) {
// log.info(`Power state change request successful for guid : ${uuid}`);
req.mpsService.mqtt.publishEvent('success', ['AMT_BootSettingData'], 'Sent Power Action ' + action, uuid)
res.status(200).json(response).end()
} else {
log.error(`Power state change request failed for guid : ${uuid}`)
Expand Down
5 changes: 5 additions & 0 deletions src/routes/amt/powerCapabilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ export async function powerCapabilities (req: Request, res: Response): Promise<v
if (ciraconn && ciraconn.readyState === 'open') {
const cred = await req.mpsService.db.getAmtPassword(guid)
const amtstack = req.amtFactory.getAmtStack(guid, amtPort, cred[0], cred[1], 0)
req.mpsService.mqtt.publishEvent('request', ['AMT_BootCapabilities'], 'Power Capabilities Requested', guid)

getVersion(amtstack, req, res, (responses, res) => {
const versionData = responses
amtstack.Get('AMT_BootCapabilities', async (stack, name, responses, status) => {
Expand All @@ -25,14 +27,17 @@ export async function powerCapabilities (req: Request, res: Response): Promise<v
}
// console.log("AMT_BootCapabilities info of " + uuid + " sent.");
const powerCap = await bootCapabilities(versionData, responses.Body)
req.mpsService.mqtt.publishEvent('success', ['AMT_BootCapabilities'], 'Sent Power Capabilities', guid)
return res.status(200).json(powerCap).end()
}, 0, 1)
})
} else {
req.mpsService.mqtt.publishEvent('fail', ['AMT_BootCapabilities'], 'Device Not Found', guid)
res.status(404).json(ErrorResponse(404, `guid : ${guid}`, 'device')).end()
}
} catch (error) {
log.error(`Exception in AMT PowerCapabilities : ${error}`)
req.mpsService.mqtt.publishEvent('fail', ['AMT_BootCapabilities'], 'Internal Server Error')
res.status(500).json(ErrorResponse(500, 'Request failed during AMT PowerCapabilities.')).end()
}
}
Expand Down
6 changes: 6 additions & 0 deletions src/routes/amt/powerState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,26 @@ export async function powerState (req: Request, res: Response): Promise<void> {
if (ciraconn && ciraconn.readyState === 'open') {
const cred = await req.mpsService.db.getAmtPassword(guid)
const amtstack = req.amtFactory.getAmtStack(guid, amtPort, cred[0], cred[1], 0)
req.mpsService.mqtt.publishEvent('request', ['AMT_PowerState'], 'Power State Requested', guid)

amtstack.Enum('CIM_ServiceAvailableToElement', (stack, name, responses, status) => {
stack.wsman.comm.socket.sendchannelclose()
if (status !== 200) {
req.mpsService.mqtt.publishEvent('fail', ['AMT_PowerState'], 'Failed to Get Power State', guid)
log.error(`Request failed during powerstate fetch for guid : ${guid}.`)
return res.status(status).json(ErrorResponse(status, `Request failed during powerstate fetch for guid : ${guid}.`)).end()
} else {
req.mpsService.mqtt.publishEvent('success', ['AMT_PowerState'], 'Sent Power State', guid)
res.status(200).json({ powerstate: responses[0].PowerState }).end()
}
})
} else {
req.mpsService.mqtt.publishEvent('fail', ['AMT_PowerState'], 'Device Not Found', guid)
res.status(404).json(ErrorResponse(404, `guid : ${guid}`, 'device')).end()
}
} catch (error) {
log.error(`Exception in Power state : ${error}`)
req.mpsService.mqtt.publishEvent('fail', ['AMT_PowerState'], 'Internal Server Error')
return res.status(500).json(ErrorResponse(500, 'Request failed during powerstate fetch.')).end()
}
}
6 changes: 6 additions & 0 deletions src/routes/amt/setAMTFeatures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,23 @@ export async function setAMTFeatures (req: Request, res: Response): Promise<void
if (ciraconn && ciraconn.readyState === 'open') {
const cred = await req.mpsService.db.getAmtPassword(guid)
const amtstack = req.amtFactory.getAmtStack(guid, amtPort, cred[0], cred[1], 0)
req.mpsService.mqtt.publishEvent('request', 'AMT_SetFeatures', 'Set AMT Features Requested', guid)

await AMTFeatures.setAMTFeatures(amtstack, payload)
amtstack.wsman.comm.socket.sendchannelclose()

req.mpsService.mqtt.publishEvent('success', 'AMT_SetFeatures', 'Set AMT Features', guid)
res.status(200).json({ status: 'Updated AMT Features' }).end()
} else {
req.mpsService.mqtt.publishEvent('fail', 'AMT_SetFeatures', 'Device Not Found', guid)
res.status(404).json(ErrorResponse(404, `guid : ${guid}`, 'device')).end()
}
} catch (error) {
log.error(`Exception in set AMT Features: ${error}`)
if (error instanceof MPSValidationError) {
res.status(error.status || 400).json(ErrorResponse(error.status || 400, error.message)).end()
} else {
req.mpsService.mqtt.publishEvent('fail', 'AMT_SetFeatures', 'Internal Server Error')
res.status(500).json(ErrorResponse(500, 'Request failed during set AMT Features.')).end()
}
}
Expand Down
Loading

0 comments on commit 51e07d0

Please sign in to comment.