/* ** Zabbix ** Copyright (C) 2001-2023 Zabbix SIA ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation; either version 2 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. **/ class HostInterfaceManager { static INTERFACE_TYPE_AGENT = 1; static INTERFACE_TYPE_SNMP = 2; static INTERFACE_TYPE_IPMI = 3; static INTERFACE_TYPE_JMX = 4; static SNMP_V1 = 1; static SNMP_V2C = 2; static SNMP_V3 = 3; static SNMP_BULK_ENABLED = 1; static INTERFACE_SECONDARY = 0; static INTERFACE_PRIMARY = 1; static INTERFACE_USE_IP = 1; static ITEM_SNMPV3_SECURITYLEVEL_NOAUTHNOPRIV = 0; static ITEM_SNMPV3_SECURITYLEVEL_AUTHNOPRIV = 1; static ITEM_SNMPV3_SECURITYLEVEL_AUTHPRIV = 2; static ITEM_SNMPV3_AUTHPROTOCOL_MD5 = 0; static ITEM_SNMPV3_PRIVPROTOCOL_DES = 0; static ZBX_STYLE_HOST_INTERFACE_BTN_MAIN_INTERFACE = 'interface-btn-main-interface'; static ZBX_STYLE_HOST_INTERFACE_BTN_REMOVE = 'interface-btn-remove'; static ZBX_STYLE_HOST_INTERFACE_BTN_TOGGLE = 'interface-btn-toggle'; static ZBX_STYLE_HOST_INTERFACE_CELL_DETAILS = 'interface-cell-details'; static ZBX_STYLE_HOST_INTERFACE_CELL_USEIP = 'interface-cell-useip'; static ZBX_STYLE_HOST_INTERFACE_CONTAINER = 'interface-container'; static ZBX_STYLE_HOST_INTERFACE_CONTAINER_HEADER = 'interface-container-header'; static ZBX_STYLE_HOST_INTERFACE_INPUT_EXPAND = 'interface-input-expand'; static ZBX_STYLE_HOST_INTERFACE_ROW = 'interface-row'; static ZBX_STYLE_HOST_NO_INTERFACE = 'no-interface'; static ZBX_STYLE_LIST_ACCORDION_ITEM = 'list-accordion-item'; static ZBX_STYLE_LIST_ACCORDION_ITEM_OPENED = 'list-accordion-item-opened'; constructor(data, host_interface_row_tmpl) { // Constants. this.TEMPLATE = new Template(host_interface_row_tmpl); this.DEFAULT_PORTS = { agent: 10050, snmp: 161, jmx: 12345, ipmi: 623 }; this.CONTAINER_IDS = { [HostInterfaceManager.INTERFACE_TYPE_AGENT]: '#agentInterfaces', [HostInterfaceManager.INTERFACE_TYPE_SNMP]: '#SNMPInterfaces', [HostInterfaceManager.INTERFACE_TYPE_JMX]: '#JMXInterfaces', [HostInterfaceManager.INTERFACE_TYPE_IPMI]: '#IPMIInterfaces' }; this.INTERFACE_TYPES = { 'agent': HostInterfaceManager.INTERFACE_TYPE_AGENT, 'snmp': HostInterfaceManager.INTERFACE_TYPE_SNMP, 'jmx': HostInterfaceManager.INTERFACE_TYPE_JMX, 'ipmi': HostInterfaceManager.INTERFACE_TYPE_IPMI }; this.INTERFACE_NAMES = { [HostInterfaceManager.INTERFACE_TYPE_AGENT]: t('Agent'), [HostInterfaceManager.INTERFACE_TYPE_SNMP]: t('SNMP'), [HostInterfaceManager.INTERFACE_TYPE_JMX]: t('JMX'), [HostInterfaceManager.INTERFACE_TYPE_IPMI]: t('IPMI') }; this.allow_empty_message = true; this.$noInterfacesMsg = jQuery('
', { html: t('No interfaces are defined.'), class: HostInterfaceManager.ZBX_STYLE_HOST_NO_INTERFACE }) .insertAfter(jQuery('.' + HostInterfaceManager.ZBX_STYLE_HOST_INTERFACE_CONTAINER_HEADER)); this.interfaces = {}; this.data = data; } /** * Setter for interface store. * * @param object new_data */ set data(new_data) { if (typeof new_data !== 'object') { throw new Error('Incorrect data.'); } Object .entries(new_data) .forEach(([_, value]) => { if (!('interfaceid' in value)) { value.interfaceid = this.generateId(); } this.interfaces[value.interfaceid] = value; }); } /** * Getter for interface store. */ get data() { return this.interfaces; } setAllowEmptyMessage(value) { this.allow_empty_message = value; } setSnmpFields(elem, iface) { if (iface.type != HostInterfaceManager.INTERFACE_TYPE_SNMP) { return elem .querySelector('.' + HostInterfaceManager.ZBX_STYLE_HOST_INTERFACE_CELL_DETAILS) .remove(); } elem .querySelector(`#interfaces_${iface.interfaceid}_details_version`) .value = iface.details.version; if (iface.details.securitylevel !== undefined) { elem .querySelector(`#interfaces_${iface.interfaceid}_details_securitylevel`) .value = iface.details.securitylevel; } if (iface.details.privprotocol !== undefined) { elem.querySelector(`[name="interfaces[${iface.interfaceid}][details][privprotocol]"]`).value = iface.details.privprotocol; } if (iface.details.authprotocol !== undefined) { elem.querySelector(`[name="interfaces[${iface.interfaceid}][details][authprotocol]"]`).value = iface.details.authprotocol; } if (iface.details.bulk == HostInterfaceManager.SNMP_BULK_ENABLED) { elem .querySelector(`#interfaces_${iface.interfaceid}_details_bulk`) .checked = true; } new CViewSwitcher(`interfaces_${iface.interfaceid}_details_version`, 'change', { [HostInterfaceManager.SNMP_V1]: [ `snmp_community_label_${iface.interfaceid}`, `snmp_community_field_${iface.interfaceid}` ], [HostInterfaceManager.SNMP_V2C]: [ `snmp_community_label_${iface.interfaceid}`, `snmp_community_field_${iface.interfaceid}`, `snmp_repetition_count_label_${iface.interfaceid}`, `snmp_repetition_count_field_${iface.interfaceid}` ], [HostInterfaceManager.SNMP_V3]: [ `snmpv3_contextname_label_${iface.interfaceid}`, `snmpv3_contextname_field_${iface.interfaceid}`, `snmpv3_securityname_label_${iface.interfaceid}`, `snmpv3_securityname_field_${iface.interfaceid}`, `snmpv3_securitylevel_label_${iface.interfaceid}`, `snmpv3_securitylevel_field_${iface.interfaceid}`, `snmpv3_authprotocol_label_${iface.interfaceid}`, `snmpv3_authprotocol_field_${iface.interfaceid}`, `snmpv3_authpassphrase_label_${iface.interfaceid}`, `snmpv3_authpassphrase_field_${iface.interfaceid}`, `snmpv3_privprotocol_label_${iface.interfaceid}`, `snmpv3_privprotocol_field_${iface.interfaceid}`, `snmpv3_privpassphrase_label_${iface.interfaceid}`, `snmpv3_privpassphrase_field_${iface.interfaceid}`, `snmp_repetition_count_label_${iface.interfaceid}`, `snmp_repetition_count_field_${iface.interfaceid}` ] } ); jQuery(`#interfaces_${iface.interfaceid}_details_version`).on('change', (e) => { jQuery(`#interfaces_${iface.interfaceid}_details_securitylevel`).off('change'); if (e.target.value == HostInterfaceManager.SNMP_V3) { new CViewSwitcher(`interfaces_${iface.interfaceid}_details_securitylevel`, 'change', { [HostInterfaceManager.ITEM_SNMPV3_SECURITYLEVEL_NOAUTHNOPRIV]: [], [HostInterfaceManager.ITEM_SNMPV3_SECURITYLEVEL_AUTHNOPRIV]: [ `snmpv3_authprotocol_label_${iface.interfaceid}`, `snmpv3_authprotocol_field_${iface.interfaceid}`, `snmpv3_authpassphrase_label_${iface.interfaceid}`, `snmpv3_authpassphrase_field_${iface.interfaceid}` ], [HostInterfaceManager.ITEM_SNMPV3_SECURITYLEVEL_AUTHPRIV]: [ `snmpv3_authprotocol_label_${iface.interfaceid}`, `snmpv3_authprotocol_field_${iface.interfaceid}`, `snmpv3_authpassphrase_label_${iface.interfaceid}`, `snmpv3_authpassphrase_field_${iface.interfaceid}`, `snmpv3_privprotocol_label_${iface.interfaceid}`, `snmpv3_privprotocol_field_${iface.interfaceid}`, `snmpv3_privpassphrase_label_${iface.interfaceid}`, `snmpv3_privpassphrase_field_${iface.interfaceid}` ] } ); } }).trigger('change'); } generateId() { const keys = Object.keys(this.data).map(Number); const max_key = Math.max(0, ...keys); return max_key+1; } getNewData(type) { return { interfaceid: this.generateId(), isNew: true, useip: 1, type: this.INTERFACE_TYPES[type], type_name: this.INTERFACE_NAMES[this.INTERFACE_TYPES[type]], port: this.DEFAULT_PORTS[type], ip: '127.0.0.1', main: '0', details: { version: HostInterfaceManager.SNMP_V2C, community: '{$SNMP_COMMUNITY}', max_repetitions: 10, bulk: HostInterfaceManager.SNMP_BULK_ENABLED, securitylevel: HostInterfaceManager.ITEM_SNMPV3_SECURITYLEVEL_NOAUTHNOPRIV, authprotocol: HostInterfaceManager.ITEM_SNMPV3_AUTHPROTOCOL_MD5, privprotocol: HostInterfaceManager.ITEM_SNMPV3_PRIVPROTOCOL_DES } }; } getInterfaces() { let types = { [HostInterfaceManager.INTERFACE_TYPE_AGENT]: {main: null, all: []}, [HostInterfaceManager.INTERFACE_TYPE_SNMP]: {main: null, all: []}, [HostInterfaceManager.INTERFACE_TYPE_JMX]: {main: null, all: []}, [HostInterfaceManager.INTERFACE_TYPE_IPMI]: {main: null, all: []} }; Object .entries(this.data) .forEach(([_, value]) => { types[value.type].all.push(value.interfaceid); if (value.main == HostInterfaceManager.INTERFACE_PRIMARY) { if (types[value.type].main !== null) { throw new Error('Multiple default interfaces for same type.'); } types[value.type].main = value.interfaceid; } }); return types; } renderRow(iface) { const container = document.querySelector(this.CONTAINER_IDS[iface.type]); const disabled = (typeof iface.items !== 'undefined' && iface.items > 0); iface.type_name = this.INTERFACE_NAMES[iface.type]; /* * New line break css selector :empty. Trim used to avoid this. * Template added with new line. Because template