fix: cm data follow spec of CM doc
This commit is contained in:
@@ -19,7 +19,7 @@ func SyncNbiCM() error {
|
||||
|
||||
// 从ne_info表获取AMF类型的网元
|
||||
var amfNEs []common.NeInfo
|
||||
err := dborm.DefaultDB().Table("ne_info").Where("ne_type = ?", "AMF").
|
||||
err := dborm.DefaultDB().Table("ne_info").Where("ne_type = ? and status <> 0", "AMF").
|
||||
Find(&amfNEs).Error
|
||||
if err != nil {
|
||||
log.Errorf("Failed to query AMF network elements: %v", err)
|
||||
@@ -47,7 +47,7 @@ func SyncNbiCM() error {
|
||||
UserLabel: ne.NeName,
|
||||
VendorName: ne.VendorName,
|
||||
ManagedBy: ne.Dn,
|
||||
ManagementIpAddress: ne.Ip,
|
||||
ManagementIpAddress: "{" + ne.Ip + "}",
|
||||
SwVersion: version,
|
||||
PatchInfo: "-",
|
||||
AdministrativeState: adminState,
|
||||
@@ -91,7 +91,7 @@ func SyncNbiCM() error {
|
||||
|
||||
// ========== AmfFunction ==========
|
||||
var capability int
|
||||
err = dborm.DefaultDB().Table("ne_license").Where("ne_type = ? and ne_id = ?", ne.NeType, ne.NeId).
|
||||
err = dborm.DefaultDB().Table("ne_license").Where("ne_type = ? and ne_id = ? and status = 1", ne.NeType, ne.NeId).
|
||||
Pluck("capability", &capability).Error
|
||||
if err != nil {
|
||||
log.Errorf("Failed to query capability for ne_id %s: %v", ne.NeId, err)
|
||||
@@ -104,9 +104,9 @@ func SyncNbiCM() error {
|
||||
OperationalState: operState,
|
||||
VnfInstanceId: "vnf-" + ne.NeType + "-" + ne.NeId,
|
||||
Fqdn: fmt.Sprintf("%s%s.mnc000.mcc460.3gppnetwork.org", strings.ToLower(ne.NeType), ne.NeId),
|
||||
SbiServiceList: "Namf_Communication,Namf_EventExposure,Namf_MT,Namf_Location",
|
||||
AmfGuamiList: "[{\"mcc\":\"460\",\"mnc\":\"000\",\"amfId\":\"" + ne.NeId + "\"}]",
|
||||
SnssaiList: "[{\"sst\":1,\"sd\":\"000001\"}]",
|
||||
SbiServiceList: "{Namf_Communication,Namf_EventExposure,Namf_MT,Namf_Location}",
|
||||
AmfGuamiList: "{{\"mcc\":\"460\",\"mnc\":\"000\",\"amfId\":\"" + ne.NeId + "\"}}",
|
||||
SnssaiList: "{{\"sst\":1,\"sd\":\"000001\"}}",
|
||||
MaxUser: capability,
|
||||
RelativeCapacity: 30,
|
||||
MaxGnbNum: 100,
|
||||
|
||||
@@ -125,6 +125,8 @@ type NeInfo struct {
|
||||
NeName string `db:"ne_name"`
|
||||
Ip string `db:"ip"`
|
||||
Port string `db:"port"`
|
||||
PVFlag string `db:"pv_flag"`
|
||||
Province string `db:"province"`
|
||||
Dn string `db:"dn"`
|
||||
Status NeStatus `db:"status"`
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ func SyncNbiCM() error {
|
||||
|
||||
// 从ne_info表获取PCF类型的网元
|
||||
var pcfNEs []common.NeInfo
|
||||
err := dborm.DefaultDB().Table("ne_info").Where("ne_type = ?", "PCF").
|
||||
err := dborm.DefaultDB().Table("ne_info").Where("ne_type = ? and status <> 0", "PCF").
|
||||
Find(&pcfNEs).Error
|
||||
if err != nil {
|
||||
log.Errorf("Failed to query PCF network elements: %v", err)
|
||||
@@ -45,7 +45,7 @@ func SyncNbiCM() error {
|
||||
UserLabel: ne.NeName,
|
||||
VendorName: ne.VendorName,
|
||||
ManagedBy: ne.Dn,
|
||||
ManagementIpAddress: ne.Ip,
|
||||
ManagementIpAddress: "{" + ne.Ip + "}",
|
||||
SwVersion: version,
|
||||
PatchInfo: "-",
|
||||
AdministrativeState: adminState,
|
||||
@@ -95,7 +95,7 @@ func SyncNbiCM() error {
|
||||
OperationalState: operState,
|
||||
VnfInstanceId: "vnf-" + ne.NeType + "-" + ne.NeId,
|
||||
Fqdn: fmt.Sprintf("%s%s.mnc000.mcc460.3gppnetwork.org", strings.ToLower(ne.NeType), ne.NeId),
|
||||
SbiServiceList: "Npcf_AMPolicyControl,Npcf_PolicyAuthorization,Npcf_SMPolicyControl,Npcf_BDTPolicyControl",
|
||||
SbiServiceList: "{Npcf_AMPolicyControl,Npcf_PolicyAuthorization,Npcf_SMPolicyControl,Npcf_BDTPolicyControl}",
|
||||
}
|
||||
pcfJSON, err := json.Marshal(pcfFunction)
|
||||
if err != nil {
|
||||
@@ -135,7 +135,7 @@ func SyncNbiCM() error {
|
||||
|
||||
// ========== UdrFunction ==========
|
||||
var capability int
|
||||
err = dborm.DefaultDB().Table("ne_license").Where("ne_type = ? and ne_id = ?", ne.NeType, ne.NeId).
|
||||
err = dborm.DefaultDB().Table("ne_license").Where("ne_type = ? and ne_id = ? and status = 1", ne.NeType, ne.NeId).
|
||||
Pluck("capability", &capability).Error
|
||||
if err != nil {
|
||||
log.Errorf("Failed to query capability for ne_id %s: %v", ne.NeId, err)
|
||||
|
||||
@@ -26,8 +26,8 @@ type SmfFunction struct {
|
||||
VnfInstanceId string `json:"vnfInstanceId"`
|
||||
Fqdn string `json:"fqdn"`
|
||||
SbiServiceList string `json:"sbiServiceList"`
|
||||
MaxPduSessions int `json:"maxPduSessions"`
|
||||
MaxQfi int `json:"maxQfi"`
|
||||
MaxPduSessions int32 `json:"maxPduSessions"`
|
||||
MaxQfi int32 `json:"maxQfi"`
|
||||
UpfList string `json:"upfList"`
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ func SyncNbiCM() error {
|
||||
|
||||
// 从ne_info表获取SMF类型的网元
|
||||
var smfNEs []common.NeInfo
|
||||
err := dborm.DefaultDB().Table("ne_info").Where("ne_type = ?", "SMF").
|
||||
err := dborm.DefaultDB().Table("ne_info").Where("ne_type = ? and status <> 0", "SMF").
|
||||
Find(&smfNEs).Error
|
||||
if err != nil {
|
||||
log.Errorf("Failed to query SMF network elements: %v", err)
|
||||
@@ -45,7 +45,7 @@ func SyncNbiCM() error {
|
||||
UserLabel: ne.NeName,
|
||||
VendorName: ne.VendorName,
|
||||
ManagedBy: ne.Dn,
|
||||
ManagementIpAddress: ne.Ip,
|
||||
ManagementIpAddress: "{" + ne.Ip + "}",
|
||||
SwVersion: version,
|
||||
PatchInfo: "-",
|
||||
AdministrativeState: adminState,
|
||||
@@ -88,13 +88,19 @@ func SyncNbiCM() error {
|
||||
}
|
||||
|
||||
// ========== SmfFunction ==========
|
||||
var capability int
|
||||
err = dborm.DefaultDB().Table("ne_license").Where("ne_type = ? and ne_id = ?", ne.NeType, ne.NeId).
|
||||
var capability int32
|
||||
err = dborm.DefaultDB().Table("ne_license").Where("ne_type = ? and ne_id = ? and status = 1", ne.NeType, ne.NeId).
|
||||
Pluck("capability", &capability).Error
|
||||
if err != nil {
|
||||
log.Errorf("Failed to query capability for ne_id %s: %v", ne.NeId, err)
|
||||
capability = 0
|
||||
}
|
||||
upfNames := []string{}
|
||||
err = dborm.DefaultDB().Table("ne_info").Where("ne_type = ? and status <> 0", "UPF").
|
||||
Select("ne_name").Find(&upfNames).Error
|
||||
if err != nil {
|
||||
log.Errorf("Failed to query UPF list for ne_id %s: %v", ne.NeId, err)
|
||||
}
|
||||
smfFunction := SmfFunction{
|
||||
Id: fmt.Sprintf("%s-%s-SmfFunction", ne.NeType, ne.NeId),
|
||||
UserLabel: ne.NeName + "-SmfFunction",
|
||||
@@ -102,10 +108,10 @@ func SyncNbiCM() error {
|
||||
OperationalState: operState,
|
||||
VnfInstanceId: "vnf-" + ne.NeType + "-" + ne.NeId,
|
||||
Fqdn: fmt.Sprintf("%s%s.mnc000.mcc460.3gppnetwork.org", strings.ToLower(ne.NeType), ne.NeId),
|
||||
SbiServiceList: "Nsmf_PDUSession,Nsmf_EventExposure",
|
||||
SbiServiceList: "{Nsmf_PDUSession,Nsmf_EventExposure}",
|
||||
MaxPduSessions: capability,
|
||||
MaxQfi: 64,
|
||||
UpfList: "[\"UPF-001\",\"UPF-2\"]",
|
||||
UpfList: "{" + strings.Join(upfNames, ",") + "}",
|
||||
}
|
||||
smfJSON, err := json.Marshal(smfFunction)
|
||||
if err != nil {
|
||||
|
||||
@@ -18,7 +18,7 @@ func SyncNbiCM() error {
|
||||
|
||||
// 从ne_info表获取UDM类型的网元
|
||||
var udmNEs []common.NeInfo
|
||||
err := dborm.DefaultDB().Table("ne_info").Where("ne_type = ?", "UDM").
|
||||
err := dborm.DefaultDB().Table("ne_info").Where("ne_type = ? and status <> 0", "UDM").
|
||||
Find(&udmNEs).Error
|
||||
if err != nil {
|
||||
log.Errorf("Failed to query UDM network elements: %v", err)
|
||||
@@ -45,7 +45,7 @@ func SyncNbiCM() error {
|
||||
UserLabel: ne.NeName,
|
||||
VendorName: ne.VendorName,
|
||||
ManagedBy: ne.Dn,
|
||||
ManagementIpAddress: ne.Ip,
|
||||
ManagementIpAddress: "{" + ne.Ip + "}",
|
||||
SwVersion: version,
|
||||
PatchInfo: "-",
|
||||
AdministrativeState: adminState,
|
||||
@@ -95,7 +95,7 @@ func SyncNbiCM() error {
|
||||
OperationalState: operState,
|
||||
VnfInstanceId: "vnf-" + ne.NeType + "-" + ne.NeId,
|
||||
Fqdn: fmt.Sprintf("%s%s.mnc000.mcc460.3gppnetwork.org", strings.ToLower(ne.NeType), ne.NeId),
|
||||
SbiServiceList: "Nudm_UEAuthentication,Nudm_SubscriberDataManagement,Nudm_UEContextManagement",
|
||||
SbiServiceList: "{Nudm_UEAuthentication,Nudm_SubscriberDataManagement,Nudm_UEContextManagement}",
|
||||
}
|
||||
udmJSON, err := json.Marshal(udmFunction)
|
||||
if err != nil {
|
||||
@@ -135,7 +135,7 @@ func SyncNbiCM() error {
|
||||
|
||||
// ========== UdrFunction ==========
|
||||
var capability int
|
||||
err = dborm.DefaultDB().Table("ne_license").Where("ne_type = ? and ne_id = ?", ne.NeType, ne.NeId).
|
||||
err = dborm.DefaultDB().Table("ne_license").Where("ne_type = ? and ne_id = ? and status = 1", ne.NeType, ne.NeId).
|
||||
Pluck("capability", &capability).Error
|
||||
if err != nil {
|
||||
log.Errorf("Failed to query capability for ne_id %s: %v", ne.NeId, err)
|
||||
@@ -148,7 +148,7 @@ func SyncNbiCM() error {
|
||||
OperationalState: operState,
|
||||
VnfInstanceId: "vnf-UDR-" + ne.NeId,
|
||||
Fqdn: fmt.Sprintf("%s%s.mnc000.mcc460.3gppnetwork.org", strings.ToLower(ne.NeType), ne.NeId),
|
||||
SbiServiceList: "Nudr_DataRepository",
|
||||
SbiServiceList: "{Nudr_DataRepository}",
|
||||
MaxNumSupi: capability,
|
||||
MaxNumMsisdn: capability,
|
||||
}
|
||||
@@ -196,7 +196,7 @@ func SyncNbiCM() error {
|
||||
OperationalState: operState,
|
||||
VnfInstanceId: "vnf-AUSF-" + ne.NeId,
|
||||
Fqdn: fmt.Sprintf("ausf%s.mnc000.mcc460.3gppnetwork.org", ne.NeId),
|
||||
SbiServiceList: "Nausf_UEAuthentication,Nausf_SoRProtection",
|
||||
SbiServiceList: "{Nausf_UEAuthentication,Nausf_SoRProtection}",
|
||||
}
|
||||
ausfJSON, err := json.Marshal(ausfFunction)
|
||||
if err != nil {
|
||||
|
||||
@@ -12,6 +12,8 @@ type ManagedElement struct {
|
||||
PatchInfo string `json:"patchInfo"`
|
||||
AdministrativeState common.AdministrativeState `json:"administrativeState"`
|
||||
OperationalState common.OperationalState `json:"operationalState"`
|
||||
LocationName string `json:"locationName"`
|
||||
HardwarePlatform string `json:"hardwarePlatform"`
|
||||
}
|
||||
|
||||
type InventoryUnitRack struct {
|
||||
@@ -39,6 +41,7 @@ type InventoryUnitShelf struct {
|
||||
DateOfManufacture string `json:"dateOfManufacture"`
|
||||
DateOfLastService string `json:"dateOfLastService"`
|
||||
ManufacturerData string `json:"manufacturerData"`
|
||||
SlotsInformation string `json:"slotsInformation"`
|
||||
ShelfPosition string `json:"shelfPosition"`
|
||||
}
|
||||
|
||||
@@ -53,24 +56,26 @@ type InventoryUnitPack struct {
|
||||
DateOfManufacture string `json:"dateOfManufacture"`
|
||||
DateOfLastService string `json:"dateOfLastService"`
|
||||
ManufacturerData string `json:"manufacturerData"`
|
||||
PortsInformation string `json:"portsInformation"`
|
||||
PackPosition string `json:"packPosition"`
|
||||
SlotsOccupied string `json:"slotsOccupied"`
|
||||
}
|
||||
|
||||
type InventoryUnitHost struct {
|
||||
Id string `json:"id"`
|
||||
UserLabel string `json:"userLabel"`
|
||||
VendorUnitFamilyType string `json:"vendorUnitFamilyType"`
|
||||
VendorUnitTypeNumber string `json:"vendorUnitTypeNumber"`
|
||||
VendorName string `json:"vendorName"`
|
||||
SerialNumber string `json:"serialNumber"`
|
||||
VersionNumber string `json:"versionNumber"`
|
||||
DateOfManufacture string `json:"dateOfManufacture"`
|
||||
DateOfLastService string `json:"dateOfLastService"`
|
||||
ManufacturerData string `json:"manufacturerData"`
|
||||
HostPosition string `json:"hostPosition"`
|
||||
NumberOfCpu string `json:"numberOfCpu"`
|
||||
MemSize string `json:"memSize"`
|
||||
HardDiskSize string `json:"hardDiskSize"`
|
||||
Id string `json:"id"`
|
||||
UserLabel string `json:"userLabel"`
|
||||
VendorUnitFamilyType string `json:"vendorUnitFamilyType"`
|
||||
VendorUnitTypeNumber string `json:"vendorUnitTypeNumber"`
|
||||
VendorName string `json:"vendorName"`
|
||||
SerialNumber string `json:"serialNumber"`
|
||||
VersionNumber string `json:"versionNumber"`
|
||||
DateOfManufacture string `json:"dateOfManufacture"`
|
||||
DateOfLastService string `json:"dateOfLastService"`
|
||||
ManufacturerData string `json:"manufacturerData"`
|
||||
HostPosition string `json:"hostPosition"`
|
||||
NumberOfCpu int32 `json:"numberOfCpu"`
|
||||
MemSize float32 `json:"memSize"`
|
||||
HardDiskSize float32 `json:"hardDiskSize"`
|
||||
}
|
||||
|
||||
type InventoryUnitAccessory struct {
|
||||
@@ -95,8 +100,8 @@ type UpfFunction struct {
|
||||
AdministrativeState common.AdministrativeState `json:"administrativeState"`
|
||||
OperationalState common.OperationalState `json:"operationalState"`
|
||||
VnfInstanceId string `json:"vnfInstanceId"`
|
||||
MaxQosFlows string `json:"maxQosFlows"`
|
||||
MaxThroughput string `json:"maxThroughput"`
|
||||
MaxQosFlows int32 `json:"maxQosFlows"`
|
||||
MaxThroughput float32 `json:"maxThroughput"`
|
||||
}
|
||||
|
||||
type EpRpDynN9Upf struct {
|
||||
|
||||
@@ -18,7 +18,7 @@ func SyncNbiCM() error {
|
||||
|
||||
// 从ne_info表获取UPF类型的网元
|
||||
var upfNEs []common.NeInfo
|
||||
err := dborm.DefaultDB().Table("ne_info").Where("ne_type = ?", "UPF").
|
||||
err := dborm.DefaultDB().Table("ne_info").Where("ne_type = ? and status <> 0", "UPF").
|
||||
Find(&upfNEs).Error
|
||||
if err != nil {
|
||||
log.Errorf("Failed to query UPF network elements: %v", err)
|
||||
@@ -29,7 +29,7 @@ func SyncNbiCM() error {
|
||||
|
||||
now := time.Now()
|
||||
|
||||
for _, ne := range upfNEs {
|
||||
for i, ne := range upfNEs {
|
||||
adminState, operState := common.ParseStateFromStatus(ne.Status)
|
||||
|
||||
var version string = "-"
|
||||
@@ -47,11 +47,13 @@ func SyncNbiCM() error {
|
||||
UserLabel: ne.NeName,
|
||||
VendorName: ne.VendorName,
|
||||
ManagedBy: ne.Dn,
|
||||
ManagementIpAddress: ne.Ip,
|
||||
ManagementIpAddress: "{" + ne.Ip + "}",
|
||||
SwVersion: version,
|
||||
PatchInfo: "-",
|
||||
AdministrativeState: adminState,
|
||||
OperationalState: operState,
|
||||
LocationName: ne.Province,
|
||||
HardwarePlatform: "x86_64",
|
||||
}
|
||||
meJSON, err := json.Marshal(managedElement)
|
||||
if err != nil {
|
||||
@@ -97,11 +99,11 @@ func SyncNbiCM() error {
|
||||
VendorUnitTypeNumber: "UPF-" + ne.NeId,
|
||||
VendorName: ne.VendorName,
|
||||
SerialNumber: "SN-UPF-" + ne.NeId,
|
||||
VersionNumber: "1.0.0",
|
||||
VersionNumber: "1.2.16",
|
||||
DateOfManufacture: "2023-01-01",
|
||||
DateOfLastService: now.Format("2006-01-02"),
|
||||
DateOfLastService: now.AddDate(0, 0, 360).Format("2006-01-02"),
|
||||
ManufacturerData: "{}",
|
||||
RackPosition: "1",
|
||||
RackPosition: "1-2",
|
||||
}
|
||||
rackJSON, err := json.Marshal(inventoryUnitRack)
|
||||
if err != nil {
|
||||
@@ -140,6 +142,7 @@ func SyncNbiCM() error {
|
||||
}
|
||||
|
||||
// ========== InventoryUnitShelf ==========
|
||||
var slotsInfo string = fmt.Sprintf(`{{"slot-%d","-",Unused}}`, i+1)
|
||||
inventoryUnitShelf := InventoryUnitShelf{
|
||||
Id: fmt.Sprintf("%s-%s-InventoryUnitShelf", ne.NeType, ne.NeId),
|
||||
UserLabel: ne.NeName + "-InventoryUnitShelf",
|
||||
@@ -149,8 +152,9 @@ func SyncNbiCM() error {
|
||||
SerialNumber: "SN-UPF-SHELF-" + ne.NeId,
|
||||
VersionNumber: "1.0.0",
|
||||
DateOfManufacture: "2023-01-01",
|
||||
DateOfLastService: now.Format("2006-01-02"),
|
||||
DateOfLastService: now.AddDate(0, 0, 360).Format("2006-01-02"),
|
||||
ManufacturerData: "{}",
|
||||
SlotsInformation: slotsInfo,
|
||||
ShelfPosition: "1",
|
||||
}
|
||||
shelfJSON, err := json.Marshal(inventoryUnitShelf)
|
||||
@@ -199,9 +203,11 @@ func SyncNbiCM() error {
|
||||
SerialNumber: "SN-UPF-PACK-" + ne.NeId,
|
||||
VersionNumber: "1.0.0",
|
||||
DateOfManufacture: "2023-01-01",
|
||||
DateOfLastService: now.Format("2006-01-02"),
|
||||
DateOfLastService: now.AddDate(0, 0, 360).Format("2006-01-02"),
|
||||
ManufacturerData: "{}",
|
||||
SlotsOccupied: "1,2",
|
||||
PortsInformation: `{{"port-1","Ethernet 10Gbs",Used},{"port-2","Ethernet 10Gbps",Used}, {"port-3","optical 50Gbps",Used}, {"port-4","optical 50Gbps",Unused}}`,
|
||||
PackPosition: "2-2",
|
||||
SlotsOccupied: "2",
|
||||
}
|
||||
packJSON, err := json.Marshal(inventoryUnitPack)
|
||||
if err != nil {
|
||||
@@ -249,12 +255,12 @@ func SyncNbiCM() error {
|
||||
SerialNumber: "SN-UPF-HOST-" + ne.NeId,
|
||||
VersionNumber: "1.0.0",
|
||||
DateOfManufacture: "2023-01-01",
|
||||
DateOfLastService: now.Format("2006-01-02"),
|
||||
DateOfLastService: now.AddDate(0, 0, 360).Format("2006-01-02"),
|
||||
ManufacturerData: "{}",
|
||||
HostPosition: "1",
|
||||
NumberOfCpu: "16",
|
||||
MemSize: "64GB",
|
||||
HardDiskSize: "1TB",
|
||||
NumberOfCpu: 16,
|
||||
MemSize: 64,
|
||||
HardDiskSize: 1024,
|
||||
}
|
||||
hostJSON, err := json.Marshal(inventoryUnitHost)
|
||||
if err != nil {
|
||||
@@ -302,7 +308,7 @@ func SyncNbiCM() error {
|
||||
SerialNumber: "SN-UPF-ACC-" + ne.NeId,
|
||||
VersionNumber: "1.0.0",
|
||||
DateOfManufacture: "2023-01-01",
|
||||
DateOfLastService: now.Format("2006-01-02"),
|
||||
DateOfLastService: now.AddDate(0, 0, 360).Format("2006-01-02"),
|
||||
ManufacturerData: "{}",
|
||||
AccessoryPosition: "1",
|
||||
AccessoryType: "FAN",
|
||||
@@ -344,8 +350,8 @@ func SyncNbiCM() error {
|
||||
}
|
||||
}
|
||||
|
||||
var capability int
|
||||
err = dborm.DefaultDB().Table("ne_license").Where("ne_type = ? and ne_id = ?", ne.NeType, ne.NeId).
|
||||
var capability int32
|
||||
err = dborm.DefaultDB().Table("ne_license").Where("ne_type = ? and ne_id = ? and status = 1", ne.NeType, ne.NeId).
|
||||
Pluck("capability", &capability).Error
|
||||
if err != nil {
|
||||
log.Errorf("Failed to query capability for ne_id %s: %v", ne.NeId, err)
|
||||
@@ -359,8 +365,8 @@ func SyncNbiCM() error {
|
||||
AdministrativeState: adminState,
|
||||
OperationalState: operState,
|
||||
VnfInstanceId: "vnf-" + ne.NeType + "-" + ne.NeId,
|
||||
MaxQosFlows: fmt.Sprintf("%d", capability),
|
||||
MaxThroughput: "10Gbps",
|
||||
MaxQosFlows: capability,
|
||||
MaxThroughput: 10.0,
|
||||
}
|
||||
upfJSON, err := json.Marshal(upfFunction)
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user