/* 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: '' } */ async 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'] } 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 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: 90000, headers: headers } // Make a login request and see if we are authenticated. return axios.post(c.url, body, config).then(log => { var sid = log.data.result['session-id'] // Headers config.headers = { 'X-RPC-Auth-Session': sid, 'Content-Type': 'application/json' } body.method = 'cmdb.location_tree' var promises = [] array.forEach(element => { const bod = { 'version': '2.0', 'method': 'cmdb.location_tree', 'params': { 'id': element.eid, 'apikey': c.apikey, 'language': 'en' }, 'id': 1 } promises.push(axios.post(c.url, bod, config).then(result => { return { gid: element.gid, childs: result.data.result } })) }) return Promise.all(promises).then(ret => { return ret }) }) } // ############################################################################ // ####################### 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: 90000, 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