From 0873cc0b67a5e3103f1efea8f3b6a18b116b0751 Mon Sep 17 00:00:00 2001 From: Jannik Schönartz Date: Sun, 31 Mar 2019 13:50:50 +0000 Subject: [server/registration] Performance improvements & add automatic registration with custom name Manual registration now sends the client as json idoit: Add server bug fixes shell: Fix building pcbios ipxe version eslint fixes --- server/api/ipxeentries.js | 2 +- server/api/registration.js | 7 +++-- server/ipxe/bash_scripts/addServer.sh | 2 +- server/ipxe/default.ipxe | 9 ++++--- server/ipxe/registration.ipxe | 21 ++++++++++----- server/lib/external-backends/backendhelper.js | 21 ++++++++++----- .../external-backends/backends/idoit-backend.js | 30 ++++++---------------- server/lib/httpresponse.js | 6 ++--- server/lib/iphelper.js | 2 ++ server/lib/shell.js | 5 +++- 10 files changed, 56 insertions(+), 49 deletions(-) diff --git a/server/api/ipxeentries.js b/server/api/ipxeentries.js index 25cfd21..d646f53 100644 --- a/server/api/ipxeentries.js +++ b/server/api/ipxeentries.js @@ -14,7 +14,7 @@ router.getAsync('', async (req, res) => { }) router.getAsync('/:id', async (req, res) => { - const entry = await db.entry.findOne({ where: { id: req.params.id }}) + const entry = await db.entry.findOne({ where: { id: req.params.id } }) if (entry) res.status(200).send(entry) else res.status(404).end() }) diff --git a/server/api/registration.js b/server/api/registration.js index 20e8618..0a9a4cb 100644 --- a/server/api/registration.js +++ b/server/api/registration.js @@ -136,7 +136,6 @@ noAuthRouter.postAsync('/clients', async (req, res) => { client.id = newClient.id // Add groups to the client. - // if (client.parents.length === 0) client.parents = await ipHelper.getGroups(client.network.ip) if (client.parents.length === 0) client.parents = await ipHelper.getGroups(client.networks[0].ip) client.parents.forEach(pid => { newClient.addGroup(pid) }) log({ category: 'CLIENT_REGISTRATION', description: 'Client added successfully.', clientId: newClient.id }) @@ -338,9 +337,9 @@ function buildIpxeMenu (id, name, groups, parents) { // Add client menu script += 'item select Add client to ' + toAscii(name) + '\r\n' - menuscript += `:select\r\necho Enter client name\r\nread clientname\r\nparams\r\nparam name \${clientname}\r\n` - menuscript += 'param id ' + id + `\r\nparam mac \${net0/mac}\r\nparam uuid \${uuid}\r\nparam ip \${net0/ip}\r\n` - menuscript += 'chain --replace ' + basUrl + '/api/registration/add##params\r\n\r\n' + menuscript += `:select\r\necho Enter client name\r\nread clientname\r\nparams\r\n` + menuscript += `param client { "name": "\${clientname}", "type": "CLIENT", "uuid": "\${uuid}", "purpose": "Pool PC", "networks": [{ "ip": "\${net0/ip}", "mac": "\${net0/mac}" }] }\r\n` + menuscript += 'chain --replace ' + basUrl + '/api/registration/clients##params\r\n\r\n' // Goto start menu if (id !== '0') { diff --git a/server/ipxe/bash_scripts/addServer.sh b/server/ipxe/bash_scripts/addServer.sh index 69088bf..9ef8aa9 100755 --- a/server/ipxe/bash_scripts/addServer.sh +++ b/server/ipxe/bash_scripts/addServer.sh @@ -75,7 +75,7 @@ json_data() { "parents": [$rack], "type": "SERVER", "name": "$hostname", - "uuid": "$(dmidecode -q -s system-uuid | grep -v '^#' | head -n 1 | tr '[a-z]' '[A-Z]')", + "uuid": "$(dmidecode -q -s system-uuid | grep -v '^#' | head -n 1 | tr 'a-z' 'A-Z')", "networks": [ $(parse_mgmt "$hostname"), $(parse_ips "$hostname" "$interface") diff --git a/server/ipxe/default.ipxe b/server/ipxe/default.ipxe index 689f4f1..0be460a 100644 --- a/server/ipxe/default.ipxe +++ b/server/ipxe/default.ipxe @@ -5,12 +5,13 @@ menu Default Script: item bwlehrpool bwLehrpool item bwlehrpool_efi bwLehrpool_efi item bwlehrpool_tpm bwLehrpool_tpm -item reg Registration -item sh [Shell] +item --key r registration Registration +item --key s sh [Shell] choose target && goto ${target} :bwlehrpool -chain --replace http://132.230.4.2/tftp/ipxelinux.0 +#chain --replace http://132.230.4.2/tftp/ipxelinux.0 +chain --replace http://132.230.4.2/boot/ipxe :bwlehrpool_efi #chain --replace http://132.230.8.192/tftp/snponly.efi || shell @@ -20,7 +21,7 @@ chain --replace http://132.230.8.197/tftp/snponly.efi || shell kernel http://132.230.4.6/tbk/kernel-neu.sb.efi boot -:reg +:registration set crosscert http://ca.ipxe.org/auto/ chain --replace https://bas.intra.uni-freiburg.de/api/ipxe/load/registration || goto start diff --git a/server/ipxe/registration.ipxe b/server/ipxe/registration.ipxe index 53f4b01..505d72f 100644 --- a/server/ipxe/registration.ipxe +++ b/server/ipxe/registration.ipxe @@ -9,15 +9,16 @@ set crosscert http://ca.ipxe.org/auto/ :start menu Initializing client registration -item --key a automatic Automatic registration +item --key a automatic Automatic Registration +item --key c customname Automatic Registration (Custom Name) +item --key m manual Manual Registration item --key k key Replace Secure Boot Keys -item --key m manual Manual registration item --key l localboot Localboot item --key r reboot Reboot item --key p poweroff Power Off item --key s sh [Shell] item --key u update Reload Menufile -choose --default automatic --timeout 15000 target && goto ${target} || goto automatic +choose --default automatic --timeout 25000 target && goto ${target} || goto automatic :localboot exit0 || @@ -28,10 +29,15 @@ goto start params param ipxe true param client { "type": "CLIENT", "uuid": "${uuid}", "purpose": "Pool PC", "networks": [{ "ip": "${net0/ip}", "mac": "${net0/mac}" }] } -chain https://bas.intra.uni-freiburg.de/api/registration##params +chain https://bas.intra.uni-freiburg.de/api/registration/clients##params -:key -chain -ar http://132.230.4.6/tbk/ReplaceKeysWithOwnKeys.efi +:customname +echo Enter client name +read clientname +params +param ipxe true +param client { "name": "${clientname}", "type": "CLIENT", "uuid": "${uuid}", "purpose": "Pool PC", "networks": [{ "ip": "${net0/ip}", "mac": "${net0/mac}" }] } +chain https://bas.intra.uni-freiburg.de/api/registration/clients##params :manual params @@ -39,6 +45,9 @@ param id 0 chain https://bas.intra.uni-freiburg.de/api/registration/group##params || goto start +:key +chain -ar http://132.230.4.6/tbk/ReplaceKeysWithOwnKeys.efi + :reboot reboot diff --git a/server/lib/external-backends/backendhelper.js b/server/lib/external-backends/backendhelper.js index 6892f7c..a088074 100644 --- a/server/lib/external-backends/backendhelper.js +++ b/server/lib/external-backends/backendhelper.js @@ -8,18 +8,18 @@ module.exports = { addClient, updateClient, deleteClients, uploadFiles } async function addClient (client) { // Get all backends and call addClient for each instance. - var backends = await db.backend.findAll({ include: ['mappedGroups', 'mappedClients'] }) + const backends = await db.backend.findAll({ include: [{ association: 'mappedGroups', where: { id: client.parents }, required: false }] }) var result = [] - for (var b in backends) { - var backend = backends[b] + for (let b in backends) { + const backend = backends[b] const ba = new ExternalBackends() const instance = ba.getInstance(backend.type) var tmpClient = JSON.parse(JSON.stringify(client)) // Convert the parent group ids to the external backend parentIds. If multiple -> conflict if (client.parents) { - const elements = backend.mappedGroups.filter(x => client.parents.includes(x.id)) + const elements = backend.mappedGroups if (elements.length > 1) { // Conflict occured! const conflict = await db.conflict.create({ description: 'Multiple parents found' }) @@ -35,12 +35,14 @@ async function addClient (client) { } let addClient = await instance.addClient(backend.credentials, tmpClient) + addClient.backendId = backend.id if (addClient.succes) { // If the object was created we need to make the objectid / external id mapping. const clientDb = await db.client.findOne({ where: { id: client.id } }) backend.addMappedClients(clientDb, { through: { externalId: addClient.id, externalType: addClient.type } }) } + if (addClient.error && addClient.error !== 'NOT_IMPLEMENTED_EXCEPTION') log({ category: 'BACKEND_ERROR', description: `[${addClient.backendId}] ${addClient.error}: ${addClient.message}`, clientId: client.id }) result.push(addClient) } @@ -49,7 +51,12 @@ async function addClient (client) { async function updateClient (client) { // Get all backends and call addClient for each instance. - const backends = await db.backend.findAll({ include: ['mappedGroups', 'mappedClients'] }) + const backends = await db.backend.findAll({ + include: [ + { association: 'mappedGroups', where: { id: client.parents }, required: false }, + { association: 'mappedClients', where: { id: client.id }, required: false } + ] + }) let result = [] for (let b in backends) { @@ -59,12 +66,12 @@ async function updateClient (client) { var tmpClient = JSON.parse(JSON.stringify(client)) // Get the external clientid. - var exid = backend.mappedClients.find(y => y.id === parseInt(client.id)) + const exid = backend.mappedClients[0] if (exid) tmpClient.id = exid.backend_x_client.externalId // Convert the parent group ids to the external backend parentIds. If multiple -> conflict if (client.parents) { - const elements = backend.mappedGroups.filter(x => client.parents.includes(x.id)) + const elements = backend.mappedGroups if (elements.length > 1) { // Conflict occured! const conflict = await db.conflict.create({ description: 'Multiple parents found' }) diff --git a/server/lib/external-backends/backends/idoit-backend.js b/server/lib/external-backends/backends/idoit-backend.js index c76b6bf..601c9f9 100644 --- a/server/lib/external-backends/backends/idoit-backend.js +++ b/server/lib/external-backends/backends/idoit-backend.js @@ -185,7 +185,7 @@ class IdoitBackend extends ExternalBackends { if (client.formfactor) params.categories.C__CATG__FORMFACTOR = { 'data': { 'formfactor': client.formfactor, 'rackunits': client.formfactor.rackunits } } // Rack segmentation - if (client.location.bay) { + if (client.location.bay !== undefined && client.location.bay !== null) { // Get all assigned objects of the rack (parentid) to check for existing rack segments at slot position. const rackobjectsBody = this.getBody('cmdb.category.read', { 'apikey': c.apikey, 'object': client.parentId, 'objID': client.parentId, 'category': 'C__CATG__OBJECT' }, 'get_rack_objects') const rackobjects = await this.axiosRequest(c.url, [rackobjectsBody], headers) @@ -218,8 +218,8 @@ class IdoitBackend extends ExternalBackends { 'categories': { 'C__CATS__CHASSIS': { 'data': { - 'front_x': 4, - 'front_y': 2, + 'front_x': 2, + 'front_y': 1, 'rear_x': 0, 'rear_y': 0 } @@ -231,7 +231,7 @@ class IdoitBackend extends ExternalBackends { 'from_x': 0, 'to_x': 0, 'from_y': 0, - 'to_y': 1 + 'to_y': 0 }, { 'title': 'Bay 2', @@ -239,23 +239,7 @@ class IdoitBackend extends ExternalBackends { 'from_x': 1, 'to_x': 1, 'from_y': 0, - 'to_y': 1 - }, - { - 'title': 'Bay 3', - 'insertion': 'front', - 'from_x': 2, - 'to_x': 2, - 'from_y': 0, - 'to_y': 1 - }, - { - 'title': 'Bay 4', - 'insertion': 'front', - 'from_x': 3, - 'to_x': 3, - 'from_y': 0, - 'to_y': 1 + 'to_y': 0 } ], 'C__CATG__LOCATION': { @@ -273,6 +257,7 @@ class IdoitBackend extends ExternalBackends { const createSegment = await this.axiosRequest(c.url, [createSegmentParam], headers) chassisId = createSegment[0].result.id + /* // Set the new rack units height. (Needs an extra request, why? I DONT KNOW... idoit...) const setSegmentSizeParams = this.getBody('cmdb.category.save', { 'apikey': c.apikey, 'object': chassisId, @@ -280,6 +265,7 @@ class IdoitBackend extends ExternalBackends { 'category': 'C__CATG__FORMFACTOR', 'data': { 'rackunits': client.formfactor.rackunits } }, 'set_segment_size') await this.axiosRequest(c.url, [setSegmentSizeParams], headers) + */ } } } @@ -331,7 +317,7 @@ class IdoitBackend extends ExternalBackends { // If chassis id is set, assign the object to the chassis bay if (chassisId) { - const bay = client.location.bay + '' + const bay = client.location.bay + 1 + '' const assignToSlotBody = this.getBody('cmdb.category.save', { 'apikey': c.apikey, 'objID': chassisId, 'object': chassisId, diff --git a/server/lib/httpresponse.js b/server/lib/httpresponse.js index ff1010a..29399b2 100644 --- a/server/lib/httpresponse.js +++ b/server/lib/httpresponse.js @@ -6,8 +6,8 @@ response.successBatch = (res, action, type, count, data = {}) => res.status(200) response.notFound = (res, id) => res.status(404).send({ error: 'NOT_FOUND', message: 'ID ' + id + ' does not exist.' }) response.invalidId = (res, zeroAllowed) => res.status(400).send({ error: 'INVALID_ID', message: 'ID has to be an integer' + (zeroAllowed ? '' : ' greater than 0') + '.' }) response.invalidBodyValue = (res, key, rule) => res.status(400).send({ - error: 'BAD_REQUEST', - message: 'JSON body value for key "' + key + '" has to be ' + rule + '.' + error: 'BAD_REQUEST', + message: 'JSON body value for key "' + key + '" has to be ' + rule + '.' }) -module.exports = response \ No newline at end of file +module.exports = response diff --git a/server/lib/iphelper.js b/server/lib/iphelper.js index 8432b01..78929bc 100644 --- a/server/lib/iphelper.js +++ b/server/lib/iphelper.js @@ -8,6 +8,8 @@ async function getGroups (ipString) { const ipInt = toDecimal(ipString) let fittingIpRanges = await db.iprange.findAll({ where: { startIp: { [db.Op.lte]: ipInt }, endIp: { [db.Op.gte]: ipInt } } }) + if (!fittingIpRanges.length) return [] + fittingIpRanges = fittingIpRanges.map(x => x.groupId) // List with all groups mapped so that groups[id] = [parents] diff --git a/server/lib/shell.js b/server/lib/shell.js index fd5151f..7265d09 100644 --- a/server/lib/shell.js +++ b/server/lib/shell.js @@ -18,7 +18,10 @@ module.exports = { var makeCmd = '' // Only one building process can be running. if (!building[ipxeVersion]) { - makeCmd = 'make bin-x86_64-efi/snponly.efi EMBED=' + path.join(__appdir, 'ipxe', 'embedded_' + ipxeVersion + '.ipxe') + ' TRUST=' + path.join(__appdir, 'bin', 'fullchain.pem')// + ' bin/undionly.kpxe' + makeCmd = 'make ' + if (ipxeVersion === 'efi') makeCmd += 'bin-x86_64-efi/snponly.efi ' + makeCmd += 'EMBED=' + path.join(__appdir, 'ipxe', 'embedded_' + ipxeVersion + '.ipxe') + ' TRUST=' + path.join(__appdir, 'bin', 'fullchain.pem')// + ' bin/undionly.kpxe' + updateInProgress(ipxeVersion, true) } else { res.send({ status: 'ALREADY_BUILDING', error: 'Building ' + ipxeVersion + '-iPXE is already in progress.' }) -- cgit v1.2.3-55-g7522