From a3e2cb36b0cbceb025753c7aeae0553de043b968 Mon Sep 17 00:00:00 2001 From: Jannik Schönartz Date: Sun, 7 Apr 2019 23:42:35 +0000 Subject: [server/backends] Add infoblox ipxe ip selection stuff --- server/api/backends.js | 12 ++++++- server/api/registration.js | 82 ++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 90 insertions(+), 4 deletions(-) (limited to 'server/api') diff --git a/server/api/backends.js b/server/api/backends.js index 838467a..e92999a 100644 --- a/server/api/backends.js +++ b/server/api/backends.js @@ -9,6 +9,16 @@ var noAuthRouter = decorateApp(express.Router()) // GET requests. +// TODO DELETE +noAuthRouter.getAsync('/:id/test', async (req, res) => { + const id = req.params.id + const backend = await db.backend.findOne({ where: { id: id } }) + const externalBackends = new ExternalBackends() + const instance = externalBackends.getInstance(backend.type) + const result = await instance.test(backend.credentials) + res.send(result) +}) + /* * @return: Returns a list of all backends saved in the db. */ @@ -31,7 +41,7 @@ router.getAsync('/:id', async (req, res) => { const instance = externalBackends.getInstance(backend.type) let credentialTypes = instance.getCredentials() - // Get the ids of the 'password' fieldds + // Get the ids of the 'password' fields let censorIds = [] credentialTypes.forEach(function f (element) { if (element.type === 'switch') { diff --git a/server/api/registration.js b/server/api/registration.js index e3ca350..dc18bf1 100644 --- a/server/api/registration.js +++ b/server/api/registration.js @@ -115,9 +115,8 @@ noAuthRouter.postAsync('/clients', async (req, res) => { let ipxe = req.body.ipxe if (typeof ipxe === 'string') ipxe = true - - if (!client.type) client.type = 'CLIENT' - if (!client.name) client.name = client.type + '_' + client.uuid + let automatic = req.body.automatic + if (typeof automatic === 'string' && automatic === 'true') automatic = true // If the client already exists return the configloader ipxe script. const clientDb = await db.client.findOne({ where: { uuid: client.uuid } }) @@ -126,6 +125,55 @@ noAuthRouter.postAsync('/clients', async (req, res) => { else return res.send({ error: 'CLIENT_ALREADY_EXISTS', msg: 'A client with the provided UUID does already exist.' }) } + if (!client.type) client.type = 'CLIENT' + + // DHCP network stuff: + + // TODO: Multiip / backend problems + // * Multiple backends possible ? multiple dhcp's? if set ip differentiates which one should we save in the bas db? + // * Only servers have multiple ips? No multi leased ips possible? + + // If there is no ip, we don't need DHCP checks. + // Only the first ip address is checked! client.networks[0] + if (client.networks.length >= 1) { + const network = client.networks[0] + // Get the dhcp backend. Only one dhcp backend can exist else -> conflict. + const dhcp = await backendHelper.getDhcp() + if (dhcp) { + if (automatic) { + // Set the name of the client if it's not set + if (!client.name) client.name = client.type + '_' + client.uuid + const setIp = await dhcp.instance.setIp(dhcp.backend.credentials, network.ip, network.mac, client.name, true) + + // Check for errors. + if (!setIp.error) { + // Client ip set successfully + client.networks[0].ip = setIp.ip + } else { + log({ category: 'ERROR_DHCP', description: `[${dhcp.backend.id}] Error setting ip ${network.ip} for mac ${network.mac}. Error: ${setIp.msg}` }) + } + } else if (network.dhcp) { + // If networks.dhcp is set the user already choose the ip and we have to set it now. + if (!client.name) return res.send(buildNameClientIpxeMenu(client)) + const setIp = await dhcp.instance.setIp(dhcp.backend.credentials, network.dhcp, network.mac, client.name) + // Check for errors. + if (setIp.error) { + // Setting the client ip failed + log({ category: 'ERROR_DHCP', description: `[${dhcp.backend.id}] Error setting ip ${network.ip} for mac ${network.mac}. Error: ${setIp.msg}` }) + } else { + // Client ip set successfully + client.networks[0].ip = network.dhcp + } + } else { + // If not check if the client has a leased ipv4 address. + const ipCheck = await dhcp.instance.checkIp(dhcp.backend.credentials, network.ip) + // Build ipxe and return + if (ipxe && ipCheck && !ipCheck.error) return res.send(buildSelectIpIpxeMenu(client, ipCheck)) + else if (!ipxe && ipCheck && !ipCheck.error) return res.send({ client: client, ipList: ipCheck }) + } + } + } + // Client does not exist. if (!client.parents) client.parents = [] // TODO: Save all IPs? Maybe only primary ip? @@ -356,6 +404,34 @@ function buildIpxeMenu (id, name, groups, parents) { return script } +function buildSelectIpIpxeMenu (client, ipList) { + const basUrl = 'https://' + url + let script = '#!ipxe\r\n' + let menuscript = '' + script += ':start\r\n' + script += 'menu Select the ip for this client:\r\n' + for (let index in ipList) { + const ip = ipList[index] + client.networks[0].dhcp = ip + script += 'item ' + ip + ' ' + ip + '\r\n' + menuscript += ':' + ip + '\r\n' + 'params\r\nparam client ' + JSON.stringify(client) + '\r\n' + menuscript += 'chain --replace ' + basUrl + '/api/registration/clients##params\r\n\r\n' + } + script += `choose target && goto \${target}\r\n\r\n` + script += menuscript + return script +} + +function buildNameClientIpxeMenu (client) { + const basUrl = 'https://' + url + let script = '#!ipxe\r\n' + script += '\r\necho Enter client name\r\nread clientname\r\nparams\r\n' + client.name = `\${clientname}` + script += 'param client ' + JSON.stringify(client) + '\r\n' + script += 'chain --replace ' + basUrl + '/api/registration/clients##params\r\n\r\n' + return script +} + function toAscii (string) { string = string.replace('ü', 'ue') string = string.replace('ö', 'oe') -- cgit v1.2.3-55-g7522