summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJannik Schönartz2018-11-12 08:26:40 +0100
committerJannik Schönartz2018-11-12 08:26:40 +0100
commitb25692fdd948d25b2dcf39bd775d50849014c180 (patch)
tree45d76aa1ca78ea5dcf4937895b8d1a74934afa41
parent[registration] add configurator for registration hooks (diff)
downloadbas-b25692fdd948d25b2dcf39bd775d50849014c180.tar.gz
bas-b25692fdd948d25b2dcf39bd775d50849014c180.tar.xz
bas-b25692fdd948d25b2dcf39bd775d50849014c180.zip
[idoit] Clients are now added to the idoit backend
Delete client in the backends if client is deleted in the bas. Add method for creating the client in the backends Add method for adding additional information to the client in the backend Add backend helper for calling all backends with the matching external id Add idoit mehtod for creating and updating a client
-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
}