summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--server/api/clients.js2
-rw-r--r--server/api/registrations.js38
-rw-r--r--server/lib/external-backends/backendhelper.js58
-rw-r--r--server/lib/external-backends/backends/idoit-backend.js224
-rw-r--r--server/lib/external-backends/index.js28
-rw-r--r--webapp/package-lock.json2
6 files changed, 348 insertions, 4 deletions
diff --git a/server/api/clients.js b/server/api/clients.js
index 3e257e2..0fbb7af 100644
--- a/server/api/clients.js
+++ b/server/api/clients.js
@@ -1,6 +1,7 @@
/* global __appdir */
var path = require('path')
var db = require(path.join(__appdir, 'lib', 'sequelize'))
+const backendHelper = require(path.join(__appdir, 'lib', 'external-backends', 'backendhelper'))
// GET Requests
module.exports.get = {
@@ -42,5 +43,6 @@ module.exports.post = {
// delete clients
delete: function (req, res) {
db.client.destroy({ where: { id: req.body.ids } }).then(count => { res.send({ count }) })
+ backendHelper.deleteClients(req.body.ids)
}
}
diff --git a/server/api/registrations.js b/server/api/registrations.js
index 928ee94..f6a8f87 100644
--- a/server/api/registrations.js
+++ b/server/api/registrations.js
@@ -5,6 +5,7 @@ var router = express.Router()
var noAuthRouter = express.Router()
var db = require(path.join(__appdir, 'lib', 'sequelize'))
const ExternalBackends = require(path.join(__appdir, 'lib', 'external-backends'))
+const backendHelper = require(path.join(__appdir, 'lib', 'external-backends', 'backendhelper'))
// GET requests.
@@ -115,7 +116,7 @@ noAuthRouter.post('/group', (req, res) => {
})
/*
- * Adds the client in the database and set parents if a parent was selected.
+ * Adds the client to the database and set parents if a parent was selected. Calls addClient for all external-backends.
*/
noAuthRouter.post('/add', (req, res) => {
const mac = req.body.mac
@@ -129,10 +130,27 @@ noAuthRouter.post('/add', (req, res) => {
var groupids = []
if (parentId) groupids = [parentId]
getNextHookScript(groupids, 0).then(resId => {
- db.client.create({ name: name, ip: ip, mac: mac, uuid: uuid, registrationState: resId }).then(client => {
+ db.client.create({ name: name, ip: ip, mac: mac, uuid: uuid, registrationState: resId }).then(newClient => {
if (parentId) {
- client.addGroup(parentId)
+ newClient.addGroup(parentId)
}
+
+ // Add the client to the backends.
+ const c = { network: { mac: mac, ip: ip } }
+ if (parentId) c.parentId = parentId
+ if (name) c.title = name
+ else c.title = 'Client_' + uuid
+ backendHelper.addClient(c).then(result => {
+ result.forEach(response => {
+ // If the object was created we need to make the objectid / external id mapping.
+ if (response.success && response.create) {
+ db.backend.findOne({ where: { id: response.backendId }, include: ['mappedClients'] }).then(backend => {
+ backend.addMappedClients(newClient, { through: { externalId: response.id, externalType: response.type } })
+ })
+ }
+ })
+ })
+
res.send('#!ipxe\r\nreboot')
})
})
@@ -141,6 +159,20 @@ noAuthRouter.post('/add', (req, res) => {
})
/*
+ * Adds additional information for the backends of the client in the firstregistration.
+ */
+noAuthRouter.post('/addInfo', (req, res) => {
+ const id = req.body.id
+ const systemModel = req.body.sysmodel
+ const systemManufacturer = req.body.sysmanu
+ const systemSerial = req.body.sysserial
+
+ // Add the client to the backends.
+ backendHelper.addClient({ id: id, system: { model: systemModel, manufacturer: systemManufacturer, serialnumber: systemSerial } })
+ res.send({ status: 'success' })
+})
+
+/*
* Open api method for setting the registration state of a given uuid.
*/
noAuthRouter.post('/:uuid/success', (req, res) => {
diff --git a/server/lib/external-backends/backendhelper.js b/server/lib/external-backends/backendhelper.js
new file mode 100644
index 0000000..0905c48
--- /dev/null
+++ b/server/lib/external-backends/backendhelper.js
@@ -0,0 +1,58 @@
+/* global __appdir */
+const path = require('path')
+const ExternalBackends = require(path.join(__appdir, 'lib', 'external-backends'))
+var db = require(path.join(__appdir, 'lib', 'sequelize'))
+
+module.exports = {
+ addClient: function (client) {
+ // Get all backends and call addClient for each instance.
+ return db.backend.findAll({ include: ['mappedGroups', 'mappedClients'] }).then(backends => {
+ var promises = []
+ var backendids = []
+ backends.forEach(backend => {
+ const ba = new ExternalBackends()
+ const instance = ba.getInstance(backend.type)
+ var tmpClient = JSON.parse(JSON.stringify(client))
+
+ // If the client id is set we need to get the external id.
+ if (client.id) {
+ var exid = backend.mappedClients.find(y => y.id === parseInt(client.id))
+ if (exid) tmpClient.id = exid.backend_x_client.externalId
+ }
+
+ // Convert the parent group id to the external backend parentId.
+ if (client.parentId) {
+ var element = backend.mappedGroups.find(x => x.id === parseInt(client.parentId))
+ if (element) tmpClient['parentId'] = element.backend_x_group.externalId
+ }
+
+ // TODO: Stuff to do if client already exists
+ backendids.push(backend.id)
+ promises.push(instance.addClient(backend.credentials, tmpClient))
+ })
+ return Promise.all(promises).then(result => {
+ result.forEach(object => {
+ object.backendId = backendids.shift()
+ })
+ return result
+ })
+ })
+ },
+
+ deleteClients: function (objectIds) {
+ // Get all backends and call deleteClient for each instance.
+ db.backend.findAll({ include: ['mappedClients'] }).then(backends => {
+ backends.forEach(backend => {
+ const ba = new ExternalBackends()
+ const instance = ba.getInstance(backend.type)
+ var objectsToDelete = []
+ objectIds.forEach(oid => {
+ var element = backend.mappedClients.find(x => x.id === parseInt(oid))
+ if (element) objectsToDelete.push(element.backend_x_client.externalId)
+ })
+ // If there are objects to delete -> delete them.
+ if (objectsToDelete.length > 0) instance.deleteObjects(backend.credentials, objectsToDelete)
+ })
+ })
+ }
+}
diff --git a/server/lib/external-backends/backends/idoit-backend.js b/server/lib/external-backends/backends/idoit-backend.js
index dc5a5d8..fc3bbca 100644
--- a/server/lib/external-backends/backends/idoit-backend.js
+++ b/server/lib/external-backends/backends/idoit-backend.js
@@ -184,6 +184,40 @@ class IdoitBackend extends ExternalBackends {
return result
}
+ async deleteObjects (credentials, objectIds) {
+ var c = this.mapCredentials(credentials)
+ var login = await this.getSession(c)
+ var sid = login.data.result['session-id']
+
+ var config = {
+ timeout: 180000,
+ headers: {
+ 'X-RPC-Auth-Session': sid,
+ 'Content-Type': 'application/json'
+ }
+ }
+
+ var bodies = []
+
+ objectIds.forEach(oid => {
+ // Body
+ bodies.push({
+ 'version': '2.0',
+ 'method': 'cmdb.object.delete',
+ 'params': {
+ 'id': oid,
+ 'apikey': c.apikey,
+ 'language': 'en'
+ },
+ 'id': oid
+ })
+ })
+
+ var requestDelete = await axios.post(c.url, bodies, config)
+
+ return { success: requestDelete.success, data: requestDelete.data }
+ }
+
// Function to use the same session for multiple requests
async getDataTree (credentials, objects) {
var c = this.mapCredentials(credentials)
@@ -278,6 +312,196 @@ class IdoitBackend extends ExternalBackends {
return result
}
+ /*
+ * Adds the client to the backend.
+ *
+ * credentials: <BACKEND_CREDENTIALS>
+ * The client parameters are all optional. If the client has an id the object is not created but the categories of the object.
+ * client: {
+ * id: <CLIENT_ID>, title: <CLIENT_TITLE>, parentId: <PARENT_ID>,
+ * system: { model: <SYSTEM_MODEL>, manufacturer: <SYSTEM_MANUFACTURER>, serialnumber: <SYSTEM_SERIALNUMBER> },
+ * cpu: { model: <CPU_MODEL>, manufacturer: <CPU_MANUFACTURER>, type: <CPU_TYPE>, frequency: <CPU_FREQUENCY>, cores: <CPU_CORES> },
+ * ram: [{ model: <RAM_MODEL>, manufacturer: <RAM_MANUFACTURER>, type: <RAM_TYPE>, capacity: <RAM_CAPACITY>, unit: <RAM_UNIT> }, ...],
+ * storage: {},
+ * network: { mac: <MAC_ADDRESS>, ip: <IP_ADDRESS> }
+ * }
+ */
+ async addClient (credentials, client) {
+ var c = this.mapCredentials(credentials)
+ var login = await this.getSession(c)
+ var sid = login.data.result['session-id']
+
+ var config = {
+ timeout: 180000,
+ headers: {
+ 'X-RPC-Auth-Session': sid,
+ 'Content-Type': 'application/json'
+ }
+ }
+
+ var clientid
+ if (!client.id) {
+ // Create the object in idoIT.
+ var params = {
+ 'type': 'C__OBJTYPE__CLIENT',
+ 'title': client.title,
+ 'apikey': c.apikey,
+ 'language': 'en'
+ }
+
+ var requestCreate = await this.axiosRequest(c.url, 'cmdb.object.create', params, config.headers)
+
+ clientid = requestCreate.data.result.id
+ } else {
+ clientid = client.id
+ }
+
+ var bodies = []
+ if (client.network) {
+ // Update the object. MAC-Address
+ if (client.network.mac) {
+ bodies.push({
+ 'version': '2.0',
+ 'method': 'cmdb.category.create',
+ 'params': {
+ 'objID': clientid,
+ 'category': 'C__CATG__NETWORK_PORT',
+ 'data': {
+ 'category_id': 1,
+ 'mac': client.network.mac
+ },
+ 'apikey': c.apikey,
+ 'language': 'en'
+ },
+ 'id': 'create_mac'
+ })
+ }
+
+ // Update the object. IP-Address
+ if (client.network.ip) {
+ bodies.push({
+ 'version': '2.0',
+ 'method': 'cmdb.category.create',
+ 'params': {
+ 'objID': clientid,
+ 'category': 'C__CATG__IP',
+ 'data': {
+ 'category_id': 1,
+ 'ipv4_address': client.network.ip
+ },
+ 'apikey': c.apikey,
+ 'language': 'en'
+ },
+ 'id': 'create_ip'
+ })
+ }
+ }
+
+ // Update the object. Location
+ if (client.parentId) {
+ bodies.push({
+ 'version': '2.0',
+ 'method': 'cmdb.category.update',
+ 'params': {
+ 'objID': clientid,
+ 'category': 'C__CATG__LOCATION',
+ 'data': {
+ 'parent': client.parentId
+ },
+ 'apikey': c.apikey,
+ 'language': 'en'
+ },
+ 'id': 'update_parent'
+ })
+ }
+
+ if (client.system) {
+ // Update the object.
+ bodies.push({
+ 'version': '2.0',
+ 'method': 'cmdb.category.update',
+ 'params': {
+ 'objID': clientid,
+ 'category': 'C__CATG__MODEL',
+ 'data': {
+ 'manufacturer': client.system.manufacturer,
+ 'title': client.system.model,
+ 'serial': client.system.serialnumber
+ },
+ 'apikey': c.apikey,
+ 'language': 'en'
+ },
+ 'id': 'update_model'
+ })
+ }
+
+ if (client.cpu) {
+ // Update the object.
+ bodies.push({
+ 'version': '2.0',
+ 'method': 'cmdb.category.create',
+ 'params': {
+ 'objID': clientid,
+ 'category': 'C__CATG__CPU',
+ 'data': {
+ 'category_id': 1,
+ 'manufacturer': client.cpu.manufacturer,
+ 'title': client.cpu.model,
+ 'type': client.cpu.type,
+ 'frequency': client.cpu.frequency,
+ 'frequency_unit': 1,
+ 'cores': client.cpu.cores
+ },
+ 'apikey': c.apikey,
+ 'language': 'en'
+ },
+ 'id': 'update_cpu'
+ })
+ }
+
+ if (client.ram) {
+ var counter = 1
+ var mem
+ for (mem in client.ram) {
+ var id = 'create_memory_' + counter
+ // Update the object.
+ bodies.push({
+ 'version': '2.0',
+ 'method': 'cmdb.category.create',
+ 'params': {
+ 'objID': clientid,
+ 'category': 'C__CATG__MEMORY',
+ 'data': {
+ 'title': mem.model,
+ 'manufacturer': mem.manufacturer,
+ 'type': mem.type,
+ 'capacity': mem.capacity,
+ 'unit': mem.unit
+ },
+ 'apikey': c.apikey,
+ 'language': 'en'
+ },
+ 'id': id
+ })
+ counter++
+ }
+ }
+
+ var requestUpdate = await axios.post(c.url, bodies, config)
+
+ var result = {
+ success: true,
+ id: clientid,
+ type: 'C__OBJTYPE__CLIENT',
+ create: requestCreate ? requestCreate.success : false,
+ update: requestUpdate ? requestUpdate.success : false,
+ createData: requestCreate ? requestCreate.data : false,
+ updateData: requestUpdate ? requestUpdate.data : false
+ }
+
+ return result
+ }
+
// ############################################################################
// ####################### helper/optional functions #########################
diff --git a/server/lib/external-backends/index.js b/server/lib/external-backends/index.js
index 9f99153..00d0da3 100644
--- a/server/lib/external-backends/index.js
+++ b/server/lib/external-backends/index.js
@@ -84,6 +84,16 @@ class ExternalBackends {
}
/*
+ * credendtials: <BACKEND_CREDENTIALS>
+ * objectIds: [<OBJECT_ID>, <OBJECT_ID>, ...]
+ *
+ * Deletes the objecs from the backend.
+ */
+ async deleteObjects (credentials, objectIds) {
+ return { status: 'NOT_IMPLEMENTED_EXCEPTION', error: 'The provided backend does not have a deleteObject method' }
+ }
+
+ /*
* credentials: <BACKEND_CREDENTIALS>
* objects: [{ eid: <EXTERNAL_ID>, gid: <GROUP_ID> }, ...]
* EXTERNAL_ID is the id of the objects in the external backend requestet.
@@ -110,6 +120,24 @@ class ExternalBackends {
async getObjectTypes (credentials) {
return []
}
+
+ /*
+ * Adds the client to the backend.
+ *
+ * credentials: <BACKEND_CREDENTIALS>
+ * The client parameters are all optional. If the client has an id the object is not created but the categories of the object.
+ * client: {
+ * id: <CLIENT_ID>, title: <CLIENT_TITLE>, parentId: <PARENT_ID>,
+ * system: { model: <SYSTEM_MODEL>, manufacturer: <SYSTEM_MANUFACTURER>, serialnumber: <SYSTEM_SERIALNUMBER> },
+ * cpu: { model: <CPU_MODEL>, manufacturer: <CPU_MANUFACTURER>, type: <CPU_TYPE>, frequency: <CPU_FREQUENCY>, cores: <CPU_CORES> },
+ * ram: [{ model: <RAM_MODEL>, manufacturer: <RAM_MANUFACTURER>, type: <RAM_TYPE>, capacity: <RAM_CAPACITY>, unit: <RAM_UNIT> }, ...],
+ * storage: {},
+ * network: { mac: <MAC_ADDRESS>, ip: <IP_ADDRESS> }
+ * }
+ */
+ async addClient (credentials, client) {
+ return { success: false, status: 'NOT_IMPLEMENTED_EXCEPTION', error: 'The provided backend does not have an addClient method' }
+ }
}
module.exports = ExternalBackends
diff --git a/webapp/package-lock.json b/webapp/package-lock.json
index 900a449..99ac667 100644
--- a/webapp/package-lock.json
+++ b/webapp/package-lock.json
@@ -7017,7 +7017,7 @@
"dependencies": {
"async": {
"version": "1.5.2",
- "resolved": "http://registry.npmjs.org/async/-/async-1.5.2.tgz",
+ "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
"integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=",
"dev": true
}