/* global __appdir */ const path = require('path') const ExternalBackends = require(path.join(__appdir, 'lib', 'external-backends')) var axios = require('axios') class IdoitBackend extends ExternalBackends { // ############################################################################ // ######################## needed functions ################################# /* * Returns the credential structure / fields, defined in the backends. */ getCredentials () { return [ { type: 'text', id: 1, name: 'API url', icon: 'link' }, { type: 'password', id: 2, name: 'API token', icon: 'vpn_key', show: false }, { type: 'switch', id: 3, name: 'Login', icon: 'lock_open', elements: [ { type: 'text', id: 4, name: 'username', icon: 'person_outline' }, { type: 'password', id: 5, name: 'password', icon: 'lock', show: false } ] } ] } /* * Checks the connection of a given backend. * idoIT: Checks if we can get a valid session id. If so the connection must be successfull. * * return: { success: , status: '', error: '' } */ checkConnection (credentials) { var c = this.mapCredentials(credentials) return this.getSession(c) } // Return the list of object types created in iDoIT. async getObjectTypes (credentials) { var c = this.mapCredentials(credentials) var login = await this.getSession(c) var sid = login.data.result['session-id'] // Headers var headers = { 'X-RPC-Auth-Session': sid } // Params var params = { 'apikey': c.apikey, 'language': 'en' } var result = {} result.types = await this.axiosRequest(c.url, 'cmdb.object_types', params, headers) result.types = result.types.data.result var types = [] result.types.forEach(type => { types.push({ id: type.id, title: type.title }) }) return types } getSyncTypes () { return ['None', 'Two-Way', 'Upload Only', 'Upload Then Delete', 'Upload Mirror', 'Download Only', 'Download Then Delete', 'Download Mirror'] } /* * Gets all objects and searches for the ip. Because idoit cannot search for ip or mac. * */ async getClient (credentials, client) { var c = this.mapCredentials(credentials) var login = await this.getSession(c) var sid = login.data.result['session-id'] // Headers var headers = { 'X-RPC-Auth-Session': sid } // Params var params = { 'id': 1450, 'apikey': c.apikey, 'language': 'en' } // Get common object data var result = {} result.common = await this.axiosRequest(c.url, 'cmdb.object.read', params, headers) result.common = result.common.data.result // Get objecttypes delete params.id // params.type = result.common.objecttype // result.categories = await this.axiosRequest(c.url, 'cmdb.object_type_categories', params, headers) // result.categories = result.categories.data.result // result.categories = result.categories.data.result /* var cat = [] var self = this result.categories.catg.forEach(async c => { delete params.type params.objID = 1450 params.category = c.const console.log(params) //var tmp = await self.axiosRequest(c.url, 'cmdb.category.read', params, headers).catch(error => {console.log(error)}) //tmp = tmp.data.result //cat.push(tmp) }) result.cat = cat */ // Get all ip addresses // delete params.type params.objID = 1450 params.category = 'C__CATG__IP' var tmp = await this.axiosRequest(c.url, 'cmdb.category.read', params, headers) tmp = tmp.data.result tmp.forEach(element => { if (element.primary_hostaddress) { result.ip = element.primary_hostaddress.ref_title } }) return result } async getObjects (credentials) { var c = this.mapCredentials(credentials) var login = await this.getSession(c) var sid = login.data.result['session-id'] // Headers var headers = { 'X-RPC-Auth-Session': sid } // Params var params = { 'apikey': c.apikey, 'language': 'en' } var result = {} result.objects = await this.axiosRequest(c.url, 'cmdb.objects', params, headers) result.objects = result.objects.data.result return result } async getObject (credentials, oid) { var c = this.mapCredentials(credentials) var login = await this.getSession(c) var sid = login.data.result['session-id'] // Headers var headers = { 'X-RPC-Auth-Session': sid } // Params var params = { 'id': oid, 'apikey': c.apikey, 'language': 'en' } var result = {} result.object = await this.axiosRequest(c.url, 'cmdb.object.read', params, headers) result.childs = await this.axiosRequest(c.url, 'cmdb.location_tree', params, headers) result.object = result.object.data.result result.childs = result.childs.data.result return result } // Function to use the same session for multiple requests async getDataTree (credentials, array) { var c = this.mapCredentials(credentials) // LOGIN // Open and get a session const body = { 'version': '2.0', 'method': 'idoit.login', 'params': { 'apikey': c.apikey, 'language': 'en' }, 'id': 1 } // Headers var headers = {} // Optional credentials if (c.login) { headers['X-RPC-Auth-Username'] = c.username headers['X-RPC-Auth-Password'] = c.password } var config = { timeout: 180000, headers: headers } // Make a login request and see if we are authenticated. var log = await axios.post(c.url, body, config) log = log.data.result var sid = log['session-id'] // Headers config.headers = { 'X-RPC-Auth-Session': sid, 'Content-Type': 'application/json' } body.method = 'cmdb.location_tree' // Go through the objects and get all the childs. var promises = [] var e for (e in array) { var element = array[e] const bod = { 'version': '2.0', 'method': 'cmdb.location_tree', 'params': { 'id': element.eid, 'apikey': c.apikey, 'language': 'en' }, 'id': 1 } var tmp = await axios.post(c.url, bod, config) promises.push({ gid: element.gid, childs: tmp.data.result }) // Add a delay, so that idoit can handle it. // await new Promise(resolve => { setTimeout(() => { resolve() }, 500) }) } return promises } // ############################################################################ // ####################### helper/optional functions ######################### // Helper function, to map the array of credential objects into a single js object. mapCredentials (credentials) { const c = JSON.parse(credentials) const login = c.find(x => x.id === 3) var mapped = { url: c.find(x => x.id === 1).value, apikey: c.find(x => x.id === 2).value, login: login.value } if (mapped.login) { mapped.username = login.elements.find(x => x.id === 4).value mapped.password = login.elements.find(x => x.id === 5).value } return mapped } // Username and password are optional. async getSession (credentials) { // Headers var headers = {} // Optional credentials if (credentials.login) { headers['X-RPC-Auth-Username'] = credentials.username headers['X-RPC-Auth-Password'] = credentials.password } // Params var params = { 'apikey': credentials.apikey, 'language': 'en' } // Make a login request and see if we are authenticated. return this.axiosRequest(credentials.url, 'idoit.login', params, headers) } // Helper function to make the axios http/https requests to reduced copy pasta code in this backend. Including the error handling. async axiosRequest (url, method, params, headers) { const body = { 'version': '2.0', 'method': method, 'params': params, 'id': 1 } var config = { timeout: 180000, headers: headers } config.headers['Content-Type'] = 'application/json' var response = await axios.post(url, body, config) .then(response => { return response }) .catch(error => { console.log(error) return error.response ? error.response : { status: 900, statusText: 'Request failed timeout' } }) // Axios error handling if (response.status !== 200) { return { success: false, error: response.status, msg: response.statusText } } // iDoIT error handling. if (response.data.result) { return { success: true, data: response.data } } else if (response.data.error) { console.log(response.data.error) return { success: false, error: response.data.error.message, msg: response.data.error.data.error } } else { return { success: false, error: 'UNNOWN_ERROR' } } } } module.exports = IdoitBackend