7 Commits

Author SHA1 Message Date
TsMask
103af4a999 fix: redis批量获得缓存数据独立上下文 2024-11-08 16:54:27 +08:00
TsMask
26b950c919 feat: 网元开站配置UPF网卡名和驱动类型参数 2024-11-08 16:18:44 +08:00
TsMask
d6f142648a sql: UDM用户数据表索引更新ne_id 2024-11-07 20:55:25 +08:00
TsMask
4a8f6e08ff feat: redis读取hgetall数据批量读取返回 2024-11-07 20:52:48 +08:00
TsMask
7f4a8abcdd sql: 网元主机支持redisl类型标签色并分配角色菜单 2024-11-07 18:05:27 +08:00
TsMask
9ac5ae50ec feat: 网元主机添加redis连接终端控制 2024-11-07 18:03:59 +08:00
TsMask
2c139e71c4 feat: iperf支持v2的版本操作 2024-11-05 17:35:11 +08:00
29 changed files with 450 additions and 98 deletions

View File

@@ -78,7 +78,7 @@ INSERT INTO `sys_dict_data` VALUES (50, 8, 'dictData.jobSaveLog.no', '0', 'sys_j
INSERT INTO `sys_dict_data` VALUES (51, 9, 'dictData.jobSaveLog.yes', '1', 'sys_job_save_log', NULL, NULL, '1', 'supervisor', 1699350000000, NULL, 0, NULL);
-- INSERT INTO `sys_dict_data` VALUES (52, 1, 'dictData.neVersionStatus.upload', 'Uploaded', 'ne_version_status', NULL, 'processing', '1', 'supervisor', 1699350000000, NULL, 0, NULL);
-- INSERT INTO `sys_dict_data` VALUES (53, 2, 'dictData.neVersionStatus.inactive', 'Inactive', 'ne_version_status', NULL, 'gold', '1', 'supervisor', 1699350000000, NULL, 0, NULL);
-- INSERT INTO `sys_dict_data` VALUES (54, 3, 'dictData.neVersionStatus.active', 'Active', 'ne_version_status', NULL, 'success', '1', 'supervisor', 1699350000000, NULL, 0, NULL);
INSERT INTO `sys_dict_data` VALUES (54, 2, 'dictData.ne_host_type.redis', 'redis', 'ne_host_type', '', 'magenta', '1', 'supervisor', 1706620000000, '', 0, '');
INSERT INTO `sys_dict_data` VALUES (55, 1, 'dictData.alarmStatus.history', '0', 'alarm_status', NULL, NULL, '1', 'supervisor', 1699350000000, NULL, 0, NULL);
INSERT INTO `sys_dict_data` VALUES (56, 2, 'dictData.alarmStatus.active', '1', 'alarm_status', NULL, NULL, '1', 'supervisor', 1699350000000, NULL, 0, NULL);
INSERT INTO `sys_dict_data` VALUES (57, 1, 'dictData.datascope.all', '1', 'sys_role_datascope', NULL, NULL, '1', 'supervisor', 1699350000000, NULL, 0, NULL);
@@ -133,8 +133,8 @@ INSERT INTO `sys_dict_data` VALUES (105, 17, 'dictData.cdr_sip_code.202', '202',
INSERT INTO `sys_dict_data` VALUES (106, 3, 'dictData.cdr_call_type.sms', 'sms', 'cdr_call_type', '', '', '1', 'supervisor', 1706620000000, '', 0, '');
INSERT INTO `sys_dict_data` VALUES (107, 9, 'dictData.cdr_sip_code.488', '488', 'cdr_sip_code', '', '', '1', 'supervisor', 1706610000000, '', 0, '');
INSERT INTO `sys_dict_data` VALUES (108, 0, 'dictData.cdr_sip_code.0', '0', 'cdr_sip_code', '', '', '1', 'supervisor', 1706610000000, '', 0, '');
INSERT INTO `sys_dict_data` VALUES (109, 0, 'dictData.ne_host_type.ssh', 'ssh', 'ne_host_type', '', '', '1', 'supervisor', 1706620000000, '', 0, '');
INSERT INTO `sys_dict_data` VALUES (110, 1, 'dictData.ne_host_type.telnet', 'telnet', 'ne_host_type', '', '', '1', 'supervisor', 1706620000000, '', 0, '');
INSERT INTO `sys_dict_data` VALUES (109, 0, 'dictData.ne_host_type.ssh', 'ssh', 'ne_host_type', '', 'blue', '1', 'supervisor', 1706620000000, '', 0, '');
INSERT INTO `sys_dict_data` VALUES (110, 1, 'dictData.ne_host_type.telnet', 'telnet', 'ne_host_type', '', 'purple', '1', 'supervisor', 1706620000000, '', 0, '');
INSERT INTO `sys_dict_data` VALUES (111, 0, 'dictData.ne_host_groupId.0', '0', 'ne_host_groupId', '', '', '1', 'supervisor', 1706620000000, '', 0, '');
INSERT INTO `sys_dict_data` VALUES (112, 1, 'dictData.ne_host_groupId.1', '1', 'ne_host_groupId', '', '', '1', 'supervisor', 1706620000000, '', 0, '');
INSERT INTO `sys_dict_data` VALUES (113, 2, 'dictData.ne_host_groupId.2', '2', 'ne_host_groupId', '', '', '1', 'supervisor', 1706620000000, '', 0, '');

View File

@@ -206,8 +206,8 @@ INSERT INTO `sys_dict_data` VALUES (1426, 1426, 'dictData.trace.user', '用户
-- INSERT INTO `sys_dict_data` VALUES (1442, 1442, 'dictData.securityLogType.add', '新增', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
-- INSERT INTO `sys_dict_data` VALUES (1443, 1443, 'dictData.securityLogType.update', '更新', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
-- INSERT INTO `sys_dict_data` VALUES (1444, 1444, 'dictData.securityLogType.delete', '删除', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
-- INSERT INTO `sys_dict_data` VALUES (1445, 1445, 'dictData.securityLogType.lock', '锁定', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
-- INSERT INTO `sys_dict_data` VALUES (1446, 1446, 'dictData.securityLogType.unlock', '解锁', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
INSERT INTO `sys_dict_data` VALUES (1445, 1445, 'neHost.banNE', '禁止操作网元', 'i18n_zh', '', '', '1', 'supervisor', 1728640045875, '', 0, '');
INSERT INTO `sys_dict_data` VALUES (1446, 1446, 'dictData.ne_host_type.redis', 'Redis', 'i18n_zh', '', '', '1', 'supervisor', 1728640045875, '', 0, '');
INSERT INTO `sys_dict_data` VALUES (1447, 1447, 'menu.tools.ping', '网络探测测试', 'i18n_zh', '', '', '1', 'supervisor', 1728640045875, '', 0, '');
INSERT INTO `sys_dict_data` VALUES (1448, 1448, 'menu.tools.iperf', '网络性能测试', 'i18n_zh', '', '', '1', 'supervisor', 1728640045875, '', 0, '');
INSERT INTO `sys_dict_data` VALUES (1449, 1449, 'dictData.jobSaveLog.no', '不记录', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
@@ -602,7 +602,7 @@ INSERT INTO `sys_dict_data` VALUES (2091, 2091, 'dictData.ne_host_groupId.1', '
INSERT INTO `sys_dict_data` VALUES (2092, 2092, 'dictData.ne_host_groupId.2', '系统', 'i18n_zh', '', '', '1', 'supervisor', 1705550000000, '', 0, '');
INSERT INTO `sys_dict_data` VALUES (2093, 2093, 'dictData.ne_host_authMode.0', '密码认证', 'i18n_zh', '', '', '1', 'supervisor', 1705550000000, '', 0, '');
INSERT INTO `sys_dict_data` VALUES (2094, 2094, 'dictData.ne_host_authMode.1', '私钥认证', 'i18n_zh', '', '', '1', 'supervisor', 1705550000000, '', 0, '');
INSERT INTO `sys_dict_data` VALUES (2095, 2095, 'menu.tools.terminal', '网元主机终端', 'i18n_zh', '', '', '1', 'supervisor', 1705550000000, '', 0, '');
INSERT INTO `sys_dict_data` VALUES (2095, 2095, 'menu.tools.terminal', '主机终端', 'i18n_zh', '', '', '1', 'supervisor', 1705550000000, '', 0, '');
INSERT INTO `sys_dict_data` VALUES (2096, 2096, 'menu.ne.neHost', '网元主机', 'i18n_zh', '', '', '1', 'supervisor', 1705550000000, '', 0, '');
INSERT INTO `sys_dict_data` VALUES (2097, 2097, 'menu.ne.neHostCommand', '网元主机命令', 'i18n_zh', '', '', '1', 'supervisor', 1705550000000, '', 0, '');
INSERT INTO `sys_dict_data` VALUES (2098, 2098, 'log.operate.title.neHostCmd', '网元主机命令', 'i18n_zh', '', '', '1', 'supervisor', 1705550000000, '', 0, '');

View File

@@ -206,8 +206,8 @@ INSERT INTO `sys_dict_data` VALUES (3426, 3426, 'dictData.trace.user', 'User Tra
-- INSERT INTO `sys_dict_data` VALUES (3442, 3442, 'dictData.securityLogType.add', 'New', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
-- INSERT INTO `sys_dict_data` VALUES (3443, 3443, 'dictData.securityLogType.update', 'Update', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
-- INSERT INTO `sys_dict_data` VALUES (3444, 3444, 'dictData.securityLogType.delete', 'Delete', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
-- INSERT INTO `sys_dict_data` VALUES (3445, 3445, 'dictData.securityLogType.lock', 'Locked', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
-- INSERT INTO `sys_dict_data` VALUES (3446, 3446, 'dictData.securityLogType.unlock', 'Unlock', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
INSERT INTO `sys_dict_data` VALUES (3445, 3445, 'neHost.banNE', 'Do not operate the NE', 'i18n_en', '', '', '1', 'supervisor', 1728640045875, '', 0, '');
INSERT INTO `sys_dict_data` VALUES (3446, 3446, 'dictData.ne_host_type.redis', 'Redis', 'i18n_en', '', '', '1', 'supervisor', 1728640045875, '', 0, '');
INSERT INTO `sys_dict_data` VALUES (3447, 3447, 'menu.tools.ping', 'Net Probing Test', 'i18n_en', '', '', '1', 'supervisor', 1728640045875, '', 0, '');
INSERT INTO `sys_dict_data` VALUES (3448, 3448, 'menu.tools.iperf', 'Net Performance Test', 'i18n_en', '', '', '1', 'supervisor', 1728640045875, '', 0, '');
INSERT INTO `sys_dict_data` VALUES (3449, 3449, 'dictData.jobSaveLog.no', 'No Record', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
@@ -602,7 +602,7 @@ INSERT INTO `sys_dict_data` VALUES (4091, 4091, 'dictData.ne_host_groupId.1', 'N
INSERT INTO `sys_dict_data` VALUES (4092, 4092, 'dictData.ne_host_groupId.2', 'System', 'i18n_en', '', '', '1', 'supervisor', 1705550000000, '', 0, '');
INSERT INTO `sys_dict_data` VALUES (4093, 4093, 'dictData.ne_host_authMode.0', 'Password Authentication', 'i18n_en', '', '', '1', 'supervisor', 1705550000000, '', 0, '');
INSERT INTO `sys_dict_data` VALUES (4094, 4094, 'dictData.ne_host_authMode.1', 'Private key authentication', 'i18n_en', '', '', '1', 'supervisor', 1705550000000, '', 0, '');
INSERT INTO `sys_dict_data` VALUES (4095, 4095, 'menu.tools.terminal', 'NE Host Terminal', 'i18n_en', '', '', '1', 'supervisor', 1705550000000, '', 0, '');
INSERT INTO `sys_dict_data` VALUES (4095, 4095, 'menu.tools.terminal', 'Host Terminal', 'i18n_en', '', '', '1', 'supervisor', 1705550000000, '', 0, '');
INSERT INTO `sys_dict_data` VALUES (4096, 4096, 'menu.ne.neHost', 'NE Host', 'i18n_en', '', '', '1', 'supervisor', 1705550000000, '', 0, '');
INSERT INTO `sys_dict_data` VALUES (4097, 4097, 'menu.ne.neHostCommand', 'NE Host CMD', 'i18n_en', '', '', '1', 'supervisor', 1705550000000, '', 0, '');
INSERT INTO `sys_dict_data` VALUES (4098, 4098, 'log.operate.title.neHostCmd', 'NE Host CMD', 'i18n_en', '', '', '1', 'supervisor', 1705550000000, '', 0, '');

View File

@@ -21,6 +21,7 @@ INSERT IGNORE INTO `sys_role_menu` VALUES (2, 1);
INSERT IGNORE INTO `sys_role_menu` VALUES (2, 4);
INSERT IGNORE INTO `sys_role_menu` VALUES (2, 5);
INSERT IGNORE INTO `sys_role_menu` VALUES (2, 60);
INSERT IGNORE INTO `sys_role_menu` VALUES (2, 61);
INSERT IGNORE INTO `sys_role_menu` VALUES (2, 63);
INSERT IGNORE INTO `sys_role_menu` VALUES (2, 64);
INSERT IGNORE INTO `sys_role_menu` VALUES (2, 65);

View File

@@ -14,7 +14,8 @@ CREATE TABLE `u_auth_user` (
`algo_index` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT 'algoIndex',
`opc` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT 'OPC',
PRIMARY KEY (`id`) USING BTREE,
UNIQUE KEY `imsi_ne` (`imsi`,`ne_id`) USING BTREE COMMENT 'imsi_neid唯一主键'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='UDM鉴权用户';
UNIQUE KEY `uk_imsi_ne` (`imsi`,`ne_id`) USING BTREE COMMENT 'imsi_neid唯一主键',
KEY `idx_ne` (`ne_id`) USING BTREE COMMENT 'neid索引'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC COMMENT='UDM鉴权用户';
-- Dump completed on 2024-03-06 17:26:59

View File

@@ -36,7 +36,8 @@ CREATE TABLE `u_sub_user` (
`smf_sel` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT 'smfSel',
`cag` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT 'CAG',
PRIMARY KEY (`id`) USING BTREE,
UNIQUE KEY `imsi_ne` (`imsi`,`ne_id`) USING BTREE COMMENT 'imsi_ne唯一索引'
UNIQUE KEY `uk_imsi_ne` (`imsi`,`ne_id`) USING BTREE COMMENT 'imsi_neid唯一主键',
KEY `idx_ne` (`ne_id`) USING BTREE COMMENT 'neid索引'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='UDM签约用户';
-- Dump completed on 2024-10-12 15:26:59

View File

@@ -78,7 +78,7 @@ INSERT IGNORE INTO `sys_dict_data` VALUES (50, 8, 'dictData.jobSaveLog.no', '0',
INSERT IGNORE INTO `sys_dict_data` VALUES (51, 9, 'dictData.jobSaveLog.yes', '1', 'sys_job_save_log', NULL, NULL, '1', 'supervisor', 1699350000000, NULL, 0, NULL);
-- INSERT IGNORE INTO `sys_dict_data` VALUES (52, 1, 'dictData.neVersionStatus.upload', 'Uploaded', 'ne_version_status', NULL, 'processing', '1', 'supervisor', 1699350000000, NULL, 0, NULL);
-- INSERT IGNORE INTO `sys_dict_data` VALUES (53, 2, 'dictData.neVersionStatus.inactive', 'Inactive', 'ne_version_status', NULL, 'gold', '1', 'supervisor', 1699350000000, NULL, 0, NULL);
-- INSERT IGNORE INTO `sys_dict_data` VALUES (54, 3, 'dictData.neVersionStatus.active', 'Active', 'ne_version_status', NULL, 'success', '1', 'supervisor', 1699350000000, NULL, 0, NULL);
INSERT IGNORE INTO `sys_dict_data` VALUES (54, 2, 'dictData.ne_host_type.redis', 'redis', 'ne_host_type', '', 'magenta', '1', 'supervisor', 1706620000000, '', 0, '');
INSERT IGNORE INTO `sys_dict_data` VALUES (55, 1, 'dictData.alarmStatus.history', '0', 'alarm_status', NULL, NULL, '1', 'supervisor', 1699350000000, NULL, 0, NULL);
INSERT IGNORE INTO `sys_dict_data` VALUES (56, 2, 'dictData.alarmStatus.active', '1', 'alarm_status', NULL, NULL, '1', 'supervisor', 1699350000000, NULL, 0, NULL);
INSERT IGNORE INTO `sys_dict_data` VALUES (57, 1, 'dictData.datascope.all', '1', 'sys_role_datascope', NULL, NULL, '1', 'supervisor', 1699350000000, NULL, 0, NULL);
@@ -133,8 +133,8 @@ INSERT IGNORE INTO `sys_dict_data` VALUES (105, 17, 'dictData.cdr_sip_code.202',
INSERT IGNORE INTO `sys_dict_data` VALUES (106, 3, 'dictData.cdr_call_type.sms', 'sms', 'cdr_call_type', '', '', '1', 'supervisor', 1706620000000, '', 0, '');
INSERT IGNORE INTO `sys_dict_data` VALUES (107, 9, 'dictData.cdr_sip_code.488', '488', 'cdr_sip_code', '', '', '1', 'supervisor', 1706610000000, '', 0, '');
INSERT IGNORE INTO `sys_dict_data` VALUES (108, 0, 'dictData.cdr_sip_code.0', '0', 'cdr_sip_code', '', '', '1', 'supervisor', 1706610000000, '', 0, '');
INSERT IGNORE INTO `sys_dict_data` VALUES (109, 0, 'dictData.ne_host_type.ssh', 'ssh', 'ne_host_type', '', '', '1', 'supervisor', 1706620000000, '', 0, '');
INSERT IGNORE INTO `sys_dict_data` VALUES (110, 1, 'dictData.ne_host_type.telnet', 'telnet', 'ne_host_type', '', '', '1', 'supervisor', 1706620000000, '', 0, '');
INSERT IGNORE INTO `sys_dict_data` VALUES (109, 0, 'dictData.ne_host_type.ssh', 'ssh', 'ne_host_type', '', 'blue', '1', 'supervisor', 1706620000000, '', 0, '');
INSERT IGNORE INTO `sys_dict_data` VALUES (110, 1, 'dictData.ne_host_type.telnet', 'telnet', 'ne_host_type', '', 'purple', '1', 'supervisor', 1706620000000, '', 0, '');
INSERT IGNORE INTO `sys_dict_data` VALUES (111, 0, 'dictData.ne_host_groupId.0', '0', 'ne_host_groupId', '', '', '1', 'supervisor', 1706620000000, '', 0, '');
INSERT IGNORE INTO `sys_dict_data` VALUES (112, 1, 'dictData.ne_host_groupId.1', '1', 'ne_host_groupId', '', '', '1', 'supervisor', 1706620000000, '', 0, '');
INSERT IGNORE INTO `sys_dict_data` VALUES (113, 2, 'dictData.ne_host_groupId.2', '2', 'ne_host_groupId', '', '', '1', 'supervisor', 1706620000000, '', 0, '');

View File

@@ -213,8 +213,8 @@ REPLACE INTO `sys_dict_data` VALUES (1426, 1426, 'dictData.trace.user', '用户
-- REPLACE INTO `sys_dict_data` VALUES (1442, 1442, 'dictData.securityLogType.add', '新增', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
-- REPLACE INTO `sys_dict_data` VALUES (1443, 1443, 'dictData.securityLogType.update', '更新', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
-- REPLACE INTO `sys_dict_data` VALUES (1444, 1444, 'dictData.securityLogType.delete', '删除', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
-- REPLACE INTO `sys_dict_data` VALUES (1445, 1445, 'dictData.securityLogType.lock', '锁定', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
-- REPLACE INTO `sys_dict_data` VALUES (1446, 1446, 'dictData.securityLogType.unlock', '解锁', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
REPLACE INTO `sys_dict_data` VALUES (1445, 1445, 'neHost.banNE', '禁止操作网元', 'i18n_zh', '', '', '1', 'supervisor', 1728640045875, '', 0, '');
REPLACE INTO `sys_dict_data` VALUES (1446, 1446, 'dictData.ne_host_type.redis', 'Redis', 'i18n_zh', '', '', '1', 'supervisor', 1728640045875, '', 0, '');
REPLACE INTO `sys_dict_data` VALUES (1447, 1447, 'menu.tools.ping', '网络探测测试', 'i18n_zh', '', '', '1', 'supervisor', 1728640045875, '', 0, '');
REPLACE INTO `sys_dict_data` VALUES (1448, 1448, 'menu.tools.iperf', '网络性能测试', 'i18n_zh', '', '', '1', 'supervisor', 1728640045875, '', 0, '');
REPLACE INTO `sys_dict_data` VALUES (1449, 1449, 'dictData.jobSaveLog.no', '不记录', 'i18n_zh', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
@@ -609,7 +609,7 @@ REPLACE INTO `sys_dict_data` VALUES (2091, 2091, 'dictData.ne_host_groupId.1', '
REPLACE INTO `sys_dict_data` VALUES (2092, 2092, 'dictData.ne_host_groupId.2', '系统', 'i18n_zh', '', '', '1', 'supervisor', 1705550000000, '', 0, '');
REPLACE INTO `sys_dict_data` VALUES (2093, 2093, 'dictData.ne_host_authMode.0', '密码认证', 'i18n_zh', '', '', '1', 'supervisor', 1705550000000, '', 0, '');
REPLACE INTO `sys_dict_data` VALUES (2094, 2094, 'dictData.ne_host_authMode.1', '私钥认证', 'i18n_zh', '', '', '1', 'supervisor', 1705550000000, '', 0, '');
REPLACE INTO `sys_dict_data` VALUES (2095, 2095, 'menu.tools.terminal', '网元主机终端', 'i18n_zh', '', '', '1', 'supervisor', 1705550000000, '', 0, '');
REPLACE INTO `sys_dict_data` VALUES (2095, 2095, 'menu.tools.terminal', '主机终端', 'i18n_zh', '', '', '1', 'supervisor', 1705550000000, '', 0, '');
REPLACE INTO `sys_dict_data` VALUES (2096, 2096, 'menu.ne.neHost', '网元主机', 'i18n_zh', '', '', '1', 'supervisor', 1705550000000, '', 0, '');
REPLACE INTO `sys_dict_data` VALUES (2097, 2097, 'menu.ne.neHostCommand', '网元主机命令', 'i18n_zh', '', '', '1', 'supervisor', 1705550000000, '', 0, '');
REPLACE INTO `sys_dict_data` VALUES (2098, 2098, 'log.operate.title.neHostCmd', '网元主机命令', 'i18n_zh', '', '', '1', 'supervisor', 1705550000000, '', 0, '');

View File

@@ -207,8 +207,8 @@ REPLACE INTO `sys_dict_data` VALUES (3426, 3426, 'dictData.trace.user', 'User Tr
-- REPLACE INTO `sys_dict_data` VALUES (3442, 3442, 'dictData.securityLogType.add', 'New', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
-- REPLACE INTO `sys_dict_data` VALUES (3443, 3443, 'dictData.securityLogType.update', 'Update', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
-- REPLACE INTO `sys_dict_data` VALUES (3444, 3444, 'dictData.securityLogType.delete', 'Delete', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
-- REPLACE INTO `sys_dict_data` VALUES (3445, 3445, 'dictData.securityLogType.lock', 'Locked', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
-- REPLACE INTO `sys_dict_data` VALUES (3446, 3446, 'dictData.securityLogType.unlock', 'Unlock', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
REPLACE INTO `sys_dict_data` VALUES (3445, 3445, 'neHost.banNE', 'Do not operate the NE', 'i18n_en', '', '', '1', 'supervisor', 1728640045875, '', 0, '');
REPLACE INTO `sys_dict_data` VALUES (3446, 3446, 'dictData.ne_host_type.redis', 'Redis', 'i18n_en', '', '', '1', 'supervisor', 1728640045875, '', 0, '');
REPLACE INTO `sys_dict_data` VALUES (3447, 3447, 'menu.tools.ping', 'Net Probing Test', 'i18n_en', '', '', '1', 'supervisor', 1728640045875, '', 0, '');
REPLACE INTO `sys_dict_data` VALUES (3448, 3448, 'menu.tools.iperf', 'Net Performance Test', 'i18n_en', '', '', '1', 'supervisor', 1728640045875, '', 0, '');
REPLACE INTO `sys_dict_data` VALUES (3449, 3449, 'dictData.jobSaveLog.no', 'No Record', 'i18n_en', NULL, NULL, '1', 'supervisor', 1700000000000, NULL, 0, NULL);
@@ -604,7 +604,7 @@ REPLACE INTO `sys_dict_data` VALUES (4091, 4091, 'dictData.ne_host_groupId.1', '
REPLACE INTO `sys_dict_data` VALUES (4092, 4092, 'dictData.ne_host_groupId.2', 'System', 'i18n_en', '', '', '1', 'supervisor', 1705550000000, '', 0, '');
REPLACE INTO `sys_dict_data` VALUES (4093, 4093, 'dictData.ne_host_authMode.0', 'Password Auth Mode', 'i18n_en', '', '', '1', 'supervisor', 1705550000000, '', 0, '');
REPLACE INTO `sys_dict_data` VALUES (4094, 4094, 'dictData.ne_host_authMode.1', 'PrivateKey Auth Mode', 'i18n_en', '', '', '1', 'supervisor', 1705550000000, '', 0, '');
REPLACE INTO `sys_dict_data` VALUES (4095, 4095, 'menu.tools.terminal', 'NE Host Terminal', 'i18n_en', '', '', '1', 'supervisor', 1705550000000, '', 0, '');
REPLACE INTO `sys_dict_data` VALUES (4095, 4095, 'menu.tools.terminal', 'Host Terminal', 'i18n_en', '', '', '1', 'supervisor', 1705550000000, '', 0, '');
REPLACE INTO `sys_dict_data` VALUES (4096, 4096, 'menu.ne.neHost', 'NE Host', 'i18n_en', '', '', '1', 'supervisor', 1705550000000, '', 0, '');
REPLACE INTO `sys_dict_data` VALUES (4097, 4097, 'menu.ne.neHostCommand', 'NE Host CMD', 'i18n_en', '', '', '1', 'supervisor', 1705550000000, '', 0, '');
REPLACE INTO `sys_dict_data` VALUES (4098, 4098, 'log.operate.title.neHostCmd', 'NE Host CMD', 'i18n_en', '', '', '1', 'supervisor', 1705550000000, '', 0, '');

View File

@@ -18,6 +18,7 @@ INSERT IGNORE INTO `sys_role_menu` VALUES (2, 1);
INSERT IGNORE INTO `sys_role_menu` VALUES (2, 4);
INSERT IGNORE INTO `sys_role_menu` VALUES (2, 5);
INSERT IGNORE INTO `sys_role_menu` VALUES (2, 60);
INSERT IGNORE INTO `sys_role_menu` VALUES (2, 61);
INSERT IGNORE INTO `sys_role_menu` VALUES (2, 63);
INSERT IGNORE INTO `sys_role_menu` VALUES (2, 64);
INSERT IGNORE INTO `sys_role_menu` VALUES (2, 65);

View File

@@ -25,3 +25,5 @@ ALTER TABLE `u_auth_user` MODIFY COLUMN IF EXISTS `ki` varchar(50) CHARACTER SET
ALTER TABLE `u_auth_user` MODIFY COLUMN IF EXISTS `algo_index` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT 'algoIndex' AFTER `ki`;
ALTER TABLE `u_auth_user` MODIFY COLUMN IF EXISTS `opc` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT 'OPC' AFTER `algo_index`;
ALTER TABLE `u_auth_user` DROP COLUMN IF EXISTS `msisdn`;
ALTER TABLE `u_auth_user` RENAME INDEX IF EXISTS `imsi_ne` TO `uk_imsi_ne`;
ALTER TABLE `u_auth_user` ADD INDEX IF NOT EXISTS `idx_ne`(`ne_id`) USING BTREE COMMENT 'neid索引';

View File

@@ -68,3 +68,5 @@ ALTER TABLE `u_sub_user` MODIFY COLUMN IF EXISTS `static_ip` varchar(50) CHARACT
ALTER TABLE `u_sub_user` MODIFY COLUMN IF EXISTS `sm_data` varchar(1500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT 'smData' AFTER `static_ip`;
ALTER TABLE `u_sub_user` MODIFY COLUMN IF EXISTS `smf_sel` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT 'smfSel' AFTER `sm_data`;
ALTER TABLE `u_sub_user` DROP COLUMN IF EXISTS `cn`;
ALTER TABLE `u_sub_user` RENAME INDEX IF EXISTS `imsi_ne` TO `uk_imsi_ne`;
ALTER TABLE `u_sub_user` ADD INDEX IF NOT EXISTS `idx_ne`(`ne_id`) USING BTREE COMMENT 'neid索引';

View File

@@ -59,3 +59,21 @@ func (c *ConnRedis) Close() {
c.Client.Close()
}
}
// RunCMD 执行单次命令 "GET key"
func (c *ConnRedis) RunCMD(cmd string) (any, error) {
if c.Client == nil {
return "", fmt.Errorf("redis client not connected")
}
// 写入命令
cmdArr := strings.Fields(cmd)
if len(cmdArr) == 0 {
return "", fmt.Errorf("redis command is empty")
}
conn := *c.Client
args := make([]any, 0)
for _, v := range cmdArr {
args = append(args, v)
}
return conn.Do(context.Background(), args...).Result()
}

View File

@@ -4,6 +4,7 @@ import (
"context"
"fmt"
"strings"
"sync"
"time"
"be.ems/src/framework/config"
@@ -179,31 +180,22 @@ func GetExpire(source string, key string) (float64, error) {
}
// 获得缓存数据的key列表
func GetKeys(source string, pattern string) ([]string, error) {
func GetKeys(source string, match string) ([]string, error) {
// 数据源
rdb := DefaultRDB()
if source != "" {
rdb = RDB(source)
}
// 初始化变量
var keys []string
var cursor uint64 = 0
keys := make([]string, 0)
ctx := context.Background()
// 循环遍历获取匹配的键
for {
// 使用 SCAN 命令获取匹配的键
batchKeys, nextCursor, err := rdb.Scan(ctx, cursor, pattern, 1000).Result()
if err != nil {
logger.Errorf("Failed to scan keys: %v", err)
return keys, err
}
cursor = nextCursor
keys = append(keys, batchKeys...)
// 当 cursor 为 0表示遍历完成
if cursor == 0 {
break
}
iter := rdb.Scan(ctx, 0, match, 1000).Iterator()
if err := iter.Err(); err != nil {
logger.Errorf("Failed to scan keys: %v", err)
return keys, err
}
for iter.Next(ctx) {
keys = append(keys, iter.Val())
}
return keys, nil
}
@@ -261,6 +253,84 @@ func GetHash(source, key string) (map[string]string, error) {
return value, nil
}
// 批量获得缓存数据 [key]result
func GetHashBatch(source string, keys []string) (map[string]map[string]string, error) {
result := make(map[string]map[string]string, 0)
if len(keys) == 0 {
return result, fmt.Errorf("not keys")
}
// 数据源
rdb := DefaultRDB()
if source != "" {
rdb = RDB(source)
}
// 创建一个有限的并发控制信号通道
sem := make(chan struct{}, 10)
var wg sync.WaitGroup
var mt sync.Mutex
batchSize := 1000
total := len(keys)
if total < batchSize {
batchSize = total
}
for i := 0; i < total; i += batchSize {
wg.Add(1)
go func(start int) {
ctx := context.Background()
// 并发控制,限制同时执行的 Goroutine 数量
sem <- struct{}{}
defer func() {
<-sem
ctx.Done()
wg.Done()
}()
pipe := rdb.Pipeline()
for _, key := range keys[start : start+batchSize] {
pipe.HGetAll(ctx, key)
}
cmds, err := pipe.Exec(ctx)
if err != nil {
logger.Errorf("Failed to get hash batch exec err: %v", err)
return
}
// 将结果添加到 result map 并发访问
mt.Lock()
defer mt.Unlock()
// 处理命令结果
for _, cmd := range cmds {
if cmd.Err() != nil {
logger.Errorf("Failed to get hash batch cmds err: %v", cmd.Err())
continue
}
// 将结果转换为 *redis.StringStringMapCmd 类型
rcmd, ok := cmd.(*redis.MapStringStringCmd)
if !ok {
logger.Errorf("Failed to get hash batch type err: %v", cmd.Err())
continue
}
key := "-"
args := rcmd.Args()
if len(args) > 0 {
key = fmt.Sprint(args[1])
}
result[key] = rcmd.Val()
}
}(i)
}
wg.Wait()
return result, nil
}
// 判断是否存在
func Has(source string, keys ...string) (bool, error) {
// 数据源

View File

@@ -43,14 +43,18 @@ func (r *UDMAuthUser) dataByRedis(imsi, neId string) []model.UDMAuthUser {
if err != nil {
return arr
}
for _, key := range ausfArr {
m, err := redis.GetHash(source, key)
if err != nil {
mkv, err := redis.GetHashBatch(source, ausfArr)
if err != nil {
return arr
}
for k, m := range mkv {
if k == "-" {
continue
}
// 跳过-号数据 ausf:360000100000130
imsi := key[5:]
imsi := k[5:]
if strings.Contains(imsi, "-") {
continue
}

View File

@@ -44,14 +44,24 @@ func (r *UDMSubUser) dataByRedis(imsi, neId string) []model.UDMSubUser {
if err != nil {
return arr
}
for _, key := range udmsdArr {
m, err := redis.GetHash(source, key)
if err != nil {
mkv, err := redis.GetHashBatch(source, udmsdArr)
if err != nil {
return arr
}
for k, m := range mkv {
if k == "-" {
continue
}
// 跳过-号数据 udm-sd:360000100000130
imsi := k[7:]
if strings.Contains(imsi, "-") {
continue
}
a := model.UDMSubUser{
IMSI: key[7:], // udm-sd:360000100000130
IMSI: imsi, // udm-sd:360000100000130
MSISDN: m["gpsi"], // 8612300000130
NeId: neId,
SmfSel: m["smf-sel"], // def_snssai

View File

@@ -79,6 +79,13 @@ func (s *NeHostController) Add(c *gin.Context) {
return
}
if body.GroupID == "1" {
// 主机信息操作【%s】失败禁止操作网元
msg := i18n.TKey(language, "neHost.banNE")
c.JSON(200, result.ErrMsg(msg))
return
}
// 检查属性值唯一
uniqueHost := s.neHostService.CheckUniqueHostTitle(body.GroupID, body.Title, body.HostType, "")
if !uniqueHost {

View File

@@ -111,8 +111,28 @@ func (r *NeHost) SelectPage(query map[string]any) map[string]any {
params = append(params, pageNum*pageSize)
params = append(params, pageSize)
// 排序
orderSql := ""
if sv, ok := query["sortField"]; ok && sv != "" {
sortSql := fmt.Sprint(sv)
if sortSql == "updateTime" {
sortSql = "update_time"
}
if sortSql == "createTime" {
sortSql = "create_time"
}
if ov, ok := query["sortOrder"]; ok && ov != "" {
if fmt.Sprint(ov) == "desc" {
sortSql += " desc "
} else {
sortSql += " asc "
}
}
orderSql = fmt.Sprintf(" order by %s ", sortSql)
}
// 查询数据
querySql := r.selectSql + whereSql + pageSql
querySql := r.selectSql + whereSql + orderSql + pageSql
results, err := datasource.RawDB("", querySql, params)
if err != nil {
logger.Errorf("query err => %v", err)

View File

@@ -18,6 +18,7 @@ var neListSort = []string{
"IMS",
"AMF",
"AUSF",
"UDR",
"UDM",
"SMF",
"PCF",

View File

@@ -149,6 +149,13 @@ func (r *NeHost) DeleteByIds(hostIds []string) (int64, error) {
return 0, fmt.Errorf("neHost.noData")
}
for _, v := range ids {
if v.GroupID == "1" {
// 主机信息操作【%s】失败禁止操作网元
return 0, fmt.Errorf("neHost.banNE")
}
}
if len(ids) == len(hostIds) {
rows := r.neHostRepository.DeleteByIds(hostIds)
return rows, nil

View File

@@ -910,22 +910,24 @@ func (r *NeInfo) neConfPara5GDataConvert(content map[string]any) map[string]stri
"DNN_IMS": basic["dnn_ims"].(string),
// external
"N2_IP": external["amfn2_ip"].(string),
"UE_POOL": external["ue_pool"].(string),
"UE_IP": ueIP,
"UE_MASK": ueMask,
"UE_CIDR": ueCicr,
"UPF_TYPE": external["upf_type"].(string), // StandardUPF LightUPF
"N3_IP": n3IP,
"N3_MASK": n3Mask,
"N3_GW": external["upfn3_gw"].(string),
"N3_PCI": external["upfn3_pci"].(string),
"N3_MAC": external["upfn3_mac"].(string),
"N6_IP": n6IP,
"N6_MASK": n6Mask,
"N6_GW": external["upfn6_gw"].(string),
"N6_PCI": external["upfn6_pci"].(string),
"N6_MAC": external["upfn6_mac"].(string),
"N2_IP": external["amfn2_ip"].(string),
"UE_POOL": external["ue_pool"].(string),
"UE_IP": ueIP,
"UE_MASK": ueMask,
"UE_CIDR": ueCicr,
"UPF_TYPE": external["upf_type"].(string), // 类型 StandardUPF LightUPF
"UPF_DRIVER_TYPE": external["upf_driver_type"].(string), // 网卡驱动 vmxnet3 host dpdk
"UPF_NIC_NAME": external["upf_card_name"].(string), // 网卡名 eth0
"N3_IP": n3IP,
"N3_MASK": n3Mask,
"N3_GW": external["upfn3_gw"].(string),
"N3_PCI": external["upfn3_pci"].(string),
"N3_MAC": external["upfn3_mac"].(string),
"N6_IP": n6IP,
"N6_MASK": n6Mask,
"N6_GW": external["upfn6_gw"].(string),
"N6_PCI": external["upfn6_pci"].(string),
"N6_MAC": external["upfn6_mac"].(string),
"SIP_IP": external["ims_sip_ip"].(string),

View File

@@ -439,6 +439,10 @@ func (r *NeVersion) operateCommand(action, neType string, neFilePaths []string)
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i '/- interfaceType: \"N3\"/,/macAddr: \"00:00:00:00:00:00\"/s/macAddr: \"00:00:00:00:00:00\"/macAddr: \"%s\"/' /usr/local/etc/upf/upfForwarder_1.yaml \n", para5GData["N3_MAC"]))
// 标准版 N6
if para5GData["UPF_TYPE"] == "StandardUPF" {
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i '/- interfaceType: \"N3\"/,/driverType: .*/s/driverType: .*/driverType: \"%s\"/' /usr/local/etc/upf/upfForwarder_1.yaml \n", para5GData["UPF_DRIVER_TYPE"]))
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i '/- interfaceType: \"N3\"/,/systemNetworkCardName: .*/s/systemNetworkCardName: .*/systemNetworkCardName: \"%s\"/' /usr/local/etc/upf/upfForwarder_1.yaml \n", para5GData["UPF_NIC_NAME"]))
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i '/- interfaceType: \"N6\"/,/driverType: .*/s/driverType: .*/driverType: \"%s\"/' /usr/local/etc/upf/upfForwarder_1.yaml \n", para5GData["UPF_DRIVER_TYPE"]))
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i '/- interfaceType: \"N6\"/,/systemNetworkCardName: .*/s/systemNetworkCardName: .*/systemNetworkCardName: \"%s\"/' /usr/local/etc/upf/upfForwarder_1.yaml \n", para5GData["UPF_NIC_NAME"]))
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i \"s/192.168.8.191/%s/g\" /usr/local/etc/upf/upfForwarder_1.yaml \n", para5GData["N6_IP"]))
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i '/- interfaceType: \"N6\"/,/ipv4Mask: 255.255.240.0/s/ipv4Mask: 255.255.240.0/ipv4Mask: %s/' /usr/local/etc/upf/upfForwarder_1.yaml \n", para5GData["N6_MASK"]))
cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo sed -i '/- interfaceType: \"N6\"/,/gatewayIpv4: 192.168.1.254/s/gatewayIpv4: 192.168.1.254/gatewayIpv4: %s/' /usr/local/etc/upf/upfForwarder_1.yaml \n", para5GData["N6_GW"]))
@@ -451,7 +455,7 @@ func (r *NeVersion) operateCommand(action, neType string, neFilePaths []string)
if para5GData["UPF_TYPE"] == "LightUPF" {
cmdStrArr = append(cmdStrArr, "sudo sed -i \"s/192.168.8.191/0.0.0.0/g\" /usr/local/etc/upf/upfForwarder_1.yaml \n")
cmdStrArr = append(cmdStrArr, "sudo sed -i \"s/type: upfd/type: tun/g\" /usr/local/etc/upf/upfForwarder_1.yaml \n")
cmdStrArr = append(cmdStrArr, "sudo sed -i 's/driverType: vmxnet3/driverType: \"\"/g' /usr/local/etc/upf/upfForwarder_1.yaml \n")
cmdStrArr = append(cmdStrArr, "sudo sed -i 's/driverType: .*/driverType: \"\"/g' /usr/local/etc/upf/upfForwarder_1.yaml \n")
}
cmdStrArr = append(cmdStrArr, fmt.Sprintf("grep -qxF '%s upf' /etc/hosts || echo '%s upf' | sudo tee -a /etc/hosts \n", para5GData["UPF_IP"], para5GData["UPF_IP"]))
cmdStrArr = append(cmdStrArr, fmt.Sprintf("grep -qxF '%s upfn3' /etc/hosts || echo '%s upfn3' | sudo tee -a /etc/hosts \n", para5GData["N3_IP"], para5GData["N3_IP"]))

View File

@@ -37,15 +37,16 @@ type IPerfController struct {
func (s *IPerfController) Version(c *gin.Context) {
language := ctx.AcceptLanguage(c)
var query struct {
NeType string `form:"neType" binding:"required"` // 网元类型
NeID string `form:"neId" binding:"required"` // 网元ID
NeType string `form:"neType" binding:"required"` // 网元类型
NeId string `form:"neId" binding:"required"` // 网元ID
Version string `form:"version" binding:"required,oneof=V2 V3"` // 版本
}
if err := c.ShouldBindQuery(&query); err != nil {
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
return
}
output, err := s.iperfService.Version(query.NeType, query.NeID)
output, err := s.iperfService.Version(query.NeType, query.NeId, query.Version)
if err != nil {
c.JSON(200, result.ErrMsg(i18n.TKey(language, err.Error())))
return
@@ -60,15 +61,16 @@ func (s *IPerfController) Version(c *gin.Context) {
func (s *IPerfController) Install(c *gin.Context) {
language := ctx.AcceptLanguage(c)
var body struct {
NeType string `json:"neType" binding:"required"` // 网元类型
NeID string `json:"neId" binding:"required"` // 网元ID
NeType string `json:"neType" binding:"required"` // 网元类型
NeId string `json:"neId" binding:"required"` // 网元ID
Version string `form:"version" binding:"required,oneof=V2 V3"` // 版本
}
if err := c.ShouldBindBodyWithJSON(&body); err != nil {
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
return
}
if err := s.iperfService.Install(body.NeType, body.NeID); err != nil {
if err := s.iperfService.Install(body.NeType, body.NeId, body.Version); err != nil {
c.JSON(200, result.ErrMsg(i18n.TKey(language, err.Error())))
return
}

View File

@@ -22,17 +22,39 @@ var NewIPerf = &IPerf{}
type IPerf struct{}
// Version 查询版本信息
func (s *IPerf) Version(meType, neId string) (string, error) {
// 检查是否安装iperf3
output, err := neService.NewNeInfo.NeRunSSHCmd(meType, neId, "iperf3 --version")
func (s *IPerf) Version(meType, neId, version string) (string, error) {
if version != "V2" && version != "V3" {
return "", fmt.Errorf("iperf version is required V2 or V3")
}
cmd := "iperf3 --version"
if version == "V2" {
cmd = "iperf -v"
}
// 网元主机的SSH客户端
sshClient, err := neService.NewNeInfo.NeRunSSHClient(meType, neId)
if err != nil {
return "", fmt.Errorf("iperf3 not installed")
return "", err
}
defer sshClient.Close()
// 检查是否安装iperf
output, err := sshClient.RunCMD(cmd)
if err != nil {
if version == "V2" && strings.HasSuffix(err.Error(), "status 1") { // V2 版本
return strings.TrimSpace(output), nil
}
return "", fmt.Errorf("iperf %s not installed", version)
}
return strings.TrimSpace(output), err
}
// Install 安装iperf3
func (s *IPerf) Install(meType, neId string) error {
func (s *IPerf) Install(meType, neId, version string) error {
if version != "V2" && version != "V3" {
return fmt.Errorf("iperf version is required V2 or V3")
}
// 网元主机的SSH客户端
sshClient, err := neService.NewNeInfo.NeRunSSHClient(meType, neId)
if err != nil {
@@ -59,6 +81,13 @@ func (s *IPerf) Install(meType, neId string) error {
depPkg = "sudo rpm -Uvh --force"
depDir = "assets/dependency/iperf3/rpm"
// yum remove iperf3 iperf3-help.noarch
} else {
return fmt.Errorf("iperf %s not supported install", version)
}
// V2版本和V3版本的安装包路径不同
if version == "V2" {
depDir = strings.Replace(depDir, "iperf3", "iperf", 1)
}
// 从 embed.FS 中读取默认配置文件内容
@@ -72,19 +101,19 @@ func (s *IPerf) Install(meType, neId string) error {
// 打开本地文件
localFile, err := assetsDir.Open(fmt.Sprintf("%s/%s", depDir, d.Name()))
if err != nil {
return fmt.Errorf("iperf3 file local error")
return fmt.Errorf("iperf %s file local error", version)
}
defer localFile.Close()
// 创建远程文件
remotePath := fmt.Sprintf("%s/%s", nePath, d.Name())
remoteFile, err := sftpClient.Client.Create(remotePath)
if err != nil {
return fmt.Errorf("iperf3 file remote error")
return fmt.Errorf("iperf %s file remote error", version)
}
defer remoteFile.Close()
// 使用 io.Copy 将嵌入的文件内容复制到目标文件
if _, err := io.Copy(remoteFile, localFile); err != nil {
return fmt.Errorf("iperf3 file copy error")
return fmt.Errorf("iperf %s file copy error", version)
}
neFilePaths = append(neFilePaths, remotePath)
}
@@ -98,7 +127,7 @@ func (s *IPerf) Install(meType, neId string) error {
// 安装软件包
pkgInstall := fmt.Sprintf("%s %s", depPkg, strings.Join(neFilePaths, " "))
if _, err := sshClient.RunCMD(pkgInstall); err != nil {
return fmt.Errorf("iperf3 install error")
return fmt.Errorf("iperf %s install error", version)
}
return err
}
@@ -108,7 +137,7 @@ func (s *IPerf) Run(client *wsModel.WSClient, reqMsg wsModel.WSRequest) {
// 必传requestId确认消息
if reqMsg.RequestID == "" {
msg := "message requestId is required"
logger.Infof("ws IPerf3 Run UID %s err: %s", client.BindUid, msg)
logger.Infof("ws IPerf Run UID %s err: %s", client.BindUid, msg)
msgByte, _ := json.Marshal(result.ErrMsg(msg))
client.MsgChan <- msgByte
return
@@ -126,7 +155,7 @@ func (s *IPerf) Run(client *wsModel.WSClient, reqMsg wsModel.WSRequest) {
time.Sleep(1 * time.Second)
client.StopChan <- struct{}{}
return
case "iperf3":
case "iperf":
// SSH会话消息接收写入会话
var command string
command, err = s.parseOptions(reqMsg.Data)
@@ -155,7 +184,7 @@ func (s *IPerf) Run(client *wsModel.WSClient, reqMsg wsModel.WSRequest) {
}
if err != nil {
logger.Warnf("ws IPerf3 Run UID %s err: %s", client.BindUid, err.Error())
logger.Warnf("ws IPerf Run UID %s err: %s", client.BindUid, err.Error())
msgByte, _ := json.Marshal(result.ErrMsg(err.Error()))
client.MsgChan <- msgByte
if err == io.EOF {
@@ -175,7 +204,8 @@ func (s *IPerf) parseOptions(reqData any) (string, error) {
msgByte, _ := json.Marshal(reqData)
var data struct {
Command string `json:"command"` // 命令字符串
Client bool `json:"client"` // 服务端或客户端,默认服务端
Version string `json:"version"` // 服务版本默认V3
Mode string `json:"mode"` // 服务端或客户端默认客户端client
Host string `json:"host"` // 客户端连接到的服务端IP地址
// Server or Client
Port int `json:"port"` // 服务端口
@@ -183,17 +213,25 @@ func (s *IPerf) parseOptions(reqData any) (string, error) {
// Server
OneOff bool `json:"oneOff"` // 只进行一次连接
// Client
UDP bool `json:"udp"` // use UDP rather than TCP
Time int `json:"time"` // 以秒为单位的传输时间(默认为 10 秒)
Reverse bool `json:"reverse"` // 以反向模式运行(服务器发送,客户端接收)
Window string `json:"window"` // 设置窗口大小/套接字缓冲区大小
UDP bool `json:"udp"` // use UDP rather than TCP
Time int `json:"time"` // 以秒为单位的传输时间(默认为 10 秒)
Reverse bool `json:"reverse"` // 以反向模式运行(服务器发送,客户端接收)
Window string `json:"window"` // 设置窗口大小/套接字缓冲区大小
Parallel int `json:"parallel"` // 运行的并行客户端流数量
Bitrate int `json:"bitrate"` // 以比特/秒为单位0 表示无限制)
}
if err := json.Unmarshal(msgByte, &data); err != nil {
logger.Warnf("ws processor parseClient err: %s", err.Error())
return "", fmt.Errorf("query data structure error")
}
if data.Version != "V3" && data.Version != "V2" {
return "", fmt.Errorf("query data version support V3 or V2")
}
command := []string{"iperf3"}
if data.Version == "V2" {
command = []string{"iperf"}
}
// 命令字符串高优先级
if data.Command != "" {
command = append(command, data.Command)
@@ -201,16 +239,14 @@ func (s *IPerf) parseOptions(reqData any) (string, error) {
return strings.Join(command, " "), nil
}
if data.Client && data.Host == "" {
if data.Mode != "client" && data.Mode != "server" {
return "", fmt.Errorf("query data mode support client or server")
}
if data.Mode == "client" && data.Host == "" {
return "", fmt.Errorf("query data client host empty")
}
if !data.Client {
command = append(command, "-s")
// Server
if data.OneOff {
command = append(command, "-1")
}
} else {
if data.Mode == "client" {
command = append(command, "-c")
command = append(command, data.Host)
// Client
@@ -220,6 +256,12 @@ func (s *IPerf) parseOptions(reqData any) (string, error) {
if data.Time > 0 {
command = append(command, fmt.Sprintf("-t %d", data.Time))
}
if data.Bitrate > 0 {
command = append(command, fmt.Sprintf("-b %d", data.Bitrate))
}
if data.Parallel > 0 {
command = append(command, fmt.Sprintf("-P %d", data.Parallel))
}
if data.Reverse {
command = append(command, "-R")
}
@@ -227,6 +269,13 @@ func (s *IPerf) parseOptions(reqData any) (string, error) {
command = append(command, fmt.Sprintf("-w %s", data.Window))
}
}
if data.Mode == "server" {
command = append(command, "-s")
// Server
if data.OneOff {
command = append(command, "-1")
}
}
// Server or Client
if data.Port > 0 {

View File

@@ -0,0 +1,69 @@
package controller
import (
"be.ems/src/framework/i18n"
"be.ems/src/framework/logger"
"be.ems/src/framework/redis"
"be.ems/src/framework/utils/ctx"
"be.ems/src/framework/vo/result"
neService "be.ems/src/modules/network_element/service"
"github.com/gin-gonic/gin"
)
// Redis 终端
//
// GET /redis?hostId=1
func (s *WSController) Redis(c *gin.Context) {
language := ctx.AcceptLanguage(c)
var query struct {
HostId string `form:"hostId" binding:"required"` // 连接主机ID
}
if err := c.ShouldBindQuery(&query); err != nil {
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
return
}
// 登录用户信息
loginUser, err := ctx.LoginUser(c)
if err != nil {
c.JSON(401, result.CodeMsg(401, i18n.TKey(language, err.Error())))
return
}
neHost := neService.NewNeHost.SelectById(query.HostId)
if neHost.HostID != query.HostId || neHost.HostType != "redis" {
// 没有可访问主机信息数据!
c.JSON(200, result.ErrMsg(i18n.TKey(language, "neHost.noData")))
return
}
// 创建链接Redis客户端
var connRedis redis.ConnRedis
neHost.CopyTo(&connRedis)
client, err := connRedis.NewClient()
if err != nil {
// 连接主机失败,请检查连接参数后重试
c.JSON(200, result.ErrMsg(i18n.TKey(language, "neHost.errByHostInfo")))
return
}
defer client.Close()
// 将 HTTP 连接升级为 WebSocket 连接
wsConn := s.wsService.UpgraderWs(c.Writer, c.Request)
if wsConn == nil {
return
}
defer wsConn.Close()
wsClient := s.wsService.ClientCreate(loginUser.UserID, nil, wsConn, client)
go s.wsService.ClientWriteListen(wsClient)
go s.wsService.ClientReadListen(wsClient, s.wsReceiveService.Redis)
// 等待停止信号
for value := range wsClient.StopChan {
s.wsService.ClientClose(wsClient.ID)
logger.Infof("ws Stop Client UID %s %s", wsClient.BindUid, value)
return
}
}

View File

@@ -4,9 +4,12 @@ import (
"encoding/json"
"fmt"
"io"
"reflect"
"strings"
"time"
"be.ems/src/framework/logger"
"be.ems/src/framework/redis"
"be.ems/src/framework/telnet"
"be.ems/src/framework/utils/ssh"
"be.ems/src/framework/vo/result"
@@ -104,7 +107,7 @@ func (s *WSReceive) Shell(client *model.WSClient, reqMsg model.WSRequest) {
command := reqMsg.Data.(string)
sshClientSession := client.ChildConn.(*ssh.SSHClientSession)
_, err = sshClientSession.Write(command)
case "ssh_resize":
case "resize":
// SSH会话窗口重置
msgByte, _ := json.Marshal(reqMsg.Data)
var data struct {
@@ -225,7 +228,7 @@ func (s *WSReceive) Telnet(client *model.WSClient, reqMsg model.WSRequest) {
command := reqMsg.Data.(string)
telnetClientSession := client.ChildConn.(*telnet.TelnetClientSession)
_, err = telnetClientSession.Write(command)
case "telnet_resize":
case "resize":
// Telnet会话窗口重置
msgByte, _ := json.Marshal(reqMsg.Data)
var data struct {
@@ -256,3 +259,76 @@ func (s *WSReceive) Telnet(client *model.WSClient, reqMsg model.WSRequest) {
client.MsgChan <- resByte
}
}
// Redis 接收终端交互业务处理
func (s *WSReceive) Redis(client *model.WSClient, reqMsg model.WSRequest) {
// 必传requestId确认消息
if reqMsg.RequestID == "" {
msg := "message requestId is required"
logger.Infof("ws Shell UID %s err: %s", client.BindUid, msg)
msgByte, _ := json.Marshal(result.ErrMsg(msg))
client.MsgChan <- msgByte
return
}
var resByte []byte
var err error
switch reqMsg.Type {
case "close":
s.close(client)
return
case "redis":
// Redis会话消息接收写入会话
command := fmt.Sprint(reqMsg.Data)
redisClientSession := client.ChildConn.(*redis.ConnRedis)
output, err := redisClientSession.RunCMD(command)
dataStr := ""
if err != nil {
dataStr = fmt.Sprintf("%s \r\n", err.Error())
} else {
// 获取结果的反射类型
resultType := reflect.TypeOf(output)
switch resultType.Kind() {
case reflect.Slice:
// 如果是切片类型需要进一步判断是否是 []string 或 []interface{}
if resultType.Elem().Kind() == reflect.String {
dataStr = fmt.Sprintf("%s \r\n", strings.Join(output.([]string), "\r\n"))
} else if resultType.Elem().Kind() == reflect.Interface {
arr := []string{}
for _, v := range output.([]any) {
arr = append(arr, fmt.Sprintf("%s", v))
}
dataStr = fmt.Sprintf("%s \r\n", strings.Join(arr, "\r\n"))
}
case reflect.Ptr:
dataStr = "\r\n"
case reflect.String, reflect.Int64:
dataStr = fmt.Sprintf("%s \r\n", output)
default:
dataStr = fmt.Sprintf("%s \r\n", output)
}
}
resByte, _ = json.Marshal(result.Ok(map[string]any{
"requestId": reqMsg.RequestID,
"data": dataStr,
}))
default:
err = fmt.Errorf("message type %s not supported", reqMsg.Type)
}
if err != nil {
logger.Warnf("ws Shell UID %s err: %s", client.BindUid, err.Error())
msgByte, _ := json.Marshal(result.ErrMsg(err.Error()))
client.MsgChan <- msgByte
if err == io.EOF {
// 等待1s后关闭连接
time.Sleep(1 * time.Second)
client.StopChan <- struct{}{}
}
return
}
if len(resByte) > 0 {
client.MsgChan <- resByte
}
}

View File

@@ -35,6 +35,11 @@ func Setup(router *gin.Engine) {
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.ws", collectlogs.BUSINESS_TYPE_OTHER)),
controller.NewWSController.Telnet,
)
wsGroup.GET("/redis",
middleware.PreAuthorize(nil),
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.ws", collectlogs.BUSINESS_TYPE_OTHER)),
controller.NewWSController.Redis,
)
wsGroup.GET("/view",
middleware.PreAuthorize(nil),
collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.ws", collectlogs.BUSINESS_TYPE_OTHER)),