package config import ( "bufio" "fmt" "os" "reflect" "strings" "be.ems/lib/global" "be.ems/lib/log" "gopkg.in/yaml.v3" //"github.com/go-yaml-comment/yaml" //"github.com/goccy/go-yaml" ) // Yaml struct of config type YamlConfig struct { Logger struct { File string `yaml:"file"` Level string `yaml:"level"` Duration int `yaml:"duration"` Count int `yaml:"count"` } `yaml:"logger"` Pprof struct { Enabled bool `yaml:"enabled"` Addr string `yaml:"addr"` } `yaml:"pprof"` // Rest []struct { // IPv4 string `yaml:"ipv4"` // IPv6 string `yaml:"ipv6"` // Port uint16 `yaml:"port"` // Scheme string `yaml:"scheme"` // ClientAuthType int `yaml:"clientAuthType"` // CaFile string `yaml:"caFile"` // CertFile string `yaml:"certFile"` // KeyFile string `yaml:"keyFile"` // } `yaml:"rest"` Rest []RestParam WebServer struct { Enabled bool `yaml:"enabled"` RootDir string `yaml:"rootDir"` Listen []struct { Addr string `yaml:"addr"` Scheme string `yaml:"scheme"` ClientAuthType int `yaml:"clientAuthType"` CaFile string `yaml:"caFile"` CertFile string `yaml:"certFile"` KeyFile string `yaml:"keyFile"` } `yaml:"listen"` } `yaml:"webServer"` Database DbConfig `yaml:"database"` OMC struct { UriPrefix string `yaml:"uriPrefix"` NeType string `yaml:"neType"` NeId string `yaml:"neId"` RmUID string `yaml:"rmUID"` NeName string `yaml:"neName"` Province string `yaml:"province"` Vendor string `yaml:"vendor"` Dn string `yaml:"dn"` Chk2Ne bool `yaml:"chk2ne"` Sn string `yaml:"sn"` CheckSign bool `yaml:"checksign"` RootDir string `yaml:"rootDir"` BinDir string `yaml:"binDir"` Backup string `yaml:"backup"` Upload string `yaml:"upload"` FrontUpload string `yaml:"frontUpload"` FrontTraceDir string `yaml:"frontTraceDir"` Software string `yaml:"software"` License string `yaml:"license"` GtpUri string `yaml:"gtpUri"` CheckContentType bool `yaml:"checkContentType"` TestMode bool `yaml:"testMode"` RBACMode bool `yaml:"rbacMode"` RunDir string `yaml:"runDir"` CmdTimeout int `yaml:"cmdTimeout"` } `yaml:"omc"` Alarm AlarmConfig `yaml:"alarm"` MML MMLParam `yaml:"mml"` NE struct { Addr string `yaml:"addr"` Port uint16 `yaml:"port"` User string `yaml:"user"` EtcDir string `yaml:"etcdir"` BinDir string `yaml:"bindir"` OmcDir string `yaml:"omcdir"` ScpDir string `yaml:"scpdir"` LicenseDir string `yaml:"licensedir"` EtcListIMS string `yaml:"etcListIMS"` EtcListDefault string `yaml:"etcListDefault"` DpkgOverwrite bool `yaml:"dpkgOverwrite"` DpkgTimeout int `yaml:"dpkgTimeout"` } `yaml:"ne"` Auth struct { Crypt string `yaml:"crypt"` Token bool `yaml:"token"` Expires uint32 `yaml:"expires"` Session string `yaml:"session"` PublicKey string `yaml:"publicKey"` PrivateKey string `yaml:"privateKey"` } `yaml:"auth"` Params struct { RmUIDMaxNum int `yaml:"rmuidmaxnum"` AlarmIDMaxNum int `yaml:"alarmidmaxnum"` PmIDMaxNum int `yaml:"pmidmaxnum"` SubIDMaxNum int `yaml:"subidmaxnum"` UriMaxLen int `yaml:"urimaxlen"` RmUIDRegexp string `yaml:"rmuidregexp"` } `yaml:"params"` TestConfig struct { Enabled bool `yaml:"enabled"` File string `yaml:"file"` } `yaml:"testConfig"` } type RestParam struct { IPv4 string `yaml:"ipv4"` IPv6 string `yaml:"ipv6"` Port uint16 `yaml:"port"` Scheme string `yaml:"scheme,omitempty" default:"http"` ClientAuthType int `yaml:"clientAuthType"` CaFile string `yaml:"caFile"` CertFile string `yaml:"certFile"` KeyFile string `yaml:"keyFile"` } type DbConfig struct { Type string `yaml:"type"` User string `yaml:"user"` Password string `yaml:"password"` Host string `yaml:"host"` Port string `yaml:"port"` Name string `yaml:"name"` ConnParam string `yaml:"connParam,omitempty"` Backup string `yaml:"backup"` } type AlarmConfig struct { SplitEventAlarm bool `yaml:"splitEventAlarm"` //ForwardAlarm bool `yaml:"forwardAlarm"` EmailForward struct { Enable bool `yaml:"enable" json:"enable"` EmailList string `yaml:"emailList" json:"emailList"` SMTP string `yaml:"smtp" json:"smtp"` Port uint16 `yaml:"port" json:"port"` User string `yaml:"user" json:"user"` Password string `yaml:"password" json:"password"` TLSSkipVerify bool `yaml:"tlsSkipVerify" json:"tlsSkipVerify"` } `yaml:"alarmEmailForward"` SMSCForward struct { Enable bool `yaml:"enable" json:"enable"` MobileList string `yaml:"mobileList" json:"mobileList"` SMSCAddr string `yaml:"smscAddr" json:"smscAddr"` SystemID string `yaml:"systemID" json:"systemID"` Password string `yaml:"password" json:"password"` SystemType string `yaml:"systemType" json:"systemType"` DataCoding byte `yaml:"dataCoding" json:"dataCoding"` ServiceNumber string `yaml:"serviceNumber" json:"serviceNumber"` } `yaml:"alarmSMSForward"` SMS struct { ApiURL string `yaml:"apiURL"` AccessKeyID string `yaml:"AccessKeyID"` AccessKeySecret string `yaml:"accessKeySecret"` SignName string `yaml:"signName"` TemplateCode string `yaml:"templateCode"` } `yaml:"smsForward"` SMProxy string `yaml:"smProxy"` } type MMLParam struct { Sleep int64 `yaml:"sleep"` DeadLine int64 `yaml:"deadLine"` SizeRow int16 `yaml:"sizeRow"` SizeCol int16 `yaml:"sizeCol"` BufferSize int `yaml:"bufferSize"` MmlHome string `yaml:"mmlHome"` } type TestDatas struct { UDM struct { CapUsed uint32 `yaml:"capUsed"` FeatureEnabled []string `yaml:"featureEnabled"` } `yaml:"udm"` AUSF struct { CapUsed uint32 `yaml:"capUsed"` FeatureEnabled []string `yaml:"featureEnabled"` } `yaml:"ausf"` AMF struct { CapUsed uint32 `yaml:"capUsed"` FeatureEnabled []string `yaml:"featureEnabled"` } `yaml:"amf"` SMF struct { CapUsed uint32 `yaml:"capUsed"` FeatureEnabled []string `yaml:"featureEnabled"` } `yaml:"smf"` UPF struct { CapUsed uint32 `yaml:"capUsed"` FeatureEnabled []string `yaml:"featureEnabled"` } `yaml:"upf"` } type NeTestData struct { CapUsed uint32 `yaml:"capUsed"` FeatureEnabled []string `yaml:"featureEnabled"` } type TestDataMap struct { NeTestDatas []map[string]NeTestData } var yamlConfig YamlConfig = NewYamlConfig() type YamlConfigFile struct { FilePath string `json:"filePath"` ConfigLines YamlConfig `json:"configLines"` OrignalLines []string `json:"orignalLines"` } var YamlConfigInfo YamlConfigFile = YamlConfigFile{ ConfigLines: NewYamlConfig(), } // set default value for yaml config func NewYamlConfig() YamlConfig { return YamlConfig{ Database: DbConfig{ Type: "mysql", ConnParam: "charset=utf8mb4&collation=utf8mb4_general_ci&parseTime=True&interpolateParams=True", }, MML: MMLParam{ SizeRow: 200, SizeCol: 120, BufferSize: 65535, }, Alarm: AlarmConfig{ SplitEventAlarm: true, }, } } func ReadConfig(configFile string) { YamlConfigInfo.FilePath = configFile yamlFile, err := os.ReadFile(configFile) if err != nil { fmt.Println("Read yaml config file error:", err) os.Exit(2) } // fmt.Println("yamlfile:", string(yamlFile)) err = yaml.Unmarshal(yamlFile, &YamlConfigInfo.ConfigLines) if err != nil { fmt.Println("Unmarshal error:", err) os.Exit(3) } yamlConfig = YamlConfigInfo.ConfigLines ReadOriginalConfig(configFile) } func ReadOriginalConfig(configFile string) { // 读取原始YAML文件 inputFile, err := os.Open(configFile) if err != nil { fmt.Println("failed to open:", err) os.Exit(3) } defer inputFile.Close() scanner := bufio.NewScanner(inputFile) for scanner.Scan() { YamlConfigInfo.OrignalLines = append(YamlConfigInfo.OrignalLines, scanner.Text()) } if err := scanner.Err(); err != nil { fmt.Println("failed to scanner:", err) os.Exit(3) } } func WriteOrignalConfig(configFile string, paramName string, paramData map[string]any) error { lines := YamlConfigInfo.OrignalLines for i, line := range lines { if strings.Contains(line, paramName) { for k, v := range paramData { // find the first line nearby the paramName for j := i + 1; j < len(lines); j++ { if strings.Contains(lines[j], k+":") { index := strings.Index(lines[j], k) // Determine the type of v switch v := v.(type) { case string: lines[j] = lines[j][:index] + fmt.Sprintf("%s: \"%s\"", k, v) // case int: // lines[j] = lines[j][:index] + fmt.Sprintf("%s: %d", k, v) // case float64: // lines[j] = lines[j][:index] + fmt.Sprintf("%s: %f", k, v) case bool: lines[j] = lines[j][:index] + fmt.Sprintf("%s: %t", k, v) default: lines[j] = lines[j][:index] + fmt.Sprintf("%s: %v", k, v) } break } } } break } } // write back to yaml file outputFile, err := os.Create(configFile) if err != nil { fmt.Println(err) return err } defer outputFile.Close() writer := bufio.NewWriter(outputFile) for _, line := range YamlConfigInfo.OrignalLines { writer.WriteString(line + "\n") } writer.Flush() return nil } func WriteYamlConfig(newConfigData YamlConfig, configFile string) error { // 将配置转换回YAML数据 newYamlData, err := yaml.Marshal(&newConfigData) if err != nil { log.Errorf("Failed to marshal YAML: %v", err) return err } // 将新的YAML数据写入文件 err = os.WriteFile(configFile, newYamlData, 0644) if err != nil { log.Errorf("Failed to write YAML file: %v", err) return err } return nil } var mapYaml map[string]interface{} func ReadParamConfig(fileName string) *map[string]interface{} { file, err := os.ReadFile(fileName) if err != nil { fmt.Println("Read yaml file error:", err) } mapYaml = make(map[string]interface{}) err = yaml.Unmarshal(file, &mapYaml) if err != nil { fmt.Printf("yaml.Unmarshal: %v when to struct", err) } // fmt.Println("mapYaml:", mapYaml) return &mapYaml } func UpdateStructFromMap(s any, updates map[string]any) { v := reflect.ValueOf(s).Elem() t := v.Type() for key, value := range updates { for i := 0; i < t.NumField(); i++ { field := t.Field(i) if field.Tag.Get("json") == key { structField := v.FieldByName(field.Name) if structField.IsValid() && structField.CanSet() { // Convert value to the appropriate type if necessary convertedValue := reflect.ValueOf(value).Convert(structField.Type()) if structField.Type() == convertedValue.Type() { structField.Set(convertedValue) } } break } } } } func GetYamlConfig() *YamlConfig { return &YamlConfigInfo.ConfigLines } func GetAuthFromConfig() interface{} { return yamlConfig.Auth } func GetExpiresFromConfig() uint32 { return yamlConfig.Auth.Expires } func GetRmUIDFromConfig() string { return yamlConfig.OMC.RmUID } func GetRmUIDRegexpFromConfig() string { return yamlConfig.Params.RmUIDRegexp } func GetRmUIDMaxNumFromConfig() int { return yamlConfig.Params.RmUIDMaxNum } func GetAlarmIDMaxNumFromConfig() int { return yamlConfig.Params.AlarmIDMaxNum } func GetPmIDMaxNumFromConfig() int { return yamlConfig.Params.PmIDMaxNum } func GetSubIDMaxNumFromConfig() int { return yamlConfig.Params.SubIDMaxNum } func GetUriMaxLenFromConfig() int { return yamlConfig.Params.UriMaxLen } func GetLogLevel() log.LogLevel { var logLevel log.LogLevel switch strings.ToLower(yamlConfig.Logger.Level) { case "trace": logLevel = log.LOG_TRACE case "info": logLevel = log.LOG_INFO case "debug": logLevel = log.LOG_DEBUG case "warn": logLevel = log.LOG_WARN case "error": logLevel = log.LOG_ERROR case "fatal": logLevel = log.LOG_FATAL case "off": logLevel = log.LOG_OFF default: logLevel = log.LOG_DEBUG } return logLevel } var ( DefaultUriPrefix string = "/api/rest" UriPrefix string = "/omc/rest" //TestDataUDM []map[string]interface{} TDatas map[string]NeTestData ) func ReadTestConfigYaml(pfile string) (ret error) { file, err := os.ReadFile(pfile) if err != nil { return err } err = yaml.Unmarshal(file, &TDatas) if err != nil { fmt.Println("Failed to Unmarshal:", err) return err } return nil } func GetDefaultUserAgent() string { return "OMC-restagent/" + global.Version } func GetOMCHostUrl() string { var omcip string = "127.0.0.1" var rest RestParam = yamlConfig.Rest[0] var port uint16 = rest.Port if rest.IPv4 != "0.0.0.0" && rest.IPv4 != "" { omcip = rest.IPv4 } else if rest.IPv6 != "::" && rest.IPv6 != "" { omcip = "[" + rest.IPv6 + "]" } var scheme string = "http" if rest.Scheme != "" { scheme = rest.Scheme } return fmt.Sprintf("%s://%s:%d", scheme, omcip, port) } // const defaultConfigFile = "./etc/restconf.yaml" // func init() { // cfile := flag.String("c", defaultConfigFile, "config file") // pv := flag.Bool("version", false, "print version") // ph := flag.Bool("help", false, "print help") // //global.BuildTime = "Wed May 31 18:24:04 CST 2023" // //global.GoVer = "go version go1.15.7 linux/arm64" // flag.Parse() // if *pv { // fmt.Printf("OMC restagent version: %s\n%s\n%s\n\n", global.Version, global.BuildTime, global.GoVer) // os.Exit(0) // } // if *ph { // flag.Usage() // os.Exit(0) // } // // 使用viper读取配置 // conf.InitConfig(*cfile) // ReadConfig(*cfile) // if GetYamlConfig().OMC.UriPrefix != "" { // UriPrefix = GetYamlConfig().OMC.UriPrefix // } // if GetYamlConfig().TestConfig.Enabled { // ReadTestConfigYaml(GetYamlConfig().TestConfig.File) // } // }