Skip to content

Commit

Permalink
refactor(api): updated event log
Browse files Browse the repository at this point in the history
AB#4552
  • Loading branch information
madhavilosetty-intel committed Dec 14, 2021
1 parent 48f4576 commit f3a04fe
Show file tree
Hide file tree
Showing 18 changed files with 442 additions and 28 deletions.
28 changes: 27 additions & 1 deletion src/amt/ConnectedDevice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import {
CIM_SoftwareIdentity,
CIM_SystemPackaging
} from './models/cim_models'
import { AMT_GeneralSettings, AMT_BootCapabilities, AMT_SetupAndConfigurationService } from './models/amt_models'
import { AMT_GeneralSettings, AMT_BootCapabilities, AMT_SetupAndConfigurationService, AMT_MessageLog } from './models/amt_models'
import { Pull, Response } from './models/common'
import { CancelOptIn_OUTPUT, SendOptInCode_OUTPUT, StartOptIn_OUTPUT } from './models/ips_models'
export class ConnectedDevice {
Expand Down Expand Up @@ -156,6 +156,7 @@ export class ConnectedDevice {
const enumResponse = await this.ciraHandler.Enumerate(this.ciraSocket, xmlRequestBody)
if (enumResponse == null) {
logger.error('failed to get CIM Processor')
return null
}
xmlRequestBody = this.cim.Processor(CIM_Methods.PULL, (this.messageId++).toString(), enumResponse.Envelope.Body.EnumerateResponse.EnumerationContext)
const pullResponse = await this.ciraHandler.Pull<CIM_Processor>(this.ciraSocket, xmlRequestBody)
Expand All @@ -167,6 +168,7 @@ export class ConnectedDevice {
const enumResponse = await this.ciraHandler.Enumerate(this.ciraSocket, xmlRequestBody)
if (enumResponse == null) {
logger.error('failed to get CIM PhysicalMemory')
return null
}
xmlRequestBody = this.cim.PhysicalMemory(CIM_Methods.PULL, (this.messageId++).toString(), enumResponse.Envelope.Body.EnumerateResponse.EnumerationContext)
const pullResponse = await this.ciraHandler.Pull<CIM_PhysicalMemory>(this.ciraSocket, xmlRequestBody)
Expand All @@ -178,6 +180,7 @@ export class ConnectedDevice {
const enumResponse = await this.ciraHandler.Enumerate(this.ciraSocket, xmlRequestBody)
if (enumResponse == null) {
logger.error('failed to get CIM Media Access Device')
return null
}
xmlRequestBody = this.cim.MediaAccessDevice(CIM_Methods.PULL, (this.messageId++).toString(), enumResponse.Envelope.Body.EnumerateResponse.EnumerationContext)
const pullResponse = await this.ciraHandler.Pull<CIM_MediaAccessDevice>(this.ciraSocket, xmlRequestBody)
Expand All @@ -189,6 +192,7 @@ export class ConnectedDevice {
const enumResponse = await this.ciraHandler.Enumerate(this.ciraSocket, xmlRequestBody)
if (enumResponse == null) {
logger.error('failed to get CIM Physical Package')
return null
}
xmlRequestBody = this.cim.PhysicalPackage(CIM_Methods.PULL, (this.messageId++).toString(), enumResponse.Envelope.Body.EnumerateResponse.EnumerationContext)
const pullResponse = await this.ciraHandler.Pull<CIM_PhysicalPackage>(this.ciraSocket, xmlRequestBody)
Expand All @@ -200,6 +204,7 @@ export class ConnectedDevice {
const enumResponse = await this.ciraHandler.Enumerate(this.ciraSocket, xmlRequestBody)
if (enumResponse == null) {
logger.error('failed to get CIM System Packaging')
return null
}
xmlRequestBody = this.cim.SystemPackaging(CIM_Methods.PULL, (this.messageId++).toString(), enumResponse.Envelope.Body.EnumerateResponse.EnumerationContext)
const pullResponse = await this.ciraHandler.Pull<CIM_SystemPackaging>(this.ciraSocket, xmlRequestBody)
Expand All @@ -211,12 +216,33 @@ export class ConnectedDevice {
const enumResponse = await this.ciraHandler.Enumerate(this.ciraSocket, xmlRequestBody)
if (enumResponse == null) {
logger.error('failed to get CIM Chip')
return null
}
xmlRequestBody = this.cim.Chip(CIM_Methods.PULL, (this.messageId++).toString(), enumResponse.Envelope.Body.EnumerateResponse.EnumerationContext)
const pullResponse = await this.ciraHandler.Pull<CIM_Chip>(this.ciraSocket, xmlRequestBody)
return pullResponse
}

async getEventLog (): Promise<Response<AMT_MessageLog>> {
let xmlRequestBody = this.amt.MessageLog(AMT_Methods.POSITION_TO_FIRSTRECORD, (this.messageId++).toString())
console.log('xmlRequestBody :', xmlRequestBody)
const response = await this.ciraHandler.Get<{PositionToFirstRecord_OUTPUT: {
IterationIdentifier: string
ReturnValue: string
}}>(this.ciraSocket, xmlRequestBody)
if (response == null) {
logger.error('failed to get position to first record of AMT_MessageLog')
return null
}
xmlRequestBody = this.amt.MessageLog(AMT_Methods.GET_RECORDS, (this.messageId++).toString(), Number(response.Envelope.Body.PositionToFirstRecord_OUTPUT.IterationIdentifier))
console.log('xmlRequestBody :', xmlRequestBody)
const eventLogs = await this.ciraHandler.Get<AMT_MessageLog>(this.ciraSocket, xmlRequestBody)
if (eventLogs == null) {
logger.error('failed to get AMT_MessageLog')
}
return eventLogs
}

async getAuditLog (startIndex: number): Promise<any> {
const xmlRequestBody = this.amt.AuditLog(AMT_Methods.READ_RECORDS, (this.messageId++).toString(), startIndex)
const pullResponse = await this.ciraHandler.Pull<CIM_SoftwareIdentity>(this.ciraSocket, xmlRequestBody)
Expand Down
16 changes: 16 additions & 0 deletions src/amt/amt/AMT.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,22 @@ export class AMT {
}
}

MessageLog = (method: Methods.GET_RECORDS|Methods.POSITION_TO_FIRSTRECORD, messageId: string, identifier?: number): string => {
let header: string, body: string
switch (method) {
case Methods.POSITION_TO_FIRSTRECORD:
header = this.wsmanMessageCreator.createHeader(Actions.POSITION_TO_FIRSTRECORD, `${this.resourceUriBase}${Classes.AMT_MESSAGE_LOG}`, messageId)
body = `<Body><r:PositionToFirstRecord_INPUT xmlns:r="${this.resourceUriBase}${Classes.AMT_MESSAGE_LOG}" /></Body>`
return this.wsmanMessageCreator.createXml(header, body)
case Methods.GET_RECORDS:
header = this.wsmanMessageCreator.createHeader(Actions.GET_RECORDS, `${this.resourceUriBase}${Classes.AMT_MESSAGE_LOG}`, messageId)
body = `<Body><r:GetRecords_INPUT xmlns:r="${this.resourceUriBase}${Classes.AMT_MESSAGE_LOG}"><r:IterationIdentifier>${identifier}</r:IterationIdentifier><r:MaxReadRecords>390</r:MaxReadRecords></r:GetRecords_INPUT></Body>`
return this.wsmanMessageCreator.createXml(header, body)
default:
throw new Error(WSManErrors.UNSUPPORTED_METHOD)
}
}

BootCapabilities = (method: Methods.GET, messageId: string): string => {
return this.amtSwitch({ method: method, messageId: messageId, class: Classes.AMT_BOOT_CAPABILITIES })
}
Expand Down
2 changes: 2 additions & 0 deletions src/amt/amt/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,6 @@ export enum Actions {
ADD_REMOTE_ACCESS_POLICY_RULE = 'http://intel.com/wbem/wscim/1/amt-schema/1/AMT_RemoteAccessService/AddRemoteAccessPolicyRule',
REQUEST_STATE_CHANGE = 'http://intel.com/wbem/wscim/1/amt-schema/1/AMT_UserInitiatedConnectionService/RequestStateChange',
SET_BOOT_CONFIG_ROLE = 'http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_BootService/SetBootConfigRole',
GET_RECORDS = 'http://intel.com/wbem/wscim/1/amt-schema/1/AMT_MessageLog/GetRecords',
POSITION_TO_FIRSTRECORD = 'http://intel.com/wbem/wscim/1/amt-schema/1/AMT_MessageLog/PositionToFirstRecord'
}
15 changes: 15 additions & 0 deletions src/amt/amt/amt.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,21 @@ describe('AMT Tests', () => {
expect(() => { castedAMTClass.AuditLog(Methods.GET, messageId) }).toThrow(WSManErrors.UNSUPPORTED_METHOD)
})
})
describe('amt_MessageLog Tests', () => {
it('should return a valid amt_MessageLog PositionToFirstRecords wsman message', () => {
const correctResponse = `<?xml version="1.0" encoding="utf-8"?><Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:a="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:w="http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd" xmlns="http://www.w3.org/2003/05/soap-envelope"><Header><a:Action>http://intel.com/wbem/wscim/1/amt-schema/1/AMT_MessageLog/PositionToFirstRecord</a:Action><a:To>/wsman</a:To><w:ResourceURI>http://intel.com/wbem/wscim/1/amt-schema/1/AMT_MessageLog</w:ResourceURI><a:MessageID>${messageId}</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo><w:OperationTimeout>PT60S</w:OperationTimeout></Header><Body><r:PositionToFirstRecord_INPUT xmlns:r="http://intel.com/wbem/wscim/1/amt-schema/1/AMT_MessageLog" /></Body></Envelope>`
const response = amtClass.MessageLog(Methods.POSITION_TO_FIRSTRECORD, messageId)
expect(response).toEqual(correctResponse)
})
it('should return a valid amt_MessageLog GetRecords wsman message', () => {
const correctResponse = `<?xml version="1.0" encoding="utf-8"?><Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:a="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:w="http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd" xmlns="http://www.w3.org/2003/05/soap-envelope"><Header><a:Action>http://intel.com/wbem/wscim/1/amt-schema/1/AMT_MessageLog/GetRecords</a:Action><a:To>/wsman</a:To><w:ResourceURI>http://intel.com/wbem/wscim/1/amt-schema/1/AMT_MessageLog</w:ResourceURI><a:MessageID>${messageId}</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo><w:OperationTimeout>PT60S</w:OperationTimeout></Header><Body><r:GetRecords_INPUT xmlns:r="http://intel.com/wbem/wscim/1/amt-schema/1/AMT_MessageLog"><r:IterationIdentifier>1</r:IterationIdentifier><r:MaxReadRecords>390</r:MaxReadRecords></r:GetRecords_INPUT></Body></Envelope>`
const response = amtClass.MessageLog(Methods.GET_RECORDS, messageId, 1)
expect(response).toEqual(correctResponse)
})
it('should throw error if an unsupported method is called', () => {
expect(() => { castedAMTClass.MessageLog(Methods.GET, messageId) }).toThrow(WSManErrors.UNSUPPORTED_METHOD)
})
})
describe('amt_RedirectionService Tests', () => {
it('should return a valid amt_RedirectionService Get wsman message', () => {
const correctResponse = `<?xml version="1.0" encoding="utf-8"?><Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:a="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:w="http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd" xmlns="http://www.w3.org/2003/05/soap-envelope"><Header><a:Action>http://schemas.xmlsoap.org/ws/2004/09/transfer/Get</a:Action><a:To>/wsman</a:To><w:ResourceURI>http://intel.com/wbem/wscim/1/amt-schema/1/AMT_RedirectionService</w:ResourceURI><a:MessageID>${messageId}</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo><w:OperationTimeout>${operationTimeout}</w:OperationTimeout></Header><Body /></Envelope>`
Expand Down
3 changes: 2 additions & 1 deletion src/amt/amt/classes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,6 @@ export enum Classes {
AMT_REMOTE_ACCESS_SERVICE = 'AMT_RemoteAccessService',
AMT_USER_INITIATED_CONNECTION_SERVICE = 'AMT_UserInitiatedConnectionService',
AMT_BOOT_SETTING_DATA = 'AMT_BootSettingData',
AMT_BOOT_CAPABILITIES = 'AMT_BootCapabilities'
AMT_BOOT_CAPABILITIES = 'AMT_BootCapabilities',
AMT_MESSAGE_LOG = 'AMT_MessageLog'
}
2 changes: 2 additions & 0 deletions src/amt/amt/methods.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,6 @@ export enum Methods {
ADD_REMOTE_ACCESS_POLICY_RULE = 'AddRemoteAccessPolicyRule',
REQUEST_STATE_CHANGE = 'RequestStateChange',
SET_BOOT_CONFIG_ROLE = 'SetBootConfigRole',
GET_RECORDS = 'GetRecords',
POSITION_TO_FIRSTRECORD = 'PositionToFirstRecord'
}
18 changes: 18 additions & 0 deletions src/amt/connectedDevice.test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { CIRASocket } from '../models/models'
import {
amtMessageLog,
cancelOptInResponse,
enumerateResponse,
generalSettings,
positionToFirstRecord,
sendOptInCodeResponse,
serviceAvailableToElement,
startOptInResponse
Expand Down Expand Up @@ -128,3 +130,19 @@ describe('user consent code', () => {
expect(result).toBe(null)
})
})

describe('event log', () => {
it('should get event log ', async () => {
const enumerateSpy = jest.spyOn(device.ciraHandler, 'Get')
enumerateSpy.mockResolvedValueOnce(positionToFirstRecord)
enumerateSpy.mockResolvedValueOnce(amtMessageLog)
const result = await device.getEventLog()
expect(result).toBe(amtMessageLog)
})
it('should return null if fails to get event log', async () => {
const enumerateSpy = jest.spyOn(device.ciraHandler, 'Get')
enumerateSpy.mockResolvedValueOnce(null)
const result = await device.getEventLog()
expect(result).toBe(null)
})
})
19 changes: 18 additions & 1 deletion src/amt/models/amt_models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* SPDX-License-Identifier: Apache-2.0
**********************************************************************/

import { CIM_ManagedElement, CIM_SettingData, CIM_EthernetPort, CIM_BootSettingData, CIM_CredentialManagementService } from './cim_models'
import { CIM_ManagedElement, CIM_SettingData, CIM_EthernetPort, CIM_BootSettingData, CIM_CredentialManagementService, CIM_MessageLog } from './cim_models'

export interface amtAuthenticateObject {
nonce?: number[]
Expand Down Expand Up @@ -217,3 +217,20 @@ export interface AMT_SetupAndConfigurationService extends CIM_CredentialManageme
ZeroTouchConfigurationEnabled: string
}
}

export interface AMT_MessageLog extends CIM_MessageLog {}

// Event Log Records have no header and the record data is combined of 21 binary bytes which could be read as EVENT_DATA
export interface EVENT_DATA {
DeviceAddress?: number
EventSensorType?: number
EventType?: number
EventOffset?: number
EventSourceType?: number
EventSeverity?: number
SensorNumber?: number
Entity?: number
EntityInstance?: number
EventData?: number[]
TimeStamp?: Date
}
26 changes: 26 additions & 0 deletions src/amt/models/cim_models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -314,3 +314,29 @@ export interface CIM_SoftwareIdentity
} & CIM_LogicalElement
>
}
export interface CIM_Log extends CIM_EnabledLogicalElement {
MaxNumberOfRecords: number
CurrentNumberOfRecords: number
OverwritePolicy: number
LogState: number
}

export interface CIM_MessageLog extends CIM_Log {
CreationClassName: string
Capabilities: number[]
CapabilitiesDescriptions: string[]
MaxLogSize: number
SizeOfHeader: number
HeaderFormat: string
MaxRecordSize: number
SizeOfRecordHeader: number
RecordHeaderFormat: string
OtherPolicyDescription: string
TimeWhenOutdated: Date
PercentageNearFull: number
LastChange: number
TimeOfLastChange: Date
RecordLastChanged: number
IsFrozen: boolean
CharacterSet: number
}
41 changes: 41 additions & 0 deletions src/routes/amt/eventLog.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { eventLog } from './eventLog'
import { createSpyObj } from '../../test/helper/jest'
import { devices } from '../../server/mpsserver'
import { ConnectedDevice } from '../../amt/ConnectedDevice'
import { amtMessageLog } from '../../test/helper/wsmanResponses'

describe('event log', () => {
let resSpy
let req
let eventLogSpy
beforeEach(() => {
resSpy = createSpyObj('Response', ['status', 'json', 'end', 'send'])
req = { params: { guid: '4c4c4544-004b-4210-8033-b6c04f504633' } }
resSpy.status.mockReturnThis()
resSpy.json.mockReturnThis()
resSpy.send.mockReturnThis()

devices['4c4c4544-004b-4210-8033-b6c04f504633'] = new ConnectedDevice(null, 'admin', 'P@ssw0rd')
eventLogSpy = jest.spyOn(devices['4c4c4544-004b-4210-8033-b6c04f504633'], 'getEventLog')
})

it('should get version', async () => {
eventLogSpy.mockResolvedValueOnce(amtMessageLog)
await eventLog(req, resSpy)
expect(resSpy.status).toHaveBeenCalledWith(200)
})
it('should get an error with status code 400, when get version is null', async () => {
eventLogSpy.mockResolvedValueOnce(null)
await eventLog(req, resSpy)
expect(resSpy.status).toHaveBeenCalledWith(400)
expect(resSpy.json).toHaveBeenCalledWith({ error: 'Incorrect URI or Bad Request', errorDescription: 'Failed during GET MessageLog guid : 4c4c4544-004b-4210-8033-b6c04f504633.' })
})
it('should get an error with status code 500 for an unexpected exception', async () => {
eventLogSpy.mockImplementation(() => {
throw new Error()
})
await eventLog(req, resSpy)
expect(resSpy.status).toHaveBeenCalledWith(500)
expect(resSpy.json).toHaveBeenCalledWith({ error: 'Internal Server Error', errorDescription: 'Request failed during AMT EventLog.' })
})
})
Loading

0 comments on commit f3a04fe

Please sign in to comment.