/*
** 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