Compare commits
39 Commits
2.2312.9-2
...
2.2312.10-
| Author | SHA1 | Date | |
|---|---|---|---|
| b74d0059b8 | |||
|
|
bb8d367967 | ||
|
|
ef89bb4038 | ||
| 7facc301c4 | |||
| 1433964be1 | |||
| 845720a705 | |||
| 49c3e8ce6d | |||
| e1e10fba00 | |||
| 29d4458267 | |||
| 5de91843a8 | |||
| 28e3dff6b8 | |||
| f26a1d79e5 | |||
| a10f8c2a43 | |||
| 7f37df1337 | |||
| 0a243a5089 | |||
| c0046f421d | |||
| e9c125f632 | |||
|
|
9c37c7ff91 | ||
|
|
8e83397d2d | ||
| daa42b0182 | |||
| 079a697dd8 | |||
| 7f3d376715 | |||
| 93d5ed2d61 | |||
| 6462710d63 | |||
| d6b07f89d0 | |||
| 7c09325bf7 | |||
| 38ae580d6f | |||
| 0590566eae | |||
|
|
55893741ef | ||
|
|
cc9f779957 | ||
| 2b3785361a | |||
| c708ea4215 | |||
| 491456caa0 | |||
| 374fb9b8f3 | |||
| 562244d0db | |||
| a066bb3692 | |||
| 524c316da4 | |||
|
|
6a32def83e | ||
| 4a4c2a97c9 |
20
CHANGELOG.md
20
CHANGELOG.md
@@ -1,5 +1,19 @@
|
||||
# 版本发布日志
|
||||
|
||||
## 2.2312.10-20231229
|
||||
|
||||
- 增加 OMC 与 NSSF 的 Available AMFs 和 Subscription 的查询接口代码, NSSF 的代码未完成,暂未联调,菜单未开放
|
||||
- 确定序列号(SN)方案,增加网元状态在异常情况下可显示序列号和版本号(通过保存在 ne_state 的网元状态信息获取,且 ne_state 表中必须有 3 天内的网元状态数据)
|
||||
- 调整优化获取网元状态命令的超时时长,优化网元状态主页的等待时间
|
||||
- BA 需求:增加网元在新增和修改时配置数据同步至网元的开关功能
|
||||
- 增加调度任务:删除过期网元状态信息
|
||||
- 移植调度任务:原有 crontask 的周期获取网元状态信息
|
||||
- 移植调度任务:原有 crontask 的检测网元状态异常并产生和消除告警的定时任务
|
||||
- 开放 IMS 的 MML 命令
|
||||
- 移除 installOMC.sh 脚本
|
||||
- 新增 支持 UDM 用户数据删除多个 imsi
|
||||
- 修复 调度任务日志查询记录数据重复问题
|
||||
|
||||
## 2.2312.9-20231222
|
||||
|
||||
- 新增 性能 KPI 统计数据获取接口
|
||||
@@ -11,6 +25,6 @@
|
||||
- 优化 UDM 用户数据同步信息及时更新
|
||||
- 优化 获取网元状态接口请求耗时过长
|
||||
- 优化 用户管理导入支持预先分别角色权限
|
||||
- 增加setomc.sh脚本,命令行格式:setomc.sh -m {install/upgrade/upgvue3} -c {BA/...}, -m参数调用了importdb.sh, -c参数加"BA"表示设置BA的定制化OMC配置, 默认不执行定制化过程
|
||||
- 暂时屏蔽IMS网元的MML命令
|
||||
- UDM签约用户数据增加/批量增加MML的字段4G static IP改为非必选
|
||||
- 增加 setomc.sh 脚本,命令行格式:setomc.sh -m {install/upgrade/upgvue3} -c {BA/...}, -m 参数调用了 importdb.sh, -c 参数加"BA"表示设置 BA 的定制化 OMC 配置, 默认不执行定制化过程
|
||||
- 暂时屏蔽 IMS 网元的 MML 命令
|
||||
- UDM 签约用户数据增加/批量增加 MML 的字段 4G static IP 改为非必选
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Makefile for rest agent project
|
||||
|
||||
PROJECT = OMC
|
||||
VERSION = 2.2312.9
|
||||
VERSION = 2.2312.10
|
||||
PLATFORM = amd64
|
||||
ARMPLATFORM = aarch64
|
||||
BUILDDIR = ../../build
|
||||
|
||||
@@ -93,7 +93,7 @@ omc:
|
||||
vendor: ""
|
||||
dn: 4600
|
||||
chk2ne: false
|
||||
sn: 13750650
|
||||
sn: "-"
|
||||
checksign: false
|
||||
rootDir: /usr/local/omc
|
||||
binDir: /usr/local/omc/bin
|
||||
@@ -128,7 +128,7 @@ alarm:
|
||||
signName: XXX SMSC
|
||||
templateCode: 1000
|
||||
|
||||
#User authorized information
|
||||
# User authorized information
|
||||
# crypt: mysql/md5/bcrypt
|
||||
# token: true/false to check accessToken
|
||||
# expires for session, unit: second
|
||||
|
||||
@@ -89,7 +89,7 @@ tasks:
|
||||
at: 00:30:00
|
||||
do: TaskDBBackupCSVGetBySQL
|
||||
- name: handshake to NF
|
||||
status: Active
|
||||
status: Inactive
|
||||
uri: /api/rest/systemManagement/v1/elementType/%s/objectType/systemState
|
||||
params:
|
||||
interval: 10
|
||||
@@ -128,7 +128,7 @@ tasks:
|
||||
at: 00:30
|
||||
do: TaskGenLicenseAlarm
|
||||
- name: Task of Generate NE system state alarm
|
||||
status: Active
|
||||
status: Inactive
|
||||
uri: /api/rest/faultManagement/v1/elementType/%s/objectType/alarms
|
||||
params: 10000
|
||||
interval: 5
|
||||
|
||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -5,5 +5,5 @@ ims:
|
||||
- operation: "help"
|
||||
object: ""
|
||||
display: "List IMS MML CMD"
|
||||
status: "Inactive"
|
||||
status: "Active"
|
||||
params:
|
||||
|
||||
@@ -212,14 +212,7 @@
|
||||
{
|
||||
"name": "orig_severity",
|
||||
"display": "Original severity",
|
||||
"length": 11,
|
||||
"alias": [
|
||||
"Critical",
|
||||
"Major",
|
||||
"Minor",
|
||||
"Warning",
|
||||
"Event"
|
||||
]
|
||||
"length": 11
|
||||
},
|
||||
{
|
||||
"name": "pv_flag",
|
||||
@@ -239,7 +232,7 @@
|
||||
"retFmt": "GetDB",
|
||||
"retMsg": "RetCode = %d operation succeeded\n\n",
|
||||
"errMsg": "ErrorCode = %d operation failed: %s\n\n",
|
||||
"title": "Alarm Information",
|
||||
"title": "Performance Task Information",
|
||||
"singleList": true,
|
||||
"sepSpaceNum": 2,
|
||||
"alignmentM": "Left",
|
||||
|
||||
@@ -114,6 +114,20 @@ ims:
|
||||
filter: ''
|
||||
display: "Dispatch System IPv4"
|
||||
comment: ""
|
||||
- name: "internalSMSInd"
|
||||
type: "bool"
|
||||
value: 'false'
|
||||
access: "read-write"
|
||||
filter: 'false;true;'
|
||||
display: "Internal SMS Indicator"
|
||||
comment: ""
|
||||
- name: "pcfIP"
|
||||
type: "ipv4"
|
||||
value: "172.16.5.140"
|
||||
access: "read-write"
|
||||
filter: ''
|
||||
display: "PCF IP Address"
|
||||
comment: ""
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -97,17 +97,17 @@ udm:
|
||||
display: "Name"
|
||||
comment: "1~32"
|
||||
- name: "uplink"
|
||||
type: "string"
|
||||
type: "regex"
|
||||
value: '1Gbps'
|
||||
access: "read-write"
|
||||
filter: '^\d+(\.\d+)?( ?)(bps|Kbps|Mbps|Gbps|Tbps)$'
|
||||
filter: '^\d+(\.\d+)?( )(bps|Kbps|Mbps|Gbps|Tbps)$'
|
||||
display: "Uplink"
|
||||
comment: ""
|
||||
- name: "downlink"
|
||||
type: "string"
|
||||
type: "regex"
|
||||
value: '2Gbps'
|
||||
access: "read-write"
|
||||
filter: '^\d+(\.\d+)?( ?)(bps|Kbps|Mbps|Gbps|Tbps)$'
|
||||
filter: '^\d+(\.\d+)?( )(bps|Kbps|Mbps|Gbps|Tbps)$'
|
||||
display: "Downlink"
|
||||
comment: ""
|
||||
subsNssais:
|
||||
|
||||
@@ -95,7 +95,7 @@ func XormGetNeInfoByType(neType string, nes *[]NeInfo) (*[]NeInfo, error) {
|
||||
log.Debug("XormGetNeInfoByType processing... ")
|
||||
|
||||
ne := new(NeInfo)
|
||||
rows, err := dbClient.xEngine.Table("ne_info").Where("status=0 and ne_type =?", neType).Rows(ne)
|
||||
rows, err := dbClient.xEngine.Table("ne_info").Where("status in ('0','3') and ne_type =?", neType).Rows(ne)
|
||||
if err != nil {
|
||||
log.Error("Failed to get table ne_info from database:", err)
|
||||
return nil, err
|
||||
@@ -139,7 +139,7 @@ type NeState struct {
|
||||
Id int `json:"id" xorm:"pk 'id' autoincr"`
|
||||
NeType string `json:"neType" xorm:"ne_type"`
|
||||
NeId string `json:"neId" xorm:"ne_id"`
|
||||
Version string `json:"version" xorm:"version"`
|
||||
Version string `json:"version" xorm:"column 'version' VARCHAR(16)"`
|
||||
Capability uint32 `json:"capability" xorm:"capability"`
|
||||
SerialNum string `json:"serialNum" xorm:"serial_num"`
|
||||
ExpiryDate string `json:"expiryDate" xorm:"expiry_date"`
|
||||
@@ -157,7 +157,13 @@ func XormInsertNeState(neState *NeState) (int64, error) {
|
||||
session := dbClient.xEngine.NewSession()
|
||||
defer session.Close()
|
||||
affected, err := session.InsertOne(neState)
|
||||
session.Commit()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
err = session.Commit()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return affected, err
|
||||
}
|
||||
|
||||
|
||||
@@ -101,7 +101,7 @@ tasks:
|
||||
at: 00:30:00
|
||||
do: TaskDBBackupCSVGetBySQL
|
||||
- name: handshake to NF
|
||||
status: Active
|
||||
status: Inactive
|
||||
uri: /api/rest/systemManagement/v1/elementType/%s/objectType/systemState
|
||||
params:
|
||||
interval: 10
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Makefile for OMC-OMC-crontask project
|
||||
|
||||
PROJECT = OMC
|
||||
VERSION = 2.2312.9
|
||||
VERSION = 2.2312.10
|
||||
LIBDIR = ems.agt/lib
|
||||
BINNAME = crontask
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Makefile for rest agent project
|
||||
|
||||
PROJECT = OMC
|
||||
VERSION = 2.2312.9
|
||||
VERSION = 2.2312.10
|
||||
RelDate = `date +%Y%m%d`
|
||||
Release = $(RelDate)
|
||||
RelVer = $(VERSION)-$(RelDate)
|
||||
|
||||
@@ -227,4 +227,112 @@ VALUES (
|
||||
'job.backupEtcFromNERemark'
|
||||
);
|
||||
|
||||
REPLACE INTO
|
||||
`omc_db`.`sys_job` (
|
||||
`job_id`,
|
||||
`job_name`,
|
||||
`job_group`,
|
||||
`invoke_target`,
|
||||
`target_params`,
|
||||
`cron_expression`,
|
||||
`misfire_policy`,
|
||||
`concurrent`,
|
||||
`status`,
|
||||
`save_log`,
|
||||
`create_by`,
|
||||
`create_time`,
|
||||
`update_by`,
|
||||
`update_time`,
|
||||
`remark`
|
||||
)
|
||||
VALUES (
|
||||
8,
|
||||
'job.deleteExpiredNeStateRecord',
|
||||
'SYSTEM',
|
||||
'deleteExpiredRecord',
|
||||
'{\"duration\":3,\"tableName\":\"ne_state\",\"colName\":\"timestamp\"}',
|
||||
'0 25 0 * * ?',
|
||||
'3',
|
||||
'0',
|
||||
'1',
|
||||
'1',
|
||||
'supervisor',
|
||||
1698478134842,
|
||||
'admin',
|
||||
1703668901929,
|
||||
'job.deleteExpiredNeStateRecordRemark'
|
||||
);
|
||||
|
||||
REPLACE INTO
|
||||
`omc_db`.`sys_job` (
|
||||
`job_id`,
|
||||
`job_name`,
|
||||
`job_group`,
|
||||
`invoke_target`,
|
||||
`target_params`,
|
||||
`cron_expression`,
|
||||
`misfire_policy`,
|
||||
`concurrent`,
|
||||
`status`,
|
||||
`save_log`,
|
||||
`create_by`,
|
||||
`create_time`,
|
||||
`update_by`,
|
||||
`update_time`,
|
||||
`remark`
|
||||
)
|
||||
VALUES (
|
||||
9,
|
||||
'job.getStateFromNE',
|
||||
'SYSTEM',
|
||||
'getStateFromNE',
|
||||
'',
|
||||
'0/10 * * * * ?',
|
||||
'3',
|
||||
'0',
|
||||
'1',
|
||||
'0',
|
||||
'supervisor',
|
||||
1698478134842,
|
||||
'admin',
|
||||
1703669877919,
|
||||
'job.getStateFromNERemark'
|
||||
);
|
||||
|
||||
REPLACE INTO
|
||||
`omc_db`.`sys_job` (
|
||||
`job_id`,
|
||||
`job_name`,
|
||||
`job_group`,
|
||||
`invoke_target`,
|
||||
`target_params`,
|
||||
`cron_expression`,
|
||||
`misfire_policy`,
|
||||
`concurrent`,
|
||||
`status`,
|
||||
`save_log`,
|
||||
`create_by`,
|
||||
`create_time`,
|
||||
`update_by`,
|
||||
`update_time`,
|
||||
`remark`
|
||||
)
|
||||
VALUES (
|
||||
10,
|
||||
'job.genNeStateAlarm',
|
||||
'SYSTEM',
|
||||
'genNeStateAlarm',
|
||||
'{\"AlarmID\":\"HXEMSSM10000\",\"alarmCode\":\"10000\",\"alarmTitle\":\"The system state is abnormal\",\"neType\":\"OMC\",\"alarmType\":\"EquipmentAlarm\",\"origSeverity\": \"Major\",\"objectName\":\"EMS;SystemManagement;Heartbeat\",\"objectType\":\"SystemState\",\"specificProblem\":\"Alarm cause: the system state of target NE has not been received for {threshold} seconds\", \"specificProblemID\":\"AC10000\",\"threshold\":30}',
|
||||
'0/5 * * * * ?',
|
||||
'3',
|
||||
'0',
|
||||
'1',
|
||||
'0',
|
||||
'supervisor',
|
||||
1698478134842,
|
||||
'admin',
|
||||
1703768623188,
|
||||
'Health status inspection of network elements, generating alarms in case of abnormalities.'
|
||||
);
|
||||
|
||||
SET FOREIGN_KEY_CHECKS = 1;
|
||||
@@ -323,7 +323,112 @@ WHERE
|
||||
`job_id` = 7
|
||||
AND `job_group` = 'SYSTEM';
|
||||
|
||||
-- 调度任务记录日志字段
|
||||
UPDATE `omc_db`.`sys_job` SET `save_log` = '1';
|
||||
REPLACE
|
||||
INTO `omc_db`.`sys_job` (
|
||||
`job_id`,
|
||||
`job_name`,
|
||||
`job_group`,
|
||||
`invoke_target`,
|
||||
`target_params`,
|
||||
`cron_expression`,
|
||||
`misfire_policy`,
|
||||
`concurrent`,
|
||||
`status`,
|
||||
`save_log`,
|
||||
`create_by`,
|
||||
`create_time`,
|
||||
`update_by`,
|
||||
`update_time`,
|
||||
`remark`
|
||||
)
|
||||
VALUES (
|
||||
8,
|
||||
'job.deleteExpiredNeStateRecord',
|
||||
'SYSTEM',
|
||||
'deleteExpiredRecord',
|
||||
'{\"duration\":3,\"tableName\":\"ne_state\",\"colName\":\"timestamp\"}',
|
||||
'0 25 0 * * ?',
|
||||
'3',
|
||||
'0',
|
||||
'1',
|
||||
'1',
|
||||
'supervisor',
|
||||
1698478134842,
|
||||
'admin',
|
||||
1703668901929,
|
||||
'job.deleteExpiredNeStateRecordRemark'
|
||||
);
|
||||
|
||||
REPLACE
|
||||
INTO `omc_db`.`sys_job` (
|
||||
`job_id`,
|
||||
`job_name`,
|
||||
`job_group`,
|
||||
`invoke_target`,
|
||||
`target_params`,
|
||||
`cron_expression`,
|
||||
`misfire_policy`,
|
||||
`concurrent`,
|
||||
`status`,
|
||||
`save_log`,
|
||||
`create_by`,
|
||||
`create_time`,
|
||||
`update_by`,
|
||||
`update_time`,
|
||||
`remark`
|
||||
)
|
||||
VALUES (
|
||||
9,
|
||||
'job.getStateFromNE',
|
||||
'SYSTEM',
|
||||
'getStateFromNE',
|
||||
'',
|
||||
'0/10 * * * * ?',
|
||||
'3',
|
||||
'0',
|
||||
'1',
|
||||
'0',
|
||||
'supervisor',
|
||||
1698478134842,
|
||||
'admin',
|
||||
1703669877919,
|
||||
'job.getStateFromNERemark'
|
||||
);
|
||||
|
||||
REPLACE
|
||||
INTO `omc_db`.`sys_job` (
|
||||
`job_id`,
|
||||
`job_name`,
|
||||
`job_group`,
|
||||
`invoke_target`,
|
||||
`target_params`,
|
||||
`cron_expression`,
|
||||
`misfire_policy`,
|
||||
`concurrent`,
|
||||
`status`,
|
||||
`save_log`,
|
||||
`create_by`,
|
||||
`create_time`,
|
||||
`update_by`,
|
||||
`update_time`,
|
||||
`remark`
|
||||
)
|
||||
VALUES (
|
||||
10,
|
||||
'job.genNeStateAlarm',
|
||||
'SYSTEM',
|
||||
'genNeStateAlarm',
|
||||
'{\"AlarmID\":\"HXEMSSM10000\",\"alarmCode\":\"10000\",\"alarmTitle\":\"The system state is abnormal\",\"neType\":\"OMC\",\"alarmType\":\"EquipmentAlarm\",\"origSeverity\": \"Major\",\"objectName\":\"EMS;SystemManagement;Heartbeat\",\"objectType\":\"SystemState\",\"specificProblem\":\"Alarm cause: the system state of target NE has not been received for {threshold} seconds\", \"specificProblemID\":\"AC10000\",\"threshold\":30}',
|
||||
'0/5 * * * * ?',
|
||||
'3',
|
||||
'0',
|
||||
'1',
|
||||
'0',
|
||||
'supervisor',
|
||||
1698478134842,
|
||||
'admin',
|
||||
1703768623188,
|
||||
'Health status inspection of network elements, generating alarms in case of abnormalities.'
|
||||
);
|
||||
|
||||
SET FOREIGN_KEY_CHECKS = 1;
|
||||
@@ -43,8 +43,28 @@ var (
|
||||
CustomUriNeInstance = config.UriPrefix + "/systemManagement/{apiVersion}/elementType/{elementTypeValue}/objectType/instance/{action}"
|
||||
)
|
||||
|
||||
func init() {
|
||||
const (
|
||||
NEStatusActive = 0
|
||||
NEStatusOffline = 1
|
||||
NEStatusStandby = 2
|
||||
NEStatusMaintain = 3
|
||||
)
|
||||
|
||||
var client = resty.New()
|
||||
|
||||
func init() {
|
||||
/*
|
||||
client.
|
||||
SetTimeout(10 * time.Second).
|
||||
SetRetryCount(1).
|
||||
SetRetryWaitTime(1 * time.Second).
|
||||
SetRetryMaxWaitTime(2 * time.Second).
|
||||
SetRetryAfter(func(client *resty.Client, resp *resty.Response) (time.Duration, error) {
|
||||
return 0, errors.New("quota exceeded")
|
||||
})
|
||||
*/
|
||||
client.
|
||||
SetTimeout(time.Duration(1 * time.Second))
|
||||
}
|
||||
|
||||
func GetNeInfo(w http.ResponseWriter, r *http.Request) {
|
||||
@@ -69,7 +89,7 @@ func GetNeInfo(w http.ResponseWriter, r *http.Request) {
|
||||
neInfo, err := dborm.XormGetNeInfo(neType, neId)
|
||||
if err != nil {
|
||||
log.Error("dborm.XormGetNeInfo is failed:", err)
|
||||
services.ResponseInternalServerError500DatabaseOperationFailed(w)
|
||||
services.ResponseInternalServerError500ProcessError(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -105,9 +125,10 @@ func PostNeInfo(w http.ResponseWriter, r *http.Request) {
|
||||
services.ResponseNotFound404UriNotExist(w, r)
|
||||
return
|
||||
}
|
||||
syncFlag := services.GetUriParamString(r, "sync2ne", ",", false, false)
|
||||
body, err := io.ReadAll(io.LimitReader(r.Body, global.RequestBodyMaxLen))
|
||||
if err != nil {
|
||||
log.Error("io.ReadAll is failed:", err)
|
||||
log.Error("Failed to o.ReadAll:", err)
|
||||
services.ResponseNotFound404UriNotExist(w, r)
|
||||
return
|
||||
}
|
||||
@@ -123,41 +144,13 @@ func PostNeInfo(w http.ResponseWriter, r *http.Request) {
|
||||
neInfo.UpdateTime = time.Now().Format(time.DateTime)
|
||||
log.Debug("NE info:", neInfo)
|
||||
|
||||
hostUri := global.CombineHostUri(neInfo.Ip, neInfo.Port)
|
||||
//hostUri := fmt.Sprintf("http://%s:%v", neInfo.Ip, neInfo.Port)
|
||||
apiUri := fmt.Sprintf(UriParamOmcNeConfig, strings.ToLower(neInfo.NeType))
|
||||
requestURI2NF := fmt.Sprintf("%s%s", hostUri, apiUri)
|
||||
log.Debug("requestURI2NF:", requestURI2NF)
|
||||
|
||||
omcNeConfig := &OmcNeConfig{
|
||||
NeId: neInfo.NeId,
|
||||
RmUID: neInfo.RmUID,
|
||||
NeName: neInfo.NeName,
|
||||
PvFlag: neInfo.PvFlag,
|
||||
Province: neInfo.Province,
|
||||
VendorName: neInfo.VendorName,
|
||||
Dn: neInfo.Dn,
|
||||
}
|
||||
body, _ = json.Marshal(omcNeConfig)
|
||||
client := resty.New()
|
||||
response, err := client.R().
|
||||
EnableTrace().
|
||||
SetHeaders(map[string]string{"User-Agent": config.GetDefaultUserAgent()}).
|
||||
SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
|
||||
SetBody(body).
|
||||
Put(requestURI2NF)
|
||||
if err != nil {
|
||||
log.Error("Failed to Put:", err)
|
||||
services.ResponseInternalServerError500NFConnectRefused(w)
|
||||
return
|
||||
}
|
||||
log.Info("StatusCode: ", response.StatusCode())
|
||||
|
||||
if !config.GetYamlConfig().OMC.Chk2Ne {
|
||||
//if !config.GetYamlConfig().OMC.Chk2Ne {
|
||||
if syncFlag == "false" {
|
||||
neInfo.Status = NEStatusMaintain
|
||||
affected, err := dborm.XormInsertNeInfo(neInfo)
|
||||
if err != nil {
|
||||
log.Error("Failed to insert Ne info:", err)
|
||||
services.ResponseInternalServerError500DatabaseOperationFailed(w)
|
||||
services.ResponseInternalServerError500ProcessError(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -167,13 +160,43 @@ func PostNeInfo(w http.ResponseWriter, r *http.Request) {
|
||||
services.ResponseWithJson(w, http.StatusOK, mapRow)
|
||||
return
|
||||
} else {
|
||||
hostUri := global.CombineHostUri(neInfo.Ip, neInfo.Port)
|
||||
//hostUri := fmt.Sprintf("http://%s:%v", neInfo.Ip, neInfo.Port)
|
||||
apiUri := fmt.Sprintf(UriParamOmcNeConfig, strings.ToLower(neInfo.NeType))
|
||||
requestURI2NF := fmt.Sprintf("%s%s", hostUri, apiUri)
|
||||
log.Debug("requestURI2NF:", requestURI2NF)
|
||||
|
||||
omcNeConfig := &OmcNeConfig{
|
||||
NeId: neInfo.NeId,
|
||||
RmUID: neInfo.RmUID,
|
||||
NeName: neInfo.NeName,
|
||||
PvFlag: neInfo.PvFlag,
|
||||
Province: neInfo.Province,
|
||||
VendorName: neInfo.VendorName,
|
||||
Dn: neInfo.Dn,
|
||||
}
|
||||
body, _ = json.Marshal(omcNeConfig)
|
||||
response, err := client.R().
|
||||
EnableTrace().
|
||||
SetHeaders(map[string]string{"User-Agent": config.GetDefaultUserAgent()}).
|
||||
SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
|
||||
SetBody(body).
|
||||
Put(requestURI2NF)
|
||||
if err != nil {
|
||||
log.Error("Failed to Put:", err)
|
||||
services.ResponseInternalServerError500ProcessError(w, err)
|
||||
return
|
||||
}
|
||||
log.Info("StatusCode: ", response.StatusCode())
|
||||
|
||||
respMsg := make(map[string]interface{})
|
||||
switch response.StatusCode() {
|
||||
case http.StatusOK, http.StatusCreated, http.StatusNoContent, http.StatusAccepted:
|
||||
neInfo.Status = NEStatusActive
|
||||
affected, err := dborm.XormInsertNeInfo(neInfo)
|
||||
if err != nil {
|
||||
log.Error("Failed to dborm.XormInsertNeInfo:", err)
|
||||
services.ResponseInternalServerError500DatabaseOperationFailed(w)
|
||||
services.ResponseInternalServerError500ProcessError(w, err)
|
||||
return
|
||||
} else if affected <= 0 {
|
||||
log.Infof("Not record affected to insert ne_info")
|
||||
@@ -208,9 +231,10 @@ func PutNeInfo(w http.ResponseWriter, r *http.Request) {
|
||||
services.ResponseNotFound404UriNotExist(w, r)
|
||||
return
|
||||
}
|
||||
syncFlag := services.GetUriParamString(r, "sync2ne", ",", false, false)
|
||||
body, err := io.ReadAll(io.LimitReader(r.Body, global.RequestBodyMaxLen))
|
||||
if err != nil {
|
||||
log.Error("io.ReadAll is failed:", err)
|
||||
log.Error("Failed to io.ReadAll:", err)
|
||||
services.ResponseNotFound404UriNotExist(w, r)
|
||||
return
|
||||
}
|
||||
@@ -221,41 +245,13 @@ func PutNeInfo(w http.ResponseWriter, r *http.Request) {
|
||||
neInfo.UpdateTime = time.Now().Format(time.DateTime)
|
||||
log.Debug("NE info:", neInfo)
|
||||
|
||||
hostUri := global.CombineHostUri(neInfo.Ip, neInfo.Port)
|
||||
//hostUri := fmt.Sprintf("http://%s:%v", neInfo.Ip, neInfo.Port)
|
||||
apiUri := fmt.Sprintf(UriParamOmcNeConfig, strings.ToLower(neType))
|
||||
requestURI2NF := fmt.Sprintf("%s%s", hostUri, apiUri)
|
||||
log.Debug("requestURI2NF:", requestURI2NF)
|
||||
|
||||
omcNeConfig := &OmcNeConfig{
|
||||
NeId: neInfo.NeId,
|
||||
RmUID: neInfo.RmUID,
|
||||
NeName: neInfo.NeName,
|
||||
PvFlag: neInfo.PvFlag,
|
||||
Province: neInfo.Province,
|
||||
VendorName: neInfo.VendorName,
|
||||
Dn: neInfo.Dn,
|
||||
}
|
||||
body, _ = json.Marshal(omcNeConfig)
|
||||
client := resty.New()
|
||||
response, err := client.R().
|
||||
EnableTrace().
|
||||
SetHeaders(map[string]string{"User-Agent": config.GetDefaultUserAgent()}).
|
||||
SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
|
||||
SetBody(body).
|
||||
Put(requestURI2NF)
|
||||
if err != nil {
|
||||
log.Error("Failed to Put:", err)
|
||||
services.ResponseInternalServerError500NFConnectRefused(w)
|
||||
return
|
||||
}
|
||||
log.Info("StatusCode: ", response.StatusCode())
|
||||
|
||||
if !config.GetYamlConfig().OMC.Chk2Ne {
|
||||
//if !config.GetYamlConfig().OMC.Chk2Ne {
|
||||
if syncFlag == "false" {
|
||||
neInfo.Status = NEStatusMaintain
|
||||
affected, err := dborm.XormUpdateNeInfo(neInfo)
|
||||
if err != nil {
|
||||
log.Error("Failed to update Ne info:", err)
|
||||
services.ResponseInternalServerError500DatabaseOperationFailed(w)
|
||||
services.ResponseInternalServerError500ProcessError(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -265,13 +261,43 @@ func PutNeInfo(w http.ResponseWriter, r *http.Request) {
|
||||
services.ResponseWithJson(w, http.StatusOK, mapRow)
|
||||
return
|
||||
} else {
|
||||
hostUri := global.CombineHostUri(neInfo.Ip, neInfo.Port)
|
||||
//hostUri := fmt.Sprintf("http://%s:%v", neInfo.Ip, neInfo.Port)
|
||||
apiUri := fmt.Sprintf(UriParamOmcNeConfig, strings.ToLower(neType))
|
||||
requestURI2NF := fmt.Sprintf("%s%s", hostUri, apiUri)
|
||||
log.Debug("requestURI2NF:", requestURI2NF)
|
||||
|
||||
omcNeConfig := &OmcNeConfig{
|
||||
NeId: neInfo.NeId,
|
||||
RmUID: neInfo.RmUID,
|
||||
NeName: neInfo.NeName,
|
||||
PvFlag: neInfo.PvFlag,
|
||||
Province: neInfo.Province,
|
||||
VendorName: neInfo.VendorName,
|
||||
Dn: neInfo.Dn,
|
||||
}
|
||||
body, _ = json.Marshal(omcNeConfig)
|
||||
response, err := client.R().
|
||||
EnableTrace().
|
||||
SetHeaders(map[string]string{"User-Agent": config.GetDefaultUserAgent()}).
|
||||
SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
|
||||
SetBody(body).
|
||||
Put(requestURI2NF)
|
||||
if err != nil {
|
||||
log.Error("Failed to Put:", err)
|
||||
services.ResponseInternalServerError500ProcessError(w, err)
|
||||
return
|
||||
}
|
||||
log.Info("StatusCode: ", response.StatusCode())
|
||||
|
||||
respMsg := make(map[string]interface{})
|
||||
switch response.StatusCode() {
|
||||
case http.StatusOK, http.StatusCreated, http.StatusNoContent, http.StatusAccepted:
|
||||
neInfo.Status = NEStatusActive
|
||||
affected, err := dborm.XormUpdateNeInfo(neInfo)
|
||||
if err != nil {
|
||||
log.Error("Failed to dborm.XormUpdateNeInfo:", err)
|
||||
services.ResponseInternalServerError500DatabaseOperationFailed(w)
|
||||
services.ResponseInternalServerError500ProcessError(w, err)
|
||||
return
|
||||
} else if affected <= 0 {
|
||||
log.Infof("Not record affected to insert ne_info")
|
||||
@@ -321,7 +347,7 @@ func DeleteNeInfo(w http.ResponseWriter, r *http.Request) {
|
||||
neInfo, err = dborm.XormGetNeInfo(neInfo.NeType, neInfo.NeId)
|
||||
if err != nil || neInfo == nil {
|
||||
log.Error("Failed to delete Ne info:", err)
|
||||
services.ResponseInternalServerError500DatabaseOperationFailed(w)
|
||||
services.ResponseInternalServerError500ProcessError(w, err)
|
||||
return
|
||||
}
|
||||
log.Debug("NE info:", neInfo)
|
||||
@@ -331,7 +357,7 @@ func DeleteNeInfo(w http.ResponseWriter, r *http.Request) {
|
||||
affected, err := dborm.XormDeleteNeInfo(neInfo)
|
||||
if err != nil {
|
||||
log.Error("Failed to delete Ne info:", err)
|
||||
services.ResponseInternalServerError500DatabaseOperationFailed(w)
|
||||
services.ResponseInternalServerError500ProcessError(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -353,7 +379,6 @@ func IsActiveNF(neInfo *dborm.NeInfo) bool {
|
||||
requestURI := fmt.Sprintf(config.UriPrefix+"/systemManagement/v1/elementType/%s/objectType/systemState",
|
||||
strings.ToLower(neInfo.NeType))
|
||||
|
||||
client := resty.New()
|
||||
response, err := client.R().
|
||||
EnableTrace().
|
||||
SetHeaders(map[string]string{"User-Agent": config.GetDefaultUserAgent()}).
|
||||
@@ -361,6 +386,7 @@ func IsActiveNF(neInfo *dborm.NeInfo) bool {
|
||||
Get(hostUri + requestURI)
|
||||
if err != nil {
|
||||
log.Error("Failed to Get:", err)
|
||||
return false
|
||||
}
|
||||
|
||||
switch response.StatusCode() {
|
||||
@@ -395,7 +421,7 @@ func ExportCmFromNF(w http.ResponseWriter, r *http.Request) {
|
||||
neInfo, err := dborm.XormGetNeInfo(neType, neId)
|
||||
if err != nil {
|
||||
log.Errorf("Failed to get ne_info:", err)
|
||||
services.ResponseInternalServerError500DatabaseOperationFailed(w)
|
||||
services.ResponseInternalServerError500ProcessError(w, err)
|
||||
return
|
||||
}
|
||||
log.Debug("neInfo:", neInfo)
|
||||
@@ -561,7 +587,7 @@ func ImportCmToNF(w http.ResponseWriter, r *http.Request) {
|
||||
neInfo, err := dborm.XormGetNeInfo(neType, neId)
|
||||
if err != nil {
|
||||
log.Errorf("Failed to get ne_info:", err)
|
||||
services.ResponseInternalServerError500DatabaseOperationFailed(w)
|
||||
services.ResponseInternalServerError500ProcessError(w, err)
|
||||
return
|
||||
}
|
||||
log.Debug("neInfo:", neInfo)
|
||||
@@ -802,7 +828,7 @@ func PostNeServiceAction(w http.ResponseWriter, r *http.Request) {
|
||||
neInfo, err := dborm.XormGetNeInfo(neType, neId)
|
||||
if err != nil {
|
||||
log.Error("Failed to get ne_info:", err)
|
||||
services.ResponseInternalServerError500DatabaseOperationFailed(w)
|
||||
services.ResponseInternalServerError500ProcessError(w, err)
|
||||
return
|
||||
}
|
||||
log.Debug("neInfo:", neInfo)
|
||||
@@ -888,7 +914,7 @@ func PostNeInstanceAction(w http.ResponseWriter, r *http.Request) {
|
||||
neInfo, err := dborm.XormGetNeInfo(neType, neId)
|
||||
if err != nil {
|
||||
log.Errorf("Failed to get ne_info:", err)
|
||||
services.ResponseInternalServerError500DatabaseOperationFailed(w)
|
||||
services.ResponseInternalServerError500ProcessError(w, err)
|
||||
return
|
||||
}
|
||||
log.Debug("neInfo:", neInfo)
|
||||
|
||||
@@ -23,8 +23,10 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
AlarmStatusClear = 0
|
||||
AlarmStatusActive = 1
|
||||
AlarmStatusClear = 0
|
||||
AlarmStatusActive = 1
|
||||
AlarmStatusClearString = "0"
|
||||
AlarmStatusActiveString = "1"
|
||||
)
|
||||
|
||||
const (
|
||||
|
||||
@@ -264,6 +264,80 @@ func PostMMLToNF(w http.ResponseWriter, r *http.Request) {
|
||||
// mmlResult = append(mmlResult, "COMMAND OK\n")
|
||||
}
|
||||
case "ims":
|
||||
hostMML := fmt.Sprintf("%s:%d", neInfo.Ip, config.GetYamlConfig().MML.Port)
|
||||
conn, err := net.Dial("tcp", hostMML)
|
||||
if err != nil {
|
||||
errMsg := fmt.Sprintf("Failed to dial %s: %v", hostMML, err)
|
||||
log.Error(errMsg)
|
||||
mmlResult = append(mmlResult, errMsg)
|
||||
response := Response{mmlResult}
|
||||
services.ResponseWithJson(w, http.StatusOK, response)
|
||||
return
|
||||
}
|
||||
defer conn.Close()
|
||||
|
||||
// localAddr := conn.LocalAddr()
|
||||
// remoteAddr := conn.RemoteAddr()
|
||||
// if localAddr == nil || remoteAddr == nil {
|
||||
// errMsg := fmt.Sprintf("connect invalid: localAddr=%v, remoteAddr=%v", localAddr, remoteAddr)
|
||||
// log.Error(errMsg)
|
||||
// mmlResult = append(mmlResult, errMsg)
|
||||
// response := Response{mmlResult}
|
||||
// services.ResponseWithJson(w, http.StatusOK, response)
|
||||
// return
|
||||
// }
|
||||
conn.SetDeadline(time.Now().Add(10 * time.Second))
|
||||
|
||||
_, err = conn.Write([]byte(config.GetYamlConfig().MML.User + "\r\n"))
|
||||
if err != nil {
|
||||
log.Error("Failed to write:", err)
|
||||
mmlResult = append(mmlResult, err.Error())
|
||||
response := Response{mmlResult}
|
||||
services.ResponseWithJson(w, http.StatusOK, response)
|
||||
return
|
||||
}
|
||||
time.Sleep(time.Millisecond * TIME_DELAY_AFTER_WRITE)
|
||||
|
||||
n, err = conn.Read(buf[0:])
|
||||
if err != nil {
|
||||
log.Error("Failed to read:", err)
|
||||
mmlResult = append(mmlResult, err.Error())
|
||||
response := Response{mmlResult}
|
||||
services.ResponseWithJson(w, http.StatusOK, response)
|
||||
return
|
||||
}
|
||||
log.Debug(string(buf[0:n]))
|
||||
|
||||
_, err = conn.Write([]byte(config.GetYamlConfig().MML.Password + "\r\n"))
|
||||
if err != nil {
|
||||
log.Error("Failed to write:", err)
|
||||
mmlResult = append(mmlResult, err.Error())
|
||||
response := Response{mmlResult}
|
||||
services.ResponseWithJson(w, http.StatusOK, response)
|
||||
return
|
||||
}
|
||||
time.Sleep(time.Millisecond * TIME_DELAY_AFTER_WRITE)
|
||||
|
||||
// loginStr := fmt.Sprintf("%s\r\n%s\r\n", config.GetYamlConfig().MML.User, config.GetYamlConfig().MML.Password)
|
||||
// _, err = conn.Write([]byte(loginStr))
|
||||
// if err != nil {
|
||||
// log.Error("Failed to write:", err)
|
||||
// mmlResult = append(mmlResult, err.Error())
|
||||
// response := Response{mmlResult}
|
||||
// services.ResponseWithJson(w, http.StatusOK, response)
|
||||
// return
|
||||
// }
|
||||
// time.Sleep(time.Millisecond * TIME_DELAY_AFTER_WRITE)
|
||||
|
||||
n, err = conn.Read(buf[0:])
|
||||
if err != nil {
|
||||
log.Error("Failed to read:", err)
|
||||
mmlResult = append(mmlResult, err.Error())
|
||||
response := Response{mmlResult}
|
||||
services.ResponseWithJson(w, http.StatusOK, response)
|
||||
return
|
||||
}
|
||||
log.Trace(string(buf[0 : n-len(neType)-2]))
|
||||
body, err := io.ReadAll(io.LimitReader(r.Body, global.RequestBodyMaxLen))
|
||||
if err != nil {
|
||||
log.Error("io.ReadAll is failed:", err)
|
||||
@@ -276,81 +350,7 @@ func PostMMLToNF(w http.ResponseWriter, r *http.Request) {
|
||||
_ = json.Unmarshal(body, mmlRequest)
|
||||
|
||||
for _, mml := range mmlRequest.MML {
|
||||
hostMML := fmt.Sprintf("%s:%d", neInfo.Ip, config.GetYamlConfig().MML.Port)
|
||||
conn, err := net.Dial("tcp", hostMML)
|
||||
if err != nil {
|
||||
errMsg := fmt.Sprintf("Failed to dial %s: %v", hostMML, err)
|
||||
log.Error(errMsg)
|
||||
mmlResult = append(mmlResult, errMsg)
|
||||
response := Response{mmlResult}
|
||||
services.ResponseWithJson(w, http.StatusOK, response)
|
||||
return
|
||||
}
|
||||
defer conn.Close()
|
||||
|
||||
// localAddr := conn.LocalAddr()
|
||||
// remoteAddr := conn.RemoteAddr()
|
||||
// if localAddr == nil || remoteAddr == nil {
|
||||
// errMsg := fmt.Sprintf("connect invalid: localAddr=%v, remoteAddr=%v", localAddr, remoteAddr)
|
||||
// log.Error(errMsg)
|
||||
// mmlResult = append(mmlResult, errMsg)
|
||||
// response := Response{mmlResult}
|
||||
// services.ResponseWithJson(w, http.StatusOK, response)
|
||||
// return
|
||||
// }
|
||||
conn.SetDeadline(time.Now().Add(10 * time.Second))
|
||||
|
||||
_, err = conn.Write([]byte(config.GetYamlConfig().MML.User + "\n"))
|
||||
if err != nil {
|
||||
log.Error("Failed to write:", err)
|
||||
mmlResult = append(mmlResult, err.Error())
|
||||
response := Response{mmlResult}
|
||||
services.ResponseWithJson(w, http.StatusOK, response)
|
||||
return
|
||||
}
|
||||
time.Sleep(time.Millisecond * TIME_DELAY_AFTER_WRITE)
|
||||
|
||||
n, err = conn.Read(buf[0:])
|
||||
if err != nil {
|
||||
log.Error("Failed to read:", err)
|
||||
mmlResult = append(mmlResult, err.Error())
|
||||
response := Response{mmlResult}
|
||||
services.ResponseWithJson(w, http.StatusOK, response)
|
||||
return
|
||||
}
|
||||
log.Debug(string(buf[0:n]))
|
||||
|
||||
_, err = conn.Write([]byte(config.GetYamlConfig().MML.Password + "\n"))
|
||||
if err != nil {
|
||||
log.Error("Failed to write:", err)
|
||||
mmlResult = append(mmlResult, err.Error())
|
||||
response := Response{mmlResult}
|
||||
services.ResponseWithJson(w, http.StatusOK, response)
|
||||
return
|
||||
}
|
||||
time.Sleep(time.Millisecond * TIME_DELAY_AFTER_WRITE)
|
||||
|
||||
// loginStr := fmt.Sprintf("%s\n%s\n", config.GetYamlConfig().MML.User, config.GetYamlConfig().MML.Password)
|
||||
// _, err = conn.Write([]byte(loginStr))
|
||||
// if err != nil {
|
||||
// log.Error("Failed to write:", err)
|
||||
// mmlResult = append(mmlResult, err.Error())
|
||||
// response := Response{mmlResult}
|
||||
// services.ResponseWithJson(w, http.StatusOK, response)
|
||||
// return
|
||||
// }
|
||||
|
||||
n, err = conn.Read(buf[0:])
|
||||
if err != nil {
|
||||
log.Error("Failed to read:", err)
|
||||
mmlResult = append(mmlResult, err.Error())
|
||||
response := Response{mmlResult}
|
||||
services.ResponseWithJson(w, http.StatusOK, response)
|
||||
return
|
||||
}
|
||||
log.Trace(string(buf[0 : n-len(neType)-2]))
|
||||
|
||||
mmlCommand := fmt.Sprintf("%s\n", mml)
|
||||
mmlCommand := fmt.Sprintf("%s\r\n", mml)
|
||||
log.Debug("mml command:", mmlCommand)
|
||||
_, err = conn.Write([]byte(mmlCommand))
|
||||
if err != nil {
|
||||
@@ -377,11 +377,9 @@ func PostMMLToNF(w http.ResponseWriter, r *http.Request) {
|
||||
re2 := regexp.MustCompile(`[\x00-\x08\x0B\x0C\x0E-\x1F\x7F\x1B]`) // 匹配空字符和包含␛的控制字符
|
||||
//re := regexp.MustCompile(`[\x00-\x1F\x7F]`)
|
||||
// upf telnet buffer只能读取一次,需要去掉前面的多余字符
|
||||
//result := re1.ReplaceAllString(string(buf[0:n-len(neType)-2]), "")
|
||||
result := re1.ReplaceAllString(string(buf[0:]), "")
|
||||
result := re1.ReplaceAllString(string(buf[0:n-len(neType)-2]), "")
|
||||
result = re2.ReplaceAllString(result, "")
|
||||
mmlResult = append(mmlResult, result)
|
||||
conn.Close()
|
||||
}
|
||||
default:
|
||||
hostMML := fmt.Sprintf("%s:%d", neInfo.Ip, config.GetYamlConfig().MML.Port)
|
||||
|
||||
@@ -154,7 +154,12 @@ func init() {
|
||||
return 0, errors.New("quota exceeded")
|
||||
})
|
||||
*/
|
||||
client.SetTimeout(3 * time.Second)
|
||||
client.
|
||||
SetTimeout(time.Duration(400 * time.Millisecond))
|
||||
// SetRetryCount(1).
|
||||
// SetRetryWaitTime(time.Duration(1 * time.Second)).
|
||||
// SetRetryMaxWaitTime(time.Duration(2 * time.Second))
|
||||
//client.SetTimeout(2 * time.Second)
|
||||
}
|
||||
|
||||
func NeStatusEnumToStr(intStatus int) string {
|
||||
@@ -216,7 +221,7 @@ func GetOneLicenseInfoFromNF(w http.ResponseWriter, r *http.Request) {
|
||||
if neType != omcNeTypeLower {
|
||||
log.Debugf("r.RemoteAddr: %s omcNeTypeLower: %s", r.RemoteAddr, omcNeTypeLower)
|
||||
var requestURI2NF string
|
||||
if config.GetYamlConfig().OMC.TestMode == true && strings.ToLower(neType) != "udm" {
|
||||
if config.GetYamlConfig().OMC.TestMode && strings.ToLower(neType) != "udm" {
|
||||
var udmNEs []dborm.NeInfo
|
||||
err := dborm.XormGetNeInfoByNeType("UDM", &udmNEs)
|
||||
if err != nil {
|
||||
@@ -237,7 +242,7 @@ func GetOneLicenseInfoFromNF(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
log.Debug("requestURI2NF:", requestURI2NF)
|
||||
|
||||
resp, err := client.SetTimeout(time.Duration(1 * time.Second)).R().
|
||||
resp, err := client.R().
|
||||
EnableTrace().
|
||||
SetHeaders(map[string]string{tokenConst.HEADER_KEY: r.Header.Get(tokenConst.HEADER_KEY)}).
|
||||
SetHeaders(map[string]string{"accessToken": token}).
|
||||
@@ -245,7 +250,7 @@ func GetOneLicenseInfoFromNF(w http.ResponseWriter, r *http.Request) {
|
||||
SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
|
||||
Get(requestURI2NF)
|
||||
if err != nil {
|
||||
log.Error("Get system state from NF is failed:", err)
|
||||
log.Error("Failed to get system state:", err)
|
||||
services.ResponseInternalServerError500ProcessError(w, err)
|
||||
return
|
||||
} else {
|
||||
@@ -266,6 +271,9 @@ func GetOneLicenseInfoFromNF(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
//neItem := strings.ToUpper(neType) + "/" + neId
|
||||
result, err = global.ToMap(*licenseInfo, "json")
|
||||
if err != nil {
|
||||
log.Warn("Failed to map:", err)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
systemState := GetEMSState(neInfo.Ip)
|
||||
@@ -279,6 +287,9 @@ func GetOneLicenseInfoFromNF(w http.ResponseWriter, r *http.Request) {
|
||||
ExpiryDate: systemState.ExpiryDate,
|
||||
}
|
||||
result, err = global.ToMap(*licenseInfo, "json")
|
||||
if err != nil {
|
||||
log.Warn("Failed to map:", err)
|
||||
}
|
||||
// neItem := strings.ToUpper(neType) + "/" + neId
|
||||
// result[neItem] = sysInfo
|
||||
}
|
||||
@@ -306,6 +317,11 @@ func GetAllLicenseInfoFromNF(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
var neList []dborm.NeInfo
|
||||
_, err = dborm.XormGetAllNeInfo(&neList)
|
||||
if err != nil {
|
||||
log.Error("Failed to XormGetAllNeInfo:", err)
|
||||
services.ResponseInternalServerError500ProcessError(w, err)
|
||||
return
|
||||
}
|
||||
omcNeTypeLower := "omc"
|
||||
if config.GetYamlConfig().OMC.NeType != "" {
|
||||
omcNeTypeLower = strings.ToLower(config.GetYamlConfig().OMC.NeType)
|
||||
@@ -321,7 +337,7 @@ func GetAllLicenseInfoFromNF(w http.ResponseWriter, r *http.Request) {
|
||||
// requestURI2NF := fmt.Sprintf("%s/api/rest/systemManagement/v1/elementType/%s/objectType/systemState",
|
||||
// hostUri, strings.ToLower(ne.NeType))
|
||||
var requestURI2NF string
|
||||
if config.GetYamlConfig().OMC.TestMode == true && strings.ToLower(ne.NeType) != "udm" {
|
||||
if config.GetYamlConfig().OMC.TestMode && strings.ToLower(ne.NeType) != "udm" {
|
||||
var udmNEs []dborm.NeInfo
|
||||
err := dborm.XormGetNeInfoByNeType("UDM", &udmNEs)
|
||||
if err != nil {
|
||||
@@ -369,6 +385,9 @@ func GetAllLicenseInfoFromNF(w http.ResponseWriter, r *http.Request) {
|
||||
ExpiryDate: systemState.ExpiryDate,
|
||||
}
|
||||
result, err = global.ToMap(*licenseInfo, "json")
|
||||
if err != nil {
|
||||
log.Warn("Failed to map:", err)
|
||||
}
|
||||
// neItem := strings.ToUpper(ne.NeType) + "/" + ne.NeId
|
||||
// result[neItem] = sysInfo
|
||||
}
|
||||
@@ -384,6 +403,9 @@ func GetAllLicenseInfoFromNF(w http.ResponseWriter, r *http.Request) {
|
||||
ExpiryDate: systemState.ExpiryDate,
|
||||
}
|
||||
result, err = global.ToMap(*licenseInfo, "json")
|
||||
if err != nil {
|
||||
log.Warn("Failed to map:", err)
|
||||
}
|
||||
// neItem := strings.ToUpper(ne.NeType) + "/" + ne.NeId
|
||||
// result[neItem] = sysInfo
|
||||
}
|
||||
@@ -441,7 +463,7 @@ func GetOneSysinfoFromNF(w http.ResponseWriter, r *http.Request) {
|
||||
if neType != omcNeTypeLower {
|
||||
log.Debugf("r.RemoteAddr: %s omcNeTypeLower: %s", r.RemoteAddr, omcNeTypeLower)
|
||||
var requestURI2NF string
|
||||
if config.GetYamlConfig().OMC.TestMode == true && strings.ToLower(neType) != "udm" {
|
||||
if config.GetYamlConfig().OMC.TestMode && strings.ToLower(neType) != "udm" {
|
||||
var udmNEs []dborm.NeInfo
|
||||
err := dborm.XormGetNeInfoByNeType("UDM", &udmNEs)
|
||||
if err != nil {
|
||||
@@ -462,7 +484,7 @@ func GetOneSysinfoFromNF(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
log.Debug("requestURI2NF:", requestURI2NF)
|
||||
|
||||
resp, err := client.SetTimeout(time.Duration(1 * time.Second)).R().
|
||||
resp, err := client.R().
|
||||
EnableTrace().
|
||||
SetHeaders(map[string]string{tokenConst.HEADER_KEY: r.Header.Get(tokenConst.HEADER_KEY)}).
|
||||
SetHeaders(map[string]string{"accessToken": token}).
|
||||
@@ -515,6 +537,9 @@ func GetOneSysinfoFromNF(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
//neItem := strings.ToUpper(neType) + "/" + neId
|
||||
result, err = global.ToMap(*sysInfo, "json")
|
||||
if err != nil {
|
||||
log.Warn("Failed to map:", err)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
systemState := GetEMSState(neInfo.Ip)
|
||||
@@ -533,6 +558,9 @@ func GetOneSysinfoFromNF(w http.ResponseWriter, r *http.Request) {
|
||||
Status: NeStatusEnumToStr(neInfo.Status),
|
||||
}
|
||||
result, err = global.ToMap(*sysInfo, "json")
|
||||
if err != nil {
|
||||
log.Warn("Failed to map:", err)
|
||||
}
|
||||
// neItem := strings.ToUpper(neType) + "/" + neId
|
||||
// result[neItem] = sysInfo
|
||||
}
|
||||
@@ -560,6 +588,11 @@ func GetAllSysinfoFromNF(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
var neList []dborm.NeInfo
|
||||
_, err = dborm.XormGetAllNeInfo(&neList)
|
||||
if err != nil {
|
||||
log.Error("Failed to XormGetAllNeInfo:", err)
|
||||
services.ResponseInternalServerError500ProcessError(w, err)
|
||||
return
|
||||
}
|
||||
omcNeTypeLower := "omc"
|
||||
if config.GetYamlConfig().OMC.NeType != "" {
|
||||
omcNeTypeLower = strings.ToLower(config.GetYamlConfig().OMC.NeType)
|
||||
@@ -575,7 +608,7 @@ func GetAllSysinfoFromNF(w http.ResponseWriter, r *http.Request) {
|
||||
// requestURI2NF := fmt.Sprintf("%s/api/rest/systemManagement/v1/elementType/%s/objectType/systemState",
|
||||
// hostUri, strings.ToLower(ne.NeType))
|
||||
var requestURI2NF string
|
||||
if config.GetYamlConfig().OMC.TestMode == true && strings.ToLower(ne.NeType) != "udm" {
|
||||
if config.GetYamlConfig().OMC.TestMode && strings.ToLower(ne.NeType) != "udm" {
|
||||
var udmNEs []dborm.NeInfo
|
||||
err := dborm.XormGetNeInfoByNeType("UDM", &udmNEs)
|
||||
if err != nil {
|
||||
@@ -651,6 +684,9 @@ func GetAllSysinfoFromNF(w http.ResponseWriter, r *http.Request) {
|
||||
// neItem := strings.ToUpper(ne.NeType) + "/" + ne.NeId
|
||||
// result[neItem] = sysInfo
|
||||
result, err = global.ToMap(*sysInfo, "json")
|
||||
if err != nil {
|
||||
log.Warn("Failed to map:", err)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
port, _ := strconv.Atoi(ne.Port)
|
||||
@@ -672,6 +708,9 @@ func GetAllSysinfoFromNF(w http.ResponseWriter, r *http.Request) {
|
||||
// neItem := strings.ToUpper(ne.NeType) + "/" + ne.NeId
|
||||
// result[neItem] = sysInfo
|
||||
result, err = global.ToMap(*sysInfo, "json")
|
||||
if err != nil {
|
||||
log.Warn("Failed to map:", err)
|
||||
}
|
||||
}
|
||||
|
||||
data = append(data, result)
|
||||
@@ -772,7 +811,7 @@ func GetStateFromNF(w http.ResponseWriter, r *http.Request) {
|
||||
log.Debug("requestURI2NF:", requestURI2NF)
|
||||
|
||||
result["ipAddress"] = ne.Ip
|
||||
resp, err := client.SetTimeout(time.Duration(1 * time.Second)).R().
|
||||
resp, err := client.R().
|
||||
EnableTrace().
|
||||
SetHeaders(map[string]string{tokenConst.HEADER_KEY: r.Header.Get(tokenConst.HEADER_KEY)}).
|
||||
SetHeaders(map[string]string{"accessToken": token}).
|
||||
@@ -785,6 +824,9 @@ func GetStateFromNF(w http.ResponseWriter, r *http.Request) {
|
||||
ErrorCode: "1", ErrorInfo: "Internal server error, NF connnect refused",
|
||||
}
|
||||
result["error"] = errorMessage
|
||||
SN, Version, _ := dborm.XormGetNEStateInfo(ne.NeType, ne.NeId)
|
||||
result["serialNum"] = SN
|
||||
result["version"] = Version
|
||||
} else {
|
||||
systemState := make(map[string]interface{})
|
||||
_ = json.Unmarshal(resp.Body(), &systemState)
|
||||
|
||||
@@ -200,12 +200,12 @@ func XormGetNeInfo(neType string, neId string) (*NeInfo, error) {
|
||||
log.Debug("XormGetNeInfo processing... ")
|
||||
|
||||
neInfo := new(NeInfo)
|
||||
has, err := xEngine.Where("status='0' and ne_type=? and ne_id=?", strings.ToUpper(neType), neId).Get(neInfo)
|
||||
has, err := xEngine.Where("status in ('0','3') and ne_type=? and ne_id=?", strings.ToUpper(neType), neId).Get(neInfo)
|
||||
if err != nil {
|
||||
log.Error("Failed to get table ne_info from database:", err)
|
||||
return nil, err
|
||||
} else if has == false {
|
||||
log.Infof("Not found ne_info from database, status='0', neType=%s, neId=%s", neType, neId)
|
||||
} else if !has {
|
||||
log.Infof("Not found ne_info from database, status in ('0','3'), neType=%s, neId=%s", neType, neId)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
@@ -217,11 +217,11 @@ func XormGetNeInfoByRmUID(neType string, rmUID string) (*NeInfo, error) {
|
||||
log.Debug("XormGetNeInfoByRmUID processing... ")
|
||||
|
||||
neInfo := new(NeInfo)
|
||||
has, err := xEngine.Where("status='0' and ne_type=? and rm_uid=?", strings.ToUpper(neType), rmUID).Get(neInfo)
|
||||
has, err := xEngine.Where("status in ('0','3') and ne_type=? and rm_uid=?", strings.ToUpper(neType), rmUID).Get(neInfo)
|
||||
if err != nil {
|
||||
log.Error("Failed to get table ne_info from database:", err)
|
||||
return nil, err
|
||||
} else if has == false {
|
||||
} else if !has {
|
||||
log.Infof("Not found ne_info from database, status='0', neType=%s, neId=%s", neType, rmUID)
|
||||
return nil, nil
|
||||
}
|
||||
@@ -234,7 +234,7 @@ func XormGetAllNeInfo(nes *[]NeInfo) (*[]NeInfo, error) {
|
||||
log.Debug("XormGetAllNeInfo processing... ")
|
||||
|
||||
ne := new(NeInfo)
|
||||
rows, err := xEngine.Table("ne_info").Where("status='0'").Rows(ne)
|
||||
rows, err := xEngine.Table("ne_info").Where("status in ('0','3')").Rows(ne)
|
||||
if err != nil {
|
||||
log.Error("Failed to get table ne_info from database:", err)
|
||||
return nil, err
|
||||
@@ -256,7 +256,7 @@ func XormGetNeInfoByNeType(neType string, nes *[]NeInfo) error {
|
||||
log.Debug("XormGetNeInfoByNeType processing... ")
|
||||
|
||||
ne := new(NeInfo)
|
||||
rows, err := xEngine.Table("ne_info").Where("status='0' and ne_type=?", neType).Rows(ne)
|
||||
rows, err := xEngine.Table("ne_info").Where("status in ('0','3') and ne_type=?", neType).Rows(ne)
|
||||
if err != nil {
|
||||
log.Error("Failed to get table ne_info from database:", err)
|
||||
return err
|
||||
@@ -283,7 +283,7 @@ func XormInsertNeInfo(neInfo *NeInfo) (int64, error) {
|
||||
xSession := xEngine.NewSession()
|
||||
defer xSession.Close()
|
||||
ex, _ := xEngine.Table("ne_info").Where("status = '1' and ne_type = ? and ne_id = ?", neInfo.NeType, neInfo.NeId).Exist()
|
||||
if ex == true {
|
||||
if ex {
|
||||
neInfo.Status = 0
|
||||
affected, err = xSession.Where("ne_type = ? and ne_id = ?", neInfo.NeType, neInfo.NeId).Update(neInfo)
|
||||
} else {
|
||||
@@ -298,7 +298,7 @@ func XormUpdateNeInfo(neInfo *NeInfo) (int64, error) {
|
||||
|
||||
xSession := xEngine.NewSession()
|
||||
defer xSession.Close()
|
||||
affected, err := xSession.ID(neInfo.Id).Update(neInfo)
|
||||
affected, err := xSession.ID(neInfo.Id).MustCols("status").Update(neInfo)
|
||||
xSession.Commit()
|
||||
return affected, err
|
||||
}
|
||||
@@ -1124,7 +1124,9 @@ type Alarm struct {
|
||||
PVFlag string `json:"pvFlag" xorm:"pv_flag"`
|
||||
NeName string `json:"neName"`
|
||||
NeType string `json:"neType"`
|
||||
ObjectUid string `json:"objectUid" xorm:"object_uid"`
|
||||
ObjectName string `json:"objectName" xorm:"object_name"`
|
||||
ObjectType string `json:"objectType" xorm:"object_type"`
|
||||
LocationInfo string `json:"locationInfo"`
|
||||
Province string `json:"province"`
|
||||
AlarmStatus int `json:"alarmStatus"`
|
||||
@@ -1820,3 +1822,80 @@ func XormGetTraceRawMsg(id int) (int64, []byte, error) {
|
||||
|
||||
return timestamp, rawMsg, nil
|
||||
}
|
||||
|
||||
func XormGetNEStateInfo(neType, neID string) (string, string, error) {
|
||||
SN := "-"
|
||||
Version := "-"
|
||||
_, err := xEngine.Table("ne_state").
|
||||
Where("ne_type=? and ne_id=?", neType, neID).
|
||||
Desc("timestamp").
|
||||
Cols("serial_num", "version").
|
||||
Limit(1).
|
||||
Get(&SN, &Version)
|
||||
return SN, Version, err
|
||||
}
|
||||
|
||||
type NeState struct {
|
||||
Id int `json:"id" xorm:"pk 'id' autoincr"`
|
||||
NeType string `json:"neType" xorm:"ne_type"`
|
||||
NeId string `json:"neId" xorm:"ne_id"`
|
||||
Version string `json:"version" xorm:"column 'version' VARCHAR(16)"`
|
||||
Capability uint32 `json:"capability" xorm:"capability"`
|
||||
SerialNum string `json:"serialNum" xorm:"serial_num"`
|
||||
ExpiryDate string `json:"expiryDate" xorm:"expiry_date"`
|
||||
CpuUsage string `json:"cpuUsage" xorm:"cpu_usage"`
|
||||
MemUsage string `json:"memUsage" xorm:"mem_usage"`
|
||||
DiskSpace string `json:"diskSpace" xorm:"disk_space"`
|
||||
Timestamp string `json:"timestamp" xorm:"-" `
|
||||
}
|
||||
|
||||
func XormInsertNeState(neState *NeState) (int64, error) {
|
||||
log.Debug("XormInsertNeState processing... ")
|
||||
|
||||
var affected int64 = 0
|
||||
|
||||
session := xEngine.NewSession()
|
||||
defer session.Close()
|
||||
affected, err := session.InsertOne(neState)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
err = session.Commit()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return affected, err
|
||||
}
|
||||
|
||||
type AlarmDefine struct {
|
||||
AlarmId string `json:"alarmId" xorm:"alarm_id"`
|
||||
AlarmCode int `json:"alarmCode" xorm:"alarm_code"`
|
||||
AlarmTitle string `json:"alarmTitle" xorm:"alarm_title"`
|
||||
NeType string `json:"neType" xorm:"ne_type"`
|
||||
AlarmType string `json:"alarmType" xorm:"alarm_type"`
|
||||
OrigSeverity string `json:"origSeverity" xorm:"orig_severity"`
|
||||
ObjectUid string `json:"objectUid" xorm:"object_uid"`
|
||||
ObjectName string `json:"objectName" xorm:"object_name"`
|
||||
ObjectType string `json:"objectType" xorm:"object_type"`
|
||||
LocationInfo string `json:"locationInfo"`
|
||||
SpecificProblem string `json:"specificProblem"`
|
||||
SpecificProblemId string `json:"specificProblemId" xorm:"specific_problem_id"`
|
||||
AddInfo string `json:"addInfo" xorm:"add_info"`
|
||||
Threshold int64 `json:"threshold" xorm:"threshold"`
|
||||
Status string `json:"status" xorm:"status"`
|
||||
}
|
||||
|
||||
func XormGetAlarmDefine(alarmCode string) (*AlarmDefine, error) {
|
||||
log.Debug("XormGetAlarmDefine processing... ")
|
||||
|
||||
alarmDefine := new(AlarmDefine)
|
||||
_, err := xEngine.
|
||||
Where("alarm_code=? and status='Active'", alarmCode).
|
||||
Get(alarmDefine)
|
||||
if err != nil {
|
||||
log.Error("Failed to get table alarm_define from database:", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return alarmDefine, nil
|
||||
}
|
||||
|
||||
2
makefile
2
makefile
@@ -3,7 +3,7 @@
|
||||
ProjectL = omc
|
||||
ProjectU = OMC
|
||||
PROJECT = $(ProjectL)
|
||||
VERSION = 2.2312.9
|
||||
VERSION = 2.2312.10
|
||||
RelDate = `date +%Y%m%d`
|
||||
Release = $(RelDate)
|
||||
RelVer = $(VERSION)-$(RelDate)
|
||||
|
||||
@@ -1,191 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
echo "-------------------please input-------------------"
|
||||
#please input the new nf ip
|
||||
read -p "please input your OMC IP: " OMCIP
|
||||
|
||||
echo "-----------------please continue to enter-----------------"
|
||||
read -p "please input your IMS IP: " IMSIP
|
||||
|
||||
echo "-----------------please continue to enter-----------------"
|
||||
read -p "please input your AMF IP: " AMFIP
|
||||
|
||||
echo "-----------------please continue to enter-----------------"
|
||||
read -p "please input your AUSF IP: " AUSFIP
|
||||
|
||||
echo "-----------------please continue to enter-----------------"
|
||||
read -p "please input your UDM IP: " UDMIP
|
||||
|
||||
echo "-----------------please continue to enter-----------------"
|
||||
read -p "please input your SMF IP: " SMFIP
|
||||
|
||||
echo "-----------------please continue to enter-----------------"
|
||||
read -p "please input your PCF IP: " PCFIP
|
||||
|
||||
echo "-----------------please continue to enter-----------------"
|
||||
read -p "please input your NSSF IP: " NSSFIP
|
||||
|
||||
echo "-----------------please continue to enter-----------------"
|
||||
read -p "please input your NRF IP: " NRFIP
|
||||
|
||||
echo "-----------------please continue to enter-----------------"
|
||||
read -p "please input your UPF IP: " UPFIP
|
||||
|
||||
echo "-----------------please continue to enter-----------------"
|
||||
read -p "please input your MME IP: " MMEIP
|
||||
|
||||
echo "------------please continue to enter Vm account-------------"
|
||||
read -p "please input your username: " username
|
||||
|
||||
echo "------------please continue to enter Vm password-------------"
|
||||
read -p "please input your passwd: " passwd
|
||||
|
||||
cd /home/agtuser
|
||||
|
||||
#Creating a local source
|
||||
tar -xzvf omcpkg*.tar.gz
|
||||
|
||||
mv /etc/apt/sources.list /etc/apt/sources.list-bak
|
||||
|
||||
echo "deb [trusted=yes] file:/home/agtuser/omcpkg archives/" > /etc/apt/sources.list
|
||||
|
||||
sleep 1
|
||||
|
||||
apt update
|
||||
|
||||
sleep 1
|
||||
|
||||
#Database installation
|
||||
apt install -y net-tools software-properties-common
|
||||
|
||||
sleep 1
|
||||
|
||||
apt-key add mariadb_release_signing_key.asc
|
||||
|
||||
apt install -y mariadb-server
|
||||
|
||||
systemctl start mariadb
|
||||
|
||||
mysql --version
|
||||
|
||||
sudo mysql_secure_installation <<-EOF
|
||||
1000omc@kp!
|
||||
y
|
||||
n
|
||||
y
|
||||
y
|
||||
y
|
||||
y
|
||||
EOF
|
||||
|
||||
#You need to enter the password manually:1000omc@kp!
|
||||
|
||||
systemctl enable mariadb
|
||||
|
||||
systemctl restart mariadb
|
||||
|
||||
#Modify mysql datebase root password
|
||||
|
||||
#You need to run the following command
|
||||
mysql -u root <<-EOF
|
||||
use mysql
|
||||
ALTER USER root@'localhost' IDENTIFIED VIA mysql_native_password USING PASSWORD("1000omc@kp!");
|
||||
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '1000omc@kp!';
|
||||
flush privileges;
|
||||
quit
|
||||
EOF
|
||||
|
||||
sleep 5
|
||||
|
||||
|
||||
echo "port=33066" >> /etc/mysql/mariadb.conf.d/50-server.cnf
|
||||
|
||||
sed -i "s/127.0.0.1/0.0.0.0/g" /etc/mysql/mariadb.conf.d/50-server.cnf
|
||||
|
||||
systemctl restart mariadb
|
||||
|
||||
#Install WEB server
|
||||
apt update
|
||||
|
||||
apt install -y nginx
|
||||
|
||||
systemctl enable nginx
|
||||
systemctl daemon-reload
|
||||
systemctl start nginx
|
||||
|
||||
#Install and config OMC
|
||||
dpkg -i omc*.deb
|
||||
|
||||
cp /usr/local/omc/htdocs/front/default/config.js /usr/local/omc/htdocs/front/
|
||||
|
||||
sed -i "s/192.168.8.100/${OMCIP}/g" /usr/local/omc/htdocs/front/config.js
|
||||
|
||||
cp /usr/local/omc/etc/default/* /usr/local/omc/etc
|
||||
|
||||
sed -i "76s/user: root/user: ${username}/" /usr/local/omc/etc/restconf.yaml
|
||||
|
||||
#Database configuration
|
||||
/usr/local/omc/bin/importdb.sh <<-EOF
|
||||
Install
|
||||
EOF
|
||||
|
||||
#Configure the trusted gateway of the managed NE
|
||||
apt install -y expect
|
||||
|
||||
echo "${OMCIP} ${username} ${passwd}" > /usr/local/omc/bin/nehosts
|
||||
echo "${IMSIP} ${username} ${passwd}" >> /usr/local/omc/bin/nehosts
|
||||
echo "${AMFIP} ${username} ${passwd}" >> /usr/local/omc/bin/nehosts
|
||||
echo "${AUSFIP} ${username} ${passwd}" >> /usr/local/omc/bin/nehosts
|
||||
echo "${UDMIP} ${username} ${passwd}" >> /usr/local/omc/bin/nehosts
|
||||
echo "${SMFIP} ${username} ${passwd}" >> /usr/local/omc/bin/nehosts
|
||||
echo "${PCFIP} ${username} ${passwd}" >> /usr/local/omc/bin/nehosts
|
||||
echo "${NSSFIP} ${username} ${passwd}" >> /usr/local/omc/bin/nehosts
|
||||
echo "${NRFIP} ${username} ${passwd}" >> /usr/local/omc/bin/nehosts
|
||||
echo "${UPFIP} ${username} ${passwd}" >> /usr/local/omc/bin/nehosts
|
||||
echo "${MMEIP} ${username} ${passwd}" >> /usr/local/omc/bin/nehosts
|
||||
|
||||
sleep 1
|
||||
|
||||
cd /usr/local/omc/bin
|
||||
/usr/local/omc/bin/cpsshkey.sh
|
||||
|
||||
cd /home/agtuser
|
||||
|
||||
sleep 5
|
||||
|
||||
#adb server configuration
|
||||
cp /usr/local/db/bin/conf/default/redis.conf /usr/local/db/bin/conf/redis.conf
|
||||
|
||||
sed -i "s/172.16.5.140/${UDMIP}/g" /usr/local/db/bin/conf/redis.conf
|
||||
|
||||
#Modifying User Rights
|
||||
sudo echo "agtuser ALL=(ALL:ALL) NOPASSWD: ALL" >> /etc/sudoers
|
||||
sudo echo "agtuser ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
|
||||
|
||||
sudo scp /etc/sudoers ${username}@${IMSIP}:/home/agtuser
|
||||
sudo scp /etc/sudoers ${username}@${AMFIP}:/home/agtuser
|
||||
sudo scp /etc/sudoers ${username}@${AUSFIP}:/home/agtuser
|
||||
sudo scp /etc/sudoers ${username}@${UDMIP}:/home/agtuser
|
||||
sudo scp /etc/sudoers ${username}@${SMFIP}:/home/agtuser
|
||||
sudo scp /etc/sudoers ${username}@${PCFIP}:/home/agtuser
|
||||
sudo scp /etc/sudoers ${username}@${NSSFIP}:/home/agtuser
|
||||
sudo scp /etc/sudoers ${username}@${NRFIP}:/home/agtuser
|
||||
sudo scp /etc/sudoers ${username}@${UPFIP}:/home/agtuser
|
||||
sudo scp /etc/sudoers ${username}@${MMEIP}:/home/agtuser
|
||||
|
||||
#Run the following commands on each NE VM:
|
||||
#cp sudoers /etc/sudoers
|
||||
|
||||
sleep 5
|
||||
|
||||
#Service initiation
|
||||
systemctl enable restagent.service
|
||||
systemctl enable crontask.service
|
||||
systemctl daemon-reload
|
||||
|
||||
/usr/local/omc/bin//omcsvc.sh restart
|
||||
|
||||
systemctl restart nginx
|
||||
|
||||
|
||||
echo "-----------------config complete------------"
|
||||
2
mkpkg.sh
2
mkpkg.sh
@@ -2,7 +2,7 @@
|
||||
|
||||
ProcList="restagent crontask sshsvc captrace data2html"
|
||||
ProjectL=omc
|
||||
VERSION=2.2312.9
|
||||
VERSION=2.2312.10
|
||||
RelDate=`date +%Y%m%d`
|
||||
Release=${RelDate}
|
||||
RelVer=${VERSION}-${RelDate}
|
||||
|
||||
@@ -94,7 +94,7 @@ omc:
|
||||
vendor: ""
|
||||
dn: 4600
|
||||
chk2ne: false
|
||||
sn: 13750650
|
||||
sn: "-"
|
||||
checksign: false
|
||||
rootDir: ./
|
||||
binDir: ./bin
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Makefile for rest agent project
|
||||
|
||||
PROJECT = OMC
|
||||
VERSION = 2.2312.9
|
||||
VERSION = 2.2312.10
|
||||
PLATFORM = amd64
|
||||
ARMPLATFORM = aarch64
|
||||
BUILDDIR = ../../build
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# 项目信息
|
||||
framework:
|
||||
name: "CN EMS"
|
||||
version: "2.2312.9"
|
||||
version: "2.2312.10"
|
||||
|
||||
# 应用服务配置
|
||||
server:
|
||||
|
||||
@@ -14,7 +14,7 @@ import (
|
||||
)
|
||||
|
||||
/**无Token可访问白名单 */
|
||||
var URL_WHITE_LIST = []string{"/performanceManagement", "/faultManagement"}
|
||||
var URL_WHITE_LIST = []string{"/performanceManagement", "/faultManagement", "/systemState"}
|
||||
|
||||
// PreAuthorize 用户身份授权认证校验
|
||||
//
|
||||
|
||||
@@ -0,0 +1,309 @@
|
||||
package genNeStateAlarm
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"ems.agt/features/fm"
|
||||
"ems.agt/lib/dborm"
|
||||
"ems.agt/lib/global"
|
||||
"ems.agt/lib/log"
|
||||
"ems.agt/restagent/config"
|
||||
"ems.agt/src/framework/cron"
|
||||
"github.com/go-resty/resty/v2"
|
||||
)
|
||||
|
||||
var NewProcessor = &BarProcessor{
|
||||
progress: 0,
|
||||
count: 0,
|
||||
}
|
||||
|
||||
// bar 队列任务处理
|
||||
type BarProcessor struct {
|
||||
// 任务进度
|
||||
progress int
|
||||
// 执行次数
|
||||
count int
|
||||
}
|
||||
type BarParams struct {
|
||||
AlarmID string `json:"alarmID"`
|
||||
AlarmCode int `json:"alarmCode"`
|
||||
AlarmTitle string `json:"alarmTitle"`
|
||||
AlarmType string `json:"alarmType"`
|
||||
OrigSeverity string `json:"origSeverity"`
|
||||
ObjectUID string `json:"objectUID"`
|
||||
ObjectName string `json:"objectName"`
|
||||
ObjectType string `json:"objectType"`
|
||||
SpecificProblem string `json:"specificProblem"`
|
||||
SpecificProblemID string `json:"specificProblemID"`
|
||||
AddInfo string `json:"AddInfo"`
|
||||
Threshold int64 `json:"threshold"`
|
||||
}
|
||||
|
||||
// type BarParams struct {
|
||||
// Duration int `json:"duration"`
|
||||
// }
|
||||
|
||||
type Alarm struct {
|
||||
Id int `json:"-" xorm:"pk 'id' autoincr"`
|
||||
AlarmSeq int `json:"alarmSeq"`
|
||||
AlarmId string `json:"alarmId" xorm:"alarm_id"`
|
||||
NeId string `json:"neId"`
|
||||
AlarmCode int `json:"alarmCode"`
|
||||
AlarmTitle string `json:"alarmTitle"`
|
||||
EventTime string `json:"eventTime"`
|
||||
AlarmType string `json:"alarmType"`
|
||||
OrigSeverity string `json:"origSeverity"`
|
||||
PerceivedSeverity string `json:"perceivedSeverity"`
|
||||
PVFlag string `json:"pvFlag" xorm:"pv_flag"`
|
||||
NeName string `json:"neName"`
|
||||
NeType string `json:"neType"`
|
||||
ObjectUid string `json:"objectUid" xorm:"object_uid"`
|
||||
ObjectName string `json:"objectName" xorm:"object_name"`
|
||||
ObjectType string `json:"objectType" xorm:"object_type"`
|
||||
LocationInfo string `json:"locationInfo"`
|
||||
Province string `json:"province"`
|
||||
AlarmStatus int `json:"alarmStatus" xorm:"alarm_status"`
|
||||
SpecificProblem string `json:"specificProblem"`
|
||||
SpecificProblemID string `json:"specificProblemID" xorm:"specific_problem_id"`
|
||||
AddInfo string `json:"addInfo"`
|
||||
|
||||
// ClearType int `json:"-" xorm:"clear_type"` // 0: Unclear, 1: Auto clear, 2: Manual clear
|
||||
// ClearTime sql.NullTime `json:"-" xorm:"clear_time"`
|
||||
}
|
||||
|
||||
var client = resty.New()
|
||||
|
||||
func init() {
|
||||
client.
|
||||
SetTimeout(time.Duration(400 * time.Millisecond))
|
||||
}
|
||||
|
||||
func (s *BarProcessor) Execute(data any) (any, error) {
|
||||
var err error
|
||||
|
||||
s.count++
|
||||
options := data.(cron.JobData)
|
||||
sysJob := options.SysJob
|
||||
var alarmDefine BarParams
|
||||
|
||||
err = json.Unmarshal([]byte(sysJob.TargetParams), &alarmDefine)
|
||||
if err == nil {
|
||||
log.Error("Failed to Unmarshal:", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var nes []dborm.NeInfo
|
||||
_, err = dborm.XormGetAllNeInfo(&nes)
|
||||
if err != nil {
|
||||
log.Error("Failed to get all ne info:", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
succActiveAlarmNum := 0
|
||||
failActiveAlarmNum := 0
|
||||
succClearAlarmNum := 0
|
||||
failClearAlarmNum := 0
|
||||
|
||||
for _, ne := range nes {
|
||||
//log.Debug("ne:", ne)
|
||||
|
||||
sql := fmt.Sprintf("select * from ne_state where ne_type = '%s' and ne_id = '%s' order by timestamp desc limit 1", ne.NeType, ne.NeId)
|
||||
neState, err := dborm.XormGetDataBySQL(sql)
|
||||
if err != nil {
|
||||
log.Error("Failed to get ne_state:", err)
|
||||
continue
|
||||
}
|
||||
if len(*neState) == 0 {
|
||||
log.Warn("Not found record in ne_state:")
|
||||
continue
|
||||
}
|
||||
//log.Debug("neState:", *neState)
|
||||
|
||||
// params := "10000"
|
||||
|
||||
// alarmDefine, err := dborm.XormGetAlarmDefine(params)
|
||||
// if err != nil {
|
||||
// log.Error("Failed to get alarm_define:", err)
|
||||
// continue
|
||||
// } else if alarmDefine == nil {
|
||||
// log.Error("Not found data from alarm_define")
|
||||
// continue
|
||||
// }
|
||||
|
||||
// log.Debug("alarmDefine:", alarmDefine)
|
||||
|
||||
sql = fmt.Sprintf("select * from alarm where alarm_id = '%s' and ne_type='%s' and ne_id = '%s' order by event_time desc limit 1",
|
||||
alarmDefine.AlarmID, ne.NeType, ne.RmUID)
|
||||
alarm, err := dborm.XormGetDataBySQL(sql)
|
||||
if err != nil {
|
||||
log.Error("Failed to get alarm:", err)
|
||||
continue
|
||||
}
|
||||
//log.Debug("alarm:", *alarm)
|
||||
|
||||
var timestamp string
|
||||
if len(*neState) == 0 {
|
||||
log.Infof("Not found ne_state neType:%s, neId:%s", ne.NeType, ne.NeId)
|
||||
timestamp = ne.UpdateTime
|
||||
} else {
|
||||
timestamp = (*neState)[0]["timestamp"]
|
||||
}
|
||||
|
||||
// 解析日期时间字符串为时间对象
|
||||
seconds, err := global.GetSecondsSinceDatetime(timestamp)
|
||||
if err != nil {
|
||||
log.Error("Failed to GetSecondsSinceDatetime:", err)
|
||||
continue
|
||||
}
|
||||
log.Debugf("timestamp:%s seconds:%d", timestamp, seconds)
|
||||
|
||||
if seconds <= alarmDefine.Threshold {
|
||||
if len(*alarm) == 0 || (*alarm)[0]["alarm_status"] == fm.AlarmStatusClearString {
|
||||
continue
|
||||
}
|
||||
|
||||
// clear alarm, todo
|
||||
var alarmSeq int = 1
|
||||
threshold := strconv.FormatInt(alarmDefine.Threshold, 10)
|
||||
SpecificProblem := strings.ReplaceAll(alarmDefine.SpecificProblem, "{threshold}", threshold)
|
||||
locationInfo := fmt.Sprintf("SystemManagement.State: NE heartbeat timestamp=%s,threshold=%v", timestamp, alarmDefine.Threshold)
|
||||
alarmData := &Alarm{
|
||||
AlarmSeq: alarmSeq,
|
||||
AlarmId: alarmDefine.AlarmID,
|
||||
NeId: ne.RmUID,
|
||||
NeType: ne.NeType,
|
||||
NeName: ne.NeName,
|
||||
Province: ne.Province,
|
||||
PVFlag: ne.PvFlag,
|
||||
AlarmCode: alarmDefine.AlarmCode,
|
||||
AlarmTitle: alarmDefine.AlarmTitle,
|
||||
AlarmType: alarmDefine.AlarmType,
|
||||
AlarmStatus: fm.AlarmStatusClear,
|
||||
OrigSeverity: alarmDefine.OrigSeverity,
|
||||
ObjectUid: alarmDefine.ObjectUID,
|
||||
ObjectName: alarmDefine.ObjectName,
|
||||
ObjectType: alarmDefine.ObjectType,
|
||||
LocationInfo: locationInfo,
|
||||
SpecificProblem: SpecificProblem,
|
||||
SpecificProblemID: alarmDefine.SpecificProblemID,
|
||||
AddInfo: alarmDefine.AddInfo,
|
||||
EventTime: time.Now().Local().Format(time.RFC3339),
|
||||
}
|
||||
|
||||
alarmArray := &[]Alarm{*alarmData}
|
||||
body, _ := json.Marshal(alarmArray)
|
||||
//log.Debug("body: ", string(body))
|
||||
|
||||
var response *resty.Response
|
||||
requestURI := fmt.Sprintf("/api/rest/faultManagement/v1/elementType/%s/objectType/alarms", ne.NeType)
|
||||
restHost := fmt.Sprintf("http://127.0.0.1:%d", config.GetYamlConfig().Rest[0].Port)
|
||||
requestURL := fmt.Sprintf("%s%s", restHost, requestURI)
|
||||
log.Debug("requestURL: POST ", requestURL)
|
||||
response, err = client.R().
|
||||
EnableTrace().
|
||||
SetHeaders(map[string]string{"User-Agent": config.GetDefaultUserAgent()}).
|
||||
SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
|
||||
SetBody(body).
|
||||
Post(requestURL)
|
||||
if err != nil {
|
||||
log.Error("Failed to post:", err)
|
||||
failClearAlarmNum++
|
||||
continue
|
||||
}
|
||||
|
||||
log.Debug("StatusCode: ", response.StatusCode())
|
||||
switch response.StatusCode() {
|
||||
case http.StatusOK, http.StatusCreated, http.StatusNoContent, http.StatusAccepted:
|
||||
log.Debug("response body:", string(response.Body()))
|
||||
body := new(map[string]interface{})
|
||||
_ = json.Unmarshal(response.Body(), &body)
|
||||
succClearAlarmNum++
|
||||
default:
|
||||
log.Debug("response body:", string(response.Body()))
|
||||
body := new(map[string]interface{})
|
||||
_ = json.Unmarshal(response.Body(), &body)
|
||||
failClearAlarmNum++
|
||||
}
|
||||
} else {
|
||||
var alarmSeq int = 1
|
||||
if len(*alarm) > 0 && (*alarm)[0]["alarm_status"] == fm.AlarmStatusActiveString {
|
||||
log.Info("System state alarm has exist")
|
||||
continue
|
||||
}
|
||||
|
||||
threshold := strconv.FormatInt(alarmDefine.Threshold, 10)
|
||||
SpecificProblem := strings.ReplaceAll(alarmDefine.SpecificProblem, "{threshold}", threshold)
|
||||
locationInfo := fmt.Sprintf("SystemManagement.State: NE heartbeat timestamp=%s,threshold=%v", timestamp, alarmDefine.Threshold)
|
||||
alarmData := &Alarm{
|
||||
AlarmSeq: alarmSeq,
|
||||
AlarmId: alarmDefine.AlarmID,
|
||||
NeId: ne.RmUID,
|
||||
NeType: ne.NeType,
|
||||
NeName: ne.NeName,
|
||||
Province: ne.Province,
|
||||
PVFlag: ne.PvFlag,
|
||||
AlarmCode: alarmDefine.AlarmCode,
|
||||
AlarmTitle: alarmDefine.AlarmTitle,
|
||||
AlarmType: alarmDefine.AlarmType,
|
||||
AlarmStatus: fm.AlarmStatusActive,
|
||||
OrigSeverity: alarmDefine.OrigSeverity,
|
||||
ObjectUid: alarmDefine.ObjectUID,
|
||||
ObjectName: alarmDefine.ObjectName,
|
||||
ObjectType: alarmDefine.ObjectType,
|
||||
LocationInfo: locationInfo,
|
||||
SpecificProblem: SpecificProblem,
|
||||
SpecificProblemID: alarmDefine.SpecificProblemID,
|
||||
AddInfo: alarmDefine.AddInfo,
|
||||
EventTime: time.Now().Local().Format(time.RFC3339),
|
||||
}
|
||||
|
||||
alarmArray := &[]Alarm{*alarmData}
|
||||
body, _ := json.Marshal(alarmArray)
|
||||
//log.Debug("body: ", string(body))
|
||||
|
||||
var response *resty.Response
|
||||
requestURI := fmt.Sprintf("/api/rest/faultManagement/v1/elementType/%s/objectType/alarms", ne.NeType)
|
||||
restHost := fmt.Sprintf("http://127.0.0.1:%d", config.GetYamlConfig().Rest[0].Port)
|
||||
requestURL := fmt.Sprintf("%s%s", restHost, requestURI)
|
||||
log.Debug("requestURL: POST ", requestURL)
|
||||
response, err = client.R().
|
||||
EnableTrace().
|
||||
SetHeaders(map[string]string{"User-Agent": config.GetDefaultUserAgent()}).
|
||||
SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
|
||||
SetBody(body).
|
||||
Post(requestURL)
|
||||
if err != nil {
|
||||
log.Error("Failed to post:", err)
|
||||
failActiveAlarmNum++
|
||||
continue
|
||||
}
|
||||
|
||||
log.Debug("StatusCode: ", response.StatusCode())
|
||||
switch response.StatusCode() {
|
||||
case http.StatusOK, http.StatusCreated, http.StatusNoContent, http.StatusAccepted:
|
||||
log.Debug("response body:", string(response.Body()))
|
||||
body := new(map[string]interface{})
|
||||
_ = json.Unmarshal(response.Body(), &body)
|
||||
succActiveAlarmNum++
|
||||
default:
|
||||
log.Debug("response body:", string(response.Body()))
|
||||
body := new(map[string]interface{})
|
||||
_ = json.Unmarshal(response.Body(), &body)
|
||||
failActiveAlarmNum++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 返回结果,用于记录执行结果
|
||||
return map[string]any{
|
||||
"succActiveAlarmNum": succActiveAlarmNum,
|
||||
"failActiveAlarmNum": failActiveAlarmNum,
|
||||
"succClearAlarmNum": succClearAlarmNum,
|
||||
"failClearAlarmNum": failClearAlarmNum,
|
||||
}, nil
|
||||
}
|
||||
167
src/modules/crontask/processor/getStateFromNE/getStateFromNE.go
Normal file
167
src/modules/crontask/processor/getStateFromNE/getStateFromNE.go
Normal file
@@ -0,0 +1,167 @@
|
||||
package getStateFromNE
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"ems.agt/lib/dborm"
|
||||
"ems.agt/lib/log"
|
||||
"ems.agt/restagent/config"
|
||||
"github.com/go-resty/resty/v2"
|
||||
)
|
||||
|
||||
var NewProcessor = &BarProcessor{
|
||||
progress: 0,
|
||||
count: 0,
|
||||
}
|
||||
|
||||
// bar 队列任务处理
|
||||
type BarProcessor struct {
|
||||
// 任务进度
|
||||
progress int
|
||||
// 执行次数
|
||||
count int
|
||||
}
|
||||
|
||||
type BarParams struct {
|
||||
Duration int `json:"duration"`
|
||||
}
|
||||
|
||||
type CpuUsage struct {
|
||||
NfCpuUsage uint16 `json:"nfCpuUsage"`
|
||||
SysCpuUsage uint16 `json:"sysCpuUsage"`
|
||||
}
|
||||
|
||||
type MemUsage struct {
|
||||
TotalMem uint32 `json:"totalMem"`
|
||||
NfUsedMem uint32 `json:"nfUsedMem"`
|
||||
SysMemUsage uint16 `json:"sysMemUsage"`
|
||||
}
|
||||
|
||||
type PartitionInfo struct {
|
||||
Total uint32 `json:"total"` // MB
|
||||
Used uint32 `json:"used"` // MB
|
||||
}
|
||||
|
||||
type DiskSpace struct {
|
||||
PartitionNum uint8 `json:"partitionNum"`
|
||||
|
||||
PartitionInfo []PartitionInfo `json:"partitionInfo"`
|
||||
}
|
||||
|
||||
type SystemState struct {
|
||||
Version string `json:"version"`
|
||||
Capability uint32 `json:"capability"`
|
||||
SerialNum string `json:"serialNum"`
|
||||
ExpiryDate string `json:"expiryDate"`
|
||||
//Timestamp string `json:"timestamp"`
|
||||
|
||||
CpuUsage CpuUsage `json:"cpuUsage"`
|
||||
MemUsage MemUsage `json:"memUsage"`
|
||||
|
||||
DiskSpace DiskSpace `json:"diskSpace"`
|
||||
}
|
||||
|
||||
var client = resty.New()
|
||||
|
||||
func init() {
|
||||
/*
|
||||
client.
|
||||
SetTimeout(10 * time.Second).
|
||||
SetRetryCount(1).
|
||||
SetRetryWaitTime(1 * time.Second).
|
||||
SetRetryMaxWaitTime(2 * time.Second).
|
||||
SetRetryAfter(func(client *resty.Client, resp *resty.Response) (time.Duration, error) {
|
||||
return 0, errors.New("quota exceeded")
|
||||
})
|
||||
*/
|
||||
client.
|
||||
SetTimeout(time.Duration(400 * time.Millisecond))
|
||||
// SetRetryCount(1).
|
||||
// SetRetryWaitTime(time.Duration(1 * time.Second)).
|
||||
// SetRetryMaxWaitTime(time.Duration(2 * time.Second))
|
||||
//client.SetTimeout(2 * time.Second)
|
||||
}
|
||||
|
||||
func (s *BarProcessor) Execute(data any) (any, error) {
|
||||
var err error
|
||||
|
||||
s.count++
|
||||
// options := data.(cron.JobData)
|
||||
// // sysJob := options.SysJob
|
||||
// // var params BarParams
|
||||
|
||||
// // // err := json.Unmarshal([]byte(sysJob.TargetParams), ¶ms)
|
||||
// // // if err == nil {
|
||||
// // // duration = params.Duration
|
||||
// // // }
|
||||
|
||||
var nes []dborm.NeInfo
|
||||
_, err = dborm.XormGetAllNeInfo(&nes)
|
||||
if err != nil {
|
||||
log.Error("Failed to get all ne info:", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
failNum := 0
|
||||
succNum := 0
|
||||
for _, ne := range nes {
|
||||
requestURI := fmt.Sprintf("/api/rest/systemManagement/v1/elementType/%s/objectType/systemState", strings.ToLower(ne.NeType))
|
||||
requestURL := fmt.Sprintf("http://%s:%s%s", ne.Ip, ne.Port, requestURI)
|
||||
log.Debug("requestURL: Get", requestURL)
|
||||
client := resty.New()
|
||||
response, err := client.R().
|
||||
EnableTrace().
|
||||
SetHeaders(map[string]string{"User-Agent": config.GetDefaultUserAgent()}).
|
||||
SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
|
||||
Get(requestURL)
|
||||
if err != nil {
|
||||
log.Error("Failed to Get:", err)
|
||||
failNum++
|
||||
continue
|
||||
}
|
||||
|
||||
log.Debug("StatusCode: ", response.StatusCode())
|
||||
switch response.StatusCode() {
|
||||
case http.StatusOK, http.StatusCreated, http.StatusNoContent, http.StatusAccepted:
|
||||
log.Debug("response body:", string(response.Body()))
|
||||
state := new(SystemState)
|
||||
_ = json.Unmarshal(response.Body(), &state)
|
||||
neState := new(dborm.NeState)
|
||||
neState.NeType = ne.NeType
|
||||
neState.NeId = ne.NeId
|
||||
neState.Version = state.Version
|
||||
neState.Capability = state.Capability
|
||||
neState.SerialNum = state.SerialNum
|
||||
neState.ExpiryDate = state.ExpiryDate
|
||||
cu, _ := json.Marshal(state.CpuUsage)
|
||||
neState.CpuUsage = string(cu)
|
||||
mu, _ := json.Marshal(state.MemUsage)
|
||||
neState.MemUsage = string(mu)
|
||||
ds, _ := json.Marshal(state.DiskSpace)
|
||||
neState.DiskSpace = string(ds)
|
||||
log.Debug("neState:", neState)
|
||||
_, err := dborm.XormInsertNeState(neState)
|
||||
if err != nil {
|
||||
log.Error("Failed to insert ne_state:", err)
|
||||
failNum++
|
||||
continue
|
||||
}
|
||||
succNum++
|
||||
default:
|
||||
log.Debug("response body:", string(response.Body()))
|
||||
body := new(map[string]interface{})
|
||||
_ = json.Unmarshal(response.Body(), &body)
|
||||
failNum++
|
||||
}
|
||||
}
|
||||
|
||||
// 返回结果,用于记录执行结果
|
||||
return map[string]any{
|
||||
"succNum": succNum,
|
||||
"failNum": failNum,
|
||||
}, nil
|
||||
}
|
||||
@@ -5,6 +5,8 @@ import (
|
||||
"ems.agt/src/modules/crontask/processor/backupEtcFromNE"
|
||||
"ems.agt/src/modules/crontask/processor/delExpiredNeBackup"
|
||||
"ems.agt/src/modules/crontask/processor/deleteExpiredRecord"
|
||||
"ems.agt/src/modules/crontask/processor/genNeStateAlarm"
|
||||
"ems.agt/src/modules/crontask/processor/getStateFromNE"
|
||||
monitorsysresource "ems.agt/src/modules/crontask/processor/monitor_sys_resource"
|
||||
)
|
||||
|
||||
@@ -16,4 +18,6 @@ func InitCronQueue() {
|
||||
cron.CreateQueue("delExpiredNeBackup", delExpiredNeBackup.NewProcessor)
|
||||
cron.CreateQueue("deleteExpiredRecord", deleteExpiredRecord.NewProcessor)
|
||||
cron.CreateQueue("backupEtcFromNE", backupEtcFromNE.NewProcessor)
|
||||
cron.CreateQueue("getStateFromNE", getStateFromNE.NewProcessor)
|
||||
cron.CreateQueue("genNeStateAlarm", genNeStateAlarm.NewProcessor)
|
||||
}
|
||||
|
||||
@@ -43,25 +43,9 @@ func (s *SysJobLogController) List(c *gin.Context) {
|
||||
querys := ctx.QueryMap(c)
|
||||
data := s.sysJobLogService.SelectJobLogPage(querys)
|
||||
|
||||
language := ctx.AcceptLanguage(c)
|
||||
|
||||
// 反查多语言key
|
||||
if v, ok := querys["jobName"]; ok && v != "" {
|
||||
querys["jobName"] = i18n.ValueKey(language, querys["jobName"].(string))
|
||||
}
|
||||
|
||||
dataI18n := s.sysJobLogService.SelectJobLogPage(querys)
|
||||
totalI18n := parse.Number(dataI18n["total"])
|
||||
if totalI18n != 0 {
|
||||
rows := data["rows"].([]model.SysJobLog)
|
||||
total := parse.Number(data["total"])
|
||||
rowsI18n := dataI18n["rows"].([]model.SysJobLog)
|
||||
data["rows"] = append(rows, rowsI18n...)
|
||||
data["total"] = total + totalI18n
|
||||
}
|
||||
|
||||
rows := data["rows"].([]model.SysJobLog)
|
||||
// 闭包函数处理多语言
|
||||
language := ctx.AcceptLanguage(c)
|
||||
converI18n := func(language string, arr *[]model.SysJobLog) {
|
||||
for i := range *arr {
|
||||
(*arr)[i].JobName = i18n.TKey(language, (*arr)[i].JobName)
|
||||
|
||||
@@ -234,9 +234,7 @@ func (r *SysJobImpl) InsertJob(sysJob model.SysJob) string {
|
||||
if sysJob.InvokeTarget != "" {
|
||||
params["invoke_target"] = sysJob.InvokeTarget
|
||||
}
|
||||
if sysJob.TargetParams != "" {
|
||||
params["target_params"] = sysJob.TargetParams
|
||||
}
|
||||
params["target_params"] = sysJob.TargetParams
|
||||
if sysJob.CronExpression != "" {
|
||||
params["cron_expression"] = sysJob.CronExpression
|
||||
}
|
||||
@@ -252,9 +250,7 @@ func (r *SysJobImpl) InsertJob(sysJob model.SysJob) string {
|
||||
if sysJob.SaveLog != "" {
|
||||
params["save_log"] = sysJob.SaveLog
|
||||
}
|
||||
if sysJob.Remark != "" {
|
||||
params["remark"] = sysJob.Remark
|
||||
}
|
||||
params["remark"] = sysJob.Remark
|
||||
if sysJob.CreateBy != "" {
|
||||
params["create_by"] = sysJob.CreateBy
|
||||
params["create_time"] = time.Now().UnixMilli()
|
||||
@@ -300,9 +296,7 @@ func (r *SysJobImpl) UpdateJob(sysJob model.SysJob) int64 {
|
||||
if sysJob.InvokeTarget != "" {
|
||||
params["invoke_target"] = sysJob.InvokeTarget
|
||||
}
|
||||
if sysJob.TargetParams != "" {
|
||||
params["target_params"] = sysJob.TargetParams
|
||||
}
|
||||
params["target_params"] = sysJob.TargetParams
|
||||
if sysJob.CronExpression != "" {
|
||||
params["cron_expression"] = sysJob.CronExpression
|
||||
}
|
||||
@@ -318,9 +312,7 @@ func (r *SysJobImpl) UpdateJob(sysJob model.SysJob) int64 {
|
||||
if sysJob.SaveLog != "" {
|
||||
params["save_log"] = sysJob.SaveLog
|
||||
}
|
||||
if sysJob.Remark != "" {
|
||||
params["remark"] = sysJob.Remark
|
||||
}
|
||||
params["remark"] = sysJob.Remark
|
||||
if sysJob.UpdateBy != "" {
|
||||
params["update_by"] = sysJob.UpdateBy
|
||||
params["update_time"] = time.Now().UnixMilli()
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"ems.agt/src/framework/i18n"
|
||||
"ems.agt/src/framework/utils/ctx"
|
||||
"ems.agt/src/framework/vo/result"
|
||||
"ems.agt/src/modules/network_element/model"
|
||||
neService "ems.agt/src/modules/network_element/service"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
@@ -30,13 +31,7 @@ type PerfKPIController struct {
|
||||
// GET /data
|
||||
func (s *PerfKPIController) GoldKPI(c *gin.Context) {
|
||||
language := ctx.AcceptLanguage(c)
|
||||
var querys struct {
|
||||
NeType string `form:"neType" binding:"required"`
|
||||
NeID string `form:"neId" binding:"required"`
|
||||
StartTime string `form:"startTime" binding:"required"`
|
||||
EndTime string `form:"endTime" binding:"required"`
|
||||
Interval int64 `form:"interval" binding:"required"`
|
||||
}
|
||||
var querys model.GoldKPIQuery
|
||||
if err := c.ShouldBindQuery(&querys); err != nil {
|
||||
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||
return
|
||||
@@ -47,12 +42,10 @@ func (s *PerfKPIController) GoldKPI(c *gin.Context) {
|
||||
if startTime.IsZero() {
|
||||
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||
}
|
||||
startTimeStr := startTime.Format(date.YYYY_MM_DD_HH_MM_SS)
|
||||
endTime := date.ParseStrToDate(querys.EndTime, date.YYYY_MM_DD_HH_MM_SS)
|
||||
if startTime.IsZero() {
|
||||
if endTime.IsZero() {
|
||||
c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
|
||||
}
|
||||
endTimeStr := endTime.Format(date.YYYY_MM_DD_HH_MM_SS)
|
||||
|
||||
// 查询网元获取IP
|
||||
neInfo := s.neInfoService.SelectNeInfoByNeTypeAndNeID(querys.NeType, querys.NeID)
|
||||
@@ -60,16 +53,10 @@ func (s *PerfKPIController) GoldKPI(c *gin.Context) {
|
||||
c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
|
||||
return
|
||||
}
|
||||
|
||||
// 获取数据指标id
|
||||
var kpiIds []string
|
||||
kpiTitles := s.perfKPIService.SelectGoldKPITitle(neInfo.NeType)
|
||||
for _, kpiId := range kpiTitles {
|
||||
kpiIds = append(kpiIds, kpiId.KPIID)
|
||||
}
|
||||
querys.RmUID = neInfo.RmUID
|
||||
|
||||
// 查询数据
|
||||
kpiData := s.perfKPIService.SelectGoldKPI(neInfo.RmUID, neInfo.NeType, startTimeStr, endTimeStr, kpiIds, querys.Interval)
|
||||
kpiData := s.perfKPIService.SelectGoldKPI(querys)
|
||||
c.JSON(200, result.OkData(kpiData))
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
"ems.agt/src/framework/i18n"
|
||||
"ems.agt/src/framework/utils/ctx"
|
||||
"ems.agt/src/framework/utils/file"
|
||||
"ems.agt/src/framework/utils/parse"
|
||||
"ems.agt/src/framework/utils/ssh"
|
||||
"ems.agt/src/framework/vo/result"
|
||||
"ems.agt/src/modules/network_element/model"
|
||||
@@ -270,6 +271,14 @@ func (s *UDMAuthController) Remove(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
// 处理字符转id数组后去重
|
||||
imsiArr := strings.Split(imsi, ",")
|
||||
uniqueIDs := parse.RemoveDuplicates(imsiArr)
|
||||
if len(uniqueIDs) <= 0 {
|
||||
c.JSON(200, result.Err(nil))
|
||||
return
|
||||
}
|
||||
|
||||
// 查询网元获取IP
|
||||
neInfo := s.neInfoService.SelectNeInfoByNeTypeAndNeID("UDM", neId)
|
||||
if neInfo.NeId != neId || neInfo.IP == "" {
|
||||
@@ -277,21 +286,24 @@ func (s *UDMAuthController) Remove(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
msg := fmt.Sprintf("del authdat:imsi=%s", imsi)
|
||||
resultData := map[string]string{}
|
||||
for _, imsi := range uniqueIDs {
|
||||
msg := fmt.Sprintf("del authdat:imsi=%s", imsi)
|
||||
|
||||
// 发送MML
|
||||
data, err := mmlclient.MMLSendMsgToString(neInfo.IP, msg)
|
||||
if err != nil {
|
||||
c.JSON(200, result.ErrMsg(err.Error()))
|
||||
return
|
||||
// 发送MML
|
||||
data, err := mmlclient.MMLSendMsgToString(neInfo.IP, msg)
|
||||
if err != nil {
|
||||
resultData[imsi] = err.Error()
|
||||
}
|
||||
// 命令ok时
|
||||
if strings.Contains(data, "ok") {
|
||||
neId = ""
|
||||
s.udmAuthService.Delete(neId, imsi)
|
||||
resultData[imsi] = data
|
||||
}
|
||||
}
|
||||
|
||||
// 命令ok时
|
||||
if strings.Contains(data, "ok") {
|
||||
neId = ""
|
||||
s.udmAuthService.Delete(neId, imsi)
|
||||
}
|
||||
c.JSON(200, result.OkData(data))
|
||||
c.JSON(200, result.OkData(resultData))
|
||||
}
|
||||
|
||||
// UDM鉴权用户-批量删除
|
||||
@@ -347,7 +359,7 @@ func (s *UDMAuthController) Export(c *gin.Context) {
|
||||
}
|
||||
|
||||
if !(body.Type == "csv" || body.Type == "txt") {
|
||||
c.JSON(200, result.ErrMsg(i18n.TKey(language, "ne.udm.errImportFileFormat")))
|
||||
c.JSON(200, result.ErrMsg(i18n.TKey(language, "ne.udm.errImportUserAuthFileFormat")))
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ import (
|
||||
"ems.agt/src/framework/i18n"
|
||||
"ems.agt/src/framework/utils/ctx"
|
||||
"ems.agt/src/framework/utils/file"
|
||||
"ems.agt/src/framework/utils/parse"
|
||||
"ems.agt/src/framework/utils/ssh"
|
||||
"ems.agt/src/framework/vo/result"
|
||||
"ems.agt/src/modules/network_element/model"
|
||||
@@ -346,6 +347,14 @@ func (s *UDMSubController) Remove(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
// 处理字符转id数组后去重
|
||||
imsiArr := strings.Split(imsi, ",")
|
||||
uniqueIDs := parse.RemoveDuplicates(imsiArr)
|
||||
if len(uniqueIDs) <= 0 {
|
||||
c.JSON(200, result.Err(nil))
|
||||
return
|
||||
}
|
||||
|
||||
// 查询网元获取IP
|
||||
neInfo := s.neInfoService.SelectNeInfoByNeTypeAndNeID("UDM", neId)
|
||||
if neInfo.NeId != neId || neInfo.IP == "" {
|
||||
@@ -353,21 +362,24 @@ func (s *UDMSubController) Remove(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
msg := fmt.Sprintf("del udmuser:imsi=%s", imsi)
|
||||
resultData := map[string]string{}
|
||||
for _, imsi := range uniqueIDs {
|
||||
msg := fmt.Sprintf("del udmuser:imsi=%s", imsi)
|
||||
|
||||
// 发送MML
|
||||
data, err := mmlclient.MMLSendMsgToString(neInfo.IP, msg)
|
||||
if err != nil {
|
||||
c.JSON(200, result.ErrMsg(err.Error()))
|
||||
return
|
||||
// 发送MML
|
||||
data, err := mmlclient.MMLSendMsgToString(neInfo.IP, msg)
|
||||
if err != nil {
|
||||
resultData[imsi] = err.Error()
|
||||
}
|
||||
// 命令ok时
|
||||
if strings.Contains(data, "ok") {
|
||||
neId = ""
|
||||
s.udmSubService.Delete(neId, imsi)
|
||||
resultData[imsi] = data
|
||||
}
|
||||
}
|
||||
|
||||
// 命令ok时
|
||||
if strings.Contains(data, "ok") {
|
||||
neId = ""
|
||||
s.udmSubService.Delete(neId, imsi)
|
||||
}
|
||||
c.JSON(200, result.OkData(data))
|
||||
c.JSON(200, result.OkData(resultData))
|
||||
}
|
||||
|
||||
// UDM签约用户-批量删除
|
||||
@@ -423,7 +435,7 @@ func (s *UDMSubController) Export(c *gin.Context) {
|
||||
}
|
||||
|
||||
if !(body.Type == "csv" || body.Type == "txt") {
|
||||
c.JSON(200, result.ErrMsg(i18n.TKey(language, "ne.udm.errImportFileFormat")))
|
||||
c.JSON(200, result.ErrMsg(i18n.TKey(language, "ne.udm.errImportUserSubFileFormat")))
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -9,3 +9,15 @@ type GoldKPITitle struct {
|
||||
CnTitle string `json:"cnTitle" gorm:"column:cn_title"`
|
||||
EnTitle string `json:"enTitle" gorm:"column:en_title"`
|
||||
}
|
||||
|
||||
// GoldKPIQuery 黄金指标查询参数结构体
|
||||
type GoldKPIQuery struct {
|
||||
NeType string `form:"neType" binding:"required"`
|
||||
NeID string `form:"neId" binding:"required"`
|
||||
StartTime string `form:"startTime" binding:"required"`
|
||||
EndTime string `form:"endTime" binding:"required"`
|
||||
Interval int64 `form:"interval" binding:"required"`
|
||||
RmUID string `form:"rmUID"`
|
||||
SortField string `form:"sortField" binding:"omitempty,oneof=timeGroup"`
|
||||
SortOrder string `form:"sortOrder" binding:"omitempty,oneof=asc desc"`
|
||||
}
|
||||
|
||||
@@ -4,8 +4,8 @@ import "ems.agt/src/modules/network_element/model"
|
||||
|
||||
// 性能统计 数据层接口
|
||||
type IPerfKPI interface {
|
||||
// SelectGoldKPI 通过ne_type和ne_id查询网元信息
|
||||
SelectGoldKPI(rmUID, neType string, startTime, endTime string, kpiIds []string, interval int64) []map[string]any
|
||||
// SelectGoldKPI 通过网元指标数据信息
|
||||
SelectGoldKPI(query model.GoldKPIQuery, kpiIds []string) []map[string]any
|
||||
|
||||
// SelectGoldKPITitle
|
||||
SelectGoldKPITitle(neType string) []model.GoldKPITitle
|
||||
|
||||
@@ -16,25 +16,25 @@ var NewPerfKPIImpl = &PerfKPIImpl{}
|
||||
type PerfKPIImpl struct{}
|
||||
|
||||
// SelectGoldKPI 通过网元指标数据信息
|
||||
func (r *PerfKPIImpl) SelectGoldKPI(rmUID, neType string, startTime, endTime string, kpiIds []string, interval int64) []map[string]any {
|
||||
func (r *PerfKPIImpl) SelectGoldKPI(query model.GoldKPIQuery, kpiIds []string) []map[string]any {
|
||||
// 查询条件拼接
|
||||
var conditions []string
|
||||
var params []any
|
||||
if rmUID != "" {
|
||||
if query.RmUID != "" {
|
||||
conditions = append(conditions, "gk.rm_uid = ?")
|
||||
params = append(params, rmUID)
|
||||
params = append(params, query.RmUID)
|
||||
}
|
||||
if neType != "" {
|
||||
if query.NeType != "" {
|
||||
conditions = append(conditions, "gk.ne_type = ?")
|
||||
params = append(params, neType)
|
||||
params = append(params, query.NeType)
|
||||
}
|
||||
if startTime != "" {
|
||||
if query.StartTime != "" {
|
||||
conditions = append(conditions, "gk.start_time >= ?")
|
||||
params = append(params, startTime)
|
||||
params = append(params, query.StartTime)
|
||||
}
|
||||
if endTime != "" {
|
||||
if query.EndTime != "" {
|
||||
conditions = append(conditions, "gk.start_time <= ?")
|
||||
params = append(params, endTime)
|
||||
params = append(params, query.EndTime)
|
||||
}
|
||||
// 构建查询条件语句
|
||||
whereSql := ""
|
||||
@@ -44,7 +44,7 @@ func (r *PerfKPIImpl) SelectGoldKPI(rmUID, neType string, startTime, endTime str
|
||||
|
||||
// 查询字段列
|
||||
timeFormat := "DATE_FORMAT(gk.start_time, '%Y-%m-%d %H:')"
|
||||
minuteGroup := fmt.Sprintf("LPAD(FLOOR(MINUTE(gk.start_time) / %d) * %d, 2, '0')", interval, interval)
|
||||
minuteGroup := fmt.Sprintf("LPAD(FLOOR(MINUTE(gk.start_time) / %d) * %d, 2, '0')", query.Interval, query.Interval)
|
||||
groupByField := fmt.Sprintf("CONCAT( %s, %s ) AS timeGroup", timeFormat, minuteGroup)
|
||||
var fields = []string{
|
||||
groupByField,
|
||||
@@ -58,7 +58,14 @@ func (r *PerfKPIImpl) SelectGoldKPI(rmUID, neType string, startTime, endTime str
|
||||
fieldsSql := strings.Join(fields, ",")
|
||||
|
||||
// 查询数据
|
||||
querySql := fmt.Sprintf("SELECT %s FROM gold_kpi gk %s GROUP BY timeGroup", fieldsSql, whereSql)
|
||||
if query.SortField == "" {
|
||||
query.SortField = "timeGroup"
|
||||
}
|
||||
if query.SortOrder == "" {
|
||||
query.SortOrder = "desc"
|
||||
}
|
||||
orderSql := fmt.Sprintf(" order by %s %s", query.SortField, query.SortOrder)
|
||||
querySql := fmt.Sprintf("SELECT %s FROM gold_kpi gk %s GROUP BY timeGroup %s", fieldsSql, whereSql, orderSql)
|
||||
results, err := datasource.RawDB("", querySql, params)
|
||||
if err != nil {
|
||||
logger.Errorf("query err => %v", err)
|
||||
|
||||
@@ -4,8 +4,8 @@ import "ems.agt/src/modules/network_element/model"
|
||||
|
||||
// 性能统计 数据层接口
|
||||
type IPerfKPI interface {
|
||||
// SelectGoldKPI 通过ne_type和ne_id查询网元信息
|
||||
SelectGoldKPI(rmUID, neType string, startTime, endTime string, kpiIds []string, interval int64) []map[string]any
|
||||
// SelectGoldKPI 通过网元指标数据信息
|
||||
SelectGoldKPI(query model.GoldKPIQuery) []map[string]any
|
||||
|
||||
// SelectGoldKPITitle
|
||||
SelectGoldKPITitle(neType string) []model.GoldKPITitle
|
||||
|
||||
@@ -17,8 +17,15 @@ type PerfKPIImpl struct {
|
||||
}
|
||||
|
||||
// SelectGoldKPI 通过网元指标数据信息
|
||||
func (r *PerfKPIImpl) SelectGoldKPI(rmUID, neType string, startTime, endTime string, kpiIds []string, interval int64) []map[string]any {
|
||||
data := r.perfKPIRepository.SelectGoldKPI(rmUID, neType, startTime, endTime, kpiIds, interval)
|
||||
func (r *PerfKPIImpl) SelectGoldKPI(query model.GoldKPIQuery) []map[string]any {
|
||||
// 获取数据指标id
|
||||
var kpiIds []string
|
||||
kpiTitles := r.perfKPIRepository.SelectGoldKPITitle(query.NeType)
|
||||
for _, kpiId := range kpiTitles {
|
||||
kpiIds = append(kpiIds, kpiId.KPIID)
|
||||
}
|
||||
|
||||
data := r.perfKPIRepository.SelectGoldKPI(query, kpiIds)
|
||||
if data == nil {
|
||||
return []map[string]any{}
|
||||
}
|
||||
|
||||
@@ -57,12 +57,10 @@ func (r *SysRoleImpl) SelectRoleById(roleId string) model.SysRole {
|
||||
// UpdateRole 修改角色信息
|
||||
func (r *SysRoleImpl) UpdateRole(sysRole model.SysRole) int64 {
|
||||
rows := r.sysRoleRepository.UpdateRole(sysRole)
|
||||
if rows > 0 {
|
||||
if rows > 0 && len(sysRole.MenuIds) > 0 {
|
||||
// 删除角色与菜单关联
|
||||
r.sysRoleMenuRepository.DeleteRoleMenu([]string{sysRole.RoleID})
|
||||
if len(sysRole.MenuIds) > 0 {
|
||||
r.insertRoleMenu(sysRole.RoleID, sysRole.MenuIds)
|
||||
}
|
||||
r.insertRoleMenu(sysRole.RoleID, sysRole.MenuIds)
|
||||
}
|
||||
return rows
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Makefile for OMC-OMC-crontask project
|
||||
|
||||
PROJECT = OMC
|
||||
VERSION = 2.2312.9
|
||||
VERSION = 2.2312.10
|
||||
LIBDIR = ems.agt/lib
|
||||
BINNAME = sshsvc
|
||||
|
||||
|
||||
Reference in New Issue
Block a user