fix(xen-api): correct $type for records from event
XenApi event system returns lowercased types which things difficult, for instance, `Record#set_name_label` methods did not work for some VM because the lib called `vm.set_name_label` instead of `VM.set_name_label`. To work-around this problem, a map of types from lowercased is constructed at connection.
This commit is contained in:
parent
685355c6fb
commit
12a7000e36
@ -7,7 +7,6 @@ import { BaseError } from 'make-error'
|
||||
import { EventEmitter } from 'events'
|
||||
import { fibonacci } from 'iterable-backoff'
|
||||
import {
|
||||
filter,
|
||||
forEach,
|
||||
isArray,
|
||||
isInteger,
|
||||
@ -403,42 +402,55 @@ export class Xapi extends EventEmitter {
|
||||
)
|
||||
}
|
||||
|
||||
connect() {
|
||||
async connect() {
|
||||
const { status } = this
|
||||
|
||||
if (status === CONNECTED) {
|
||||
return Promise.reject(new Error('already connected'))
|
||||
throw new Error('already connected')
|
||||
}
|
||||
|
||||
if (status === CONNECTING) {
|
||||
return Promise.reject(new Error('already connecting'))
|
||||
throw new Error('already connecting')
|
||||
}
|
||||
|
||||
const auth = this._auth
|
||||
if (auth === undefined) {
|
||||
return Promise.reject(new Error('missing credentials'))
|
||||
throw new Error('missing credentials')
|
||||
}
|
||||
|
||||
this._sessionId = CONNECTING
|
||||
|
||||
return this._transportCall('session.login_with_password', [
|
||||
try {
|
||||
const [methods, sessionId] = await Promise.all([
|
||||
this._transportCall('system.listMethods'),
|
||||
this._transportCall('session.login_with_password', [
|
||||
auth.user,
|
||||
auth.password,
|
||||
]).then(
|
||||
async sessionId => {
|
||||
]),
|
||||
])
|
||||
|
||||
// Uses introspection to list available types.
|
||||
const types = (this._types = methods
|
||||
.filter(isGetAllRecordsMethod)
|
||||
.map(method => method.slice(0, method.indexOf('.'))))
|
||||
this._lcToTypes = { __proto__: null }
|
||||
types.forEach(type => {
|
||||
const lcType = type.toLowerCase()
|
||||
if (lcType !== type) {
|
||||
this._lcToTypes[lcType] = type
|
||||
}
|
||||
})
|
||||
|
||||
this._sessionId = sessionId
|
||||
this._pool = (await this.getAllRecords('pool'))[0]
|
||||
|
||||
debug('%s: connected', this._humanId)
|
||||
|
||||
this.emit(CONNECTED)
|
||||
},
|
||||
error => {
|
||||
} catch (error) {
|
||||
this._sessionId = null
|
||||
|
||||
throw error
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
disconnect() {
|
||||
@ -911,7 +923,12 @@ export class Xapi extends EventEmitter {
|
||||
|
||||
_processEvents(events) {
|
||||
forEach(events, event => {
|
||||
const { class: type, ref } = event
|
||||
let type = event.class
|
||||
const lcToTypes = this._lcToTypes
|
||||
if (type in lcToTypes) {
|
||||
type = lcToTypes[type]
|
||||
}
|
||||
const { ref } = event
|
||||
if (event.operation === 'del') {
|
||||
this._removeObject(type, ref)
|
||||
} else {
|
||||
@ -996,17 +1013,11 @@ export class Xapi extends EventEmitter {
|
||||
//
|
||||
// It also has to manually get all objects first.
|
||||
_watchEventsLegacy() {
|
||||
const getAllObjects = () => {
|
||||
return this._sessionCall('system.listMethods').then(methods => {
|
||||
// Uses introspection to determine the methods to use to get
|
||||
// all objects.
|
||||
const getAllRecordsMethods = filter(methods, isGetAllRecordsMethod)
|
||||
|
||||
const getAllObjects = async () => {
|
||||
return Promise.all(
|
||||
map(getAllRecordsMethods, method =>
|
||||
this._sessionCall(method).then(
|
||||
this._types.map(type =>
|
||||
this._sessionCall(`${type}.get_all_records`).then(
|
||||
objects => {
|
||||
const type = method.slice(0, method.indexOf('.')).toLowerCase()
|
||||
forEach(objects, (object, ref) => {
|
||||
this._addObject(type, ref, object)
|
||||
})
|
||||
@ -1019,7 +1030,6 @@ export class Xapi extends EventEmitter {
|
||||
)
|
||||
)
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
const watchEvents = () =>
|
||||
|
Loading…
Reference in New Issue
Block a user