diff --git a/.golangci.yml b/.golangci.yml index 58965fb..9699253 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -28,13 +28,6 @@ run: # default is true. Enables skipping of directories: # vendor$, third_party$, testdata$, examples$, Godeps$, builtin$ skip-dirs-use-default: true - # which files to skip: they will be analyzed, but issues from them - # won't be reported. Default value is empty list, but there is - # no need to include all autogenerated files, we confidently recognize - # autogenerated files. If it's not please let us know. - # "/" will be replaced by current OS file path separator to properly work - # on Windows. - skip-files: # by default isn't set. If set we pass it to "go list -mod={option}". From "go help modules": # If invoked with -mod=readonly, the go command is disallowed from the implicit # automatic updating of go.mod described above. Instead, it fails when any changes @@ -50,7 +43,7 @@ run: # output configuration options output: # colored-line-number|line-number|json|tab|checkstyle|code-climate, default is "colored-line-number" - format: colored-line-number + formats: colored-line-number # print lines of code with issue, default is true print-issued-lines: true # print linter name in the end of issue text, default is true @@ -133,10 +126,14 @@ linters-settings: # minimal confidence for issues, default is 0.8 min-confidence: 0.8 gomnd: - settings: - mnd: - # the list of enabled checks, see https://github.com/tommy-muehle/go-mnd/#checks for description. - checks: argument,case,condition,operation,return,assign + # the list of enabled checks, see https://github.com/tommy-muehle/go-mnd/#checks for description. + checks: + - argument + - case + - condition + - operation + - return + - assign gomodguard: allowed: modules: # List of allowed modules @@ -154,8 +151,6 @@ linters-settings: # version: "< 1.1.0" # Version constraint, see https://github.com/Masterminds/semver#basic-comparisons # reason: "testing if blocked version constraint works." # Reason why the version constraint exists. (Optional) govet: - # report about shadowed variables - check-shadowing: true # settings per analyzer settings: printf: # analyzer name, run `go tool vet help` to see all analyzers @@ -201,8 +196,6 @@ linters-settings: whitespace: multi-if: false # Enforces newlines (or comments) after every multi-line if statement multi-func: false # Enforces newlines (or comments) after every multi-line function signature - gci: - local-prefixes: "bitbucket.org" misspell: #locale: US ignore-words: @@ -231,9 +224,8 @@ linters-settings: linters: enable: - gofmt - # - govet + - govet - errcheck - - staticcheck - unused - gosimple - ineffassign @@ -257,9 +249,9 @@ linters: - dogsled # - bodyclose - asciicheck - #- stylecheck - # - unparam - # - wsl + # - stylecheck + # - unparam + # - wsl #disable-all: false fast: true diff --git a/Dockerfile b/Dockerfile index 21c6386..35ad765 100644 --- a/Dockerfile +++ b/Dockerfile @@ -6,8 +6,6 @@ FROM golang:1.23.2-bookworm AS builder -LABEL maintainer="Aether SD-Core " - RUN apt-get update && \ apt-get -y install --no-install-recommends \ vim && \ @@ -19,7 +17,8 @@ RUN make all FROM alpine:3.20 AS simapp -LABEL description="Aether open source 5G Core Network" \ +LABEL maintainer="Aether SD-Core " \ + description="Aether open source 5G Core Network" \ version="Stage 3" ARG DEBUG_TOOLS @@ -29,7 +28,5 @@ RUN if [ "$DEBUG_TOOLS" = "true" ]; then \ apk update && apk add --no-cache -U gcompat vim strace net-tools curl netcat-openbsd bind-tools bash; \ fi -WORKDIR /simapp/bin - # Copy executable -COPY --from=builder /go/src/simapp/bin/* . +COPY --from=builder /go/src/simapp/bin/* /usr/local/bin/. diff --git a/go.mod b/go.mod index c499614..4e48329 100644 --- a/go.mod +++ b/go.mod @@ -5,16 +5,19 @@ go 1.21 require ( github.com/fsnotify/fsnotify v1.8.0 github.com/spf13/viper v1.19.0 + github.com/urfave/cli/v2 v2.27.5 go.uber.org/zap v1.27.0 golang.org/x/net v0.30.0 gopkg.in/yaml.v2 v2.4.0 ) require ( + github.com/cpuguy83/go-md2man/v2 v2.0.5 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/magiconair/properties v1.8.7 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/pelletier/go-toml/v2 v2.2.2 // indirect + github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/sagikazarmark/locafero v0.4.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect github.com/sourcegraph/conc v0.3.0 // indirect @@ -22,6 +25,7 @@ require ( github.com/spf13/cast v1.6.0 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/subosito/gotenv v1.6.0 // indirect + github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect go.uber.org/multierr v1.10.0 // indirect golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect golang.org/x/sys v0.26.0 // indirect diff --git a/go.sum b/go.sum index 5aec34d..abc5c48 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,5 @@ +github.com/cpuguy83/go-md2man/v2 v2.0.5 h1:ZtcqGrnekaHpVLArFSe4HK5DoKx1T0rq2DwVB0alcyc= +github.com/cpuguy83/go-md2man/v2 v2.0.5/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= @@ -25,6 +27,8 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRI github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ= github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4= github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= @@ -50,6 +54,10 @@ github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsT github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= +github.com/urfave/cli/v2 v2.27.5 h1:WoHEJLdsXr6dDWoJgMq/CboDmyY/8HMMH1fTECbih+w= +github.com/urfave/cli/v2 v2.27.5/go.mod h1:3Sevf16NykTbInEnD0yKkjDAeZDS0A6bzhBH5hrMvTQ= +github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4= +github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ= diff --git a/logger/logger.go b/logger/logger.go index b91749f..5d88b01 100644 --- a/logger/logger.go +++ b/logger/logger.go @@ -41,7 +41,7 @@ func init() { panic(err) } - SimappLog = log.Sugar() + SimappLog = log.Sugar().With("component", "SIMApp", "category", "App") } func GetLogger() *zap.Logger { diff --git a/simapp.go b/simapp.go index e373c93..d95a12e 100644 --- a/simapp.go +++ b/simapp.go @@ -17,6 +17,7 @@ import ( "net" "net/http" "os" + "path/filepath" "reflect" "strconv" "strings" @@ -25,6 +26,7 @@ import ( "github.com/fsnotify/fsnotify" "github.com/omec-project/simapp/logger" "github.com/spf13/viper" + "github.com/urfave/cli/v2" "go.uber.org/zap" "go.uber.org/zap/zapcore" "golang.org/x/net/http2" @@ -288,9 +290,8 @@ func InitConfigFactory(f string, configMsgChan chan configMessage, subProvisionE subProxyEndpt.Port = SimappConfig.Configuration.SubProxyEndpt.Port } - viper.SetConfigName("simapp.yaml") + viper.SetConfigFile(f) viper.SetConfigType("yaml") - viper.AddConfigPath("/simapp/config") err := viper.ReadInConfig() // Find and read the config file if err != nil { // Handle errors reading the config file return err @@ -308,12 +309,38 @@ func syncConfig(w http.ResponseWriter, req *http.Request) { } func main() { - logger.SimappLog.Infoln("simApp started") + app := cli.NewApp() + app.Name = "simapp" + logger.SimappLog.Infoln(app.Name) + app.Usage = "SIMApp" + app.UsageText = "simapp -cfg " + app.Flags = []cli.Flag{ + &cli.StringFlag{ + Name: "cfg", + Usage: "simapp config file", + Required: true, + }, + } + app.Action = action + if err := app.Run(os.Args); err != nil { + logger.SimappLog.Fatalf("SIMApp run error: %v", err) + } +} + +func action(c *cli.Context) error { + logger.SimappLog.Infoln("SIMApp started") configMsgChan = make(chan configMessage, 100) var subProvisionEndpt SubProvisionEndpt var subProxyEndpt SubProxyEndpt - err := InitConfigFactory("./config/simapp.yaml", configMsgChan, &subProvisionEndpt, &subProxyEndpt) + cfg := c.String("cfg") + absPath, err := filepath.Abs(cfg) + if err != nil { + logger.SimappLog.Errorln(err) + return err + } + + err = InitConfigFactory(absPath, configMsgChan, &subProvisionEndpt, &subProxyEndpt) if err != nil { logger.SimappLog.Errorln(err) } @@ -362,7 +389,7 @@ func sendHttpReqMsg(req *http.Request) (*http.Response, error) { retries += 1 if err != nil { nextInterval := getNextBackoffInterval(retries, 2) - logger.SimappLog.Errorf("http req send error [%v], retrying after %d sec...", err, nextInterval) + logger.SimappLog.Errorf("http req send error [%v], retrying after %d sec", err, nextInterval) time.Sleep(time.Second * time.Duration(nextInterval)) continue } @@ -378,7 +405,7 @@ func sendHttpReqMsg(req *http.Request) (*http.Response, error) { return rsp, nil } else { nextInterval := getNextBackoffInterval(retries, 2) - logger.SimappLog.Infof("http rsp error [%v], retrying after %d sec...", http.StatusText(rsp.StatusCode), nextInterval) + logger.SimappLog.Infof("http rsp error [%v], retrying after %d sec", http.StatusText(rsp.StatusCode), nextInterval) err = rsp.Body.Close() if err != nil { logger.SimappLog.Infoln(err) @@ -435,7 +462,7 @@ func sendMessage(msgChan chan configMessage, subProvisionEndpt SubProvisionEndpt logger.SimappLog.Infof("post message [%v] to %v", msg.String(), httpend) req, err := http.NewRequestWithContext(context.Background(), http.MethodPost, httpend, msg.msgPtr) if err != nil { - logger.SimappLog.Errorf("An Error Occurred %v", err) + logger.SimappLog.Errorf("an error occurred %v", err) time.Sleep(1 * time.Second) continue } @@ -673,13 +700,13 @@ func UpdateConfig(f string) error { for o := 0; o < len(NewSimappConfig.Configuration.Subscriber); o++ { newSubscribers := NewSimappConfig.Configuration.Subscriber[o] logger.SimappLog.Infoln("Subscribers:") - logger.SimappLog.Infoln(" UeIdStart", newSubscribers.UeIdStart) - logger.SimappLog.Infoln(" UeIdEnd", newSubscribers.UeIdEnd) - logger.SimappLog.Infoln(" PlmnId", newSubscribers.PlmnId) - logger.SimappLog.Infoln(" OPc", newSubscribers.OPc) - logger.SimappLog.Infoln(" OP", newSubscribers.OP) - logger.SimappLog.Infoln(" Key", newSubscribers.Key) - logger.SimappLog.Infoln(" SequenceNumber", newSubscribers.SequenceNumber) + logger.SimappLog.Infoln("UeIdStart", newSubscribers.UeIdStart) + logger.SimappLog.Infoln("UeIdEnd", newSubscribers.UeIdEnd) + logger.SimappLog.Infoln("PlmnId", newSubscribers.PlmnId) + logger.SimappLog.Infoln("OPc", newSubscribers.OPc) + logger.SimappLog.Infoln("OP", newSubscribers.OP) + logger.SimappLog.Infoln("Key", newSubscribers.Key) + logger.SimappLog.Infoln("SequenceNumber", newSubscribers.SequenceNumber) newStart, err := strconv.Atoi(newSubscribers.UeIdStart) if err != nil { @@ -877,11 +904,11 @@ func UpdateConfig(f string) error { func WatchConfig() { viper.WatchConfig() viper.OnConfigChange(func(e fsnotify.Event) { - logger.SimappLog.Infoln("****config file changed:", e.Name) + logger.SimappLog.Infoln("config file changed:", e.Name) if err := UpdateConfig("config/simapp.yaml"); err != nil { logger.SimappLog.Errorln("error in loading updated configuration ", err) } else { - logger.SimappLog.Infoln("****successfully updated configuration****") + logger.SimappLog.Infoln("successfully updated configuration") } }) logger.SimappLog.Infoln("watchConfig done") @@ -904,7 +931,7 @@ func dispatchAllSubscribers(configMsgChan chan configMessage) { } for i := start; i <= end; i++ { subscribers.UeId = fmt.Sprintf("%015d", i) - logger.SimappLog.Debugln("UeId", subscribers.UeId) + logger.SimappLog.Debugln("ueId", subscribers.UeId) b, err := json.Marshal(subscribers) if err != nil { logger.SimappLog.Errorln("error in marshal with subscribers", err) @@ -923,18 +950,18 @@ func dispatchAllSubscribers(configMsgChan chan configMessage) { func dispatchGroup(configMsgChan chan configMessage, group *DevGroup, msgOp int) { logger.SimappLog.Infoln("group name", group.Name) - logger.SimappLog.Infoln(" site name", group.SiteInfo) - logger.SimappLog.Infoln(" imsis", group.Imsis) + logger.SimappLog.Infoln("site name", group.SiteInfo) + logger.SimappLog.Infoln("imsis", group.Imsis) for im := 0; im < len(group.Imsis); im++ { - logger.SimappLog.Debugln(" IMSI", group.Imsis[im]) + logger.SimappLog.Debugln("imsi", group.Imsis[im]) } - logger.SimappLog.Infoln(" IpDomainName", group.IpDomainName) + logger.SimappLog.Infoln("IpDomainName", group.IpDomainName) ipDomain := group.IpDomain if group.IpDomain != nil { - logger.SimappLog.Infoln(" IpDomain Dnn", ipDomain.Dnn) - logger.SimappLog.Infoln(" IpDomain Dns Primary", ipDomain.DnsPrimary) - logger.SimappLog.Infoln(" IpDomain Mtu", ipDomain.Mtu) - logger.SimappLog.Infoln(" IpDomain UePool", ipDomain.UePool) + logger.SimappLog.Infoln("IpDomain Dnn", ipDomain.Dnn) + logger.SimappLog.Infoln("IpDomain Dns Primary", ipDomain.DnsPrimary) + logger.SimappLog.Infoln("IpDomain Mtu", ipDomain.Mtu) + logger.SimappLog.Infoln("IpDomain UePool", ipDomain.UePool) } b, err := json.Marshal(group) if err != nil { @@ -962,21 +989,21 @@ func dispatchAllGroups(configMsgChan chan configMessage) { } func dispatchNetworkSlice(configMsgChan chan configMessage, slice *NetworkSlice, msgOp int) { - logger.SimappLog.Infoln(" Slice Name:", slice.Name) - logger.SimappLog.Infof(" Slice sst %v, sd %v", slice.SliceId.Sst, slice.SliceId.Sd) - logger.SimappLog.Infoln(" Slice site info", slice.SiteInfo) + logger.SimappLog.Infoln("slice Name:", slice.Name) + logger.SimappLog.Infof("slice sst %v, sd %v", slice.SliceId.Sst, slice.SliceId.Sd) + logger.SimappLog.Infoln("slice site info", slice.SiteInfo) site := slice.SiteInfo - logger.SimappLog.Infoln(" Slice site name", site.SiteName) - logger.SimappLog.Infoln(" Slice gNB", len(site.Gnb)) + logger.SimappLog.Infoln("slice site name", site.SiteName) + logger.SimappLog.Infoln("slice gNB", len(site.Gnb)) for e := 0; e < len(site.Gnb); e++ { - logger.SimappLog.Infof(" Slice gNB[%v] = %s, tac: %d", e, site.Gnb[e].Name, site.Gnb[e].Tac) + logger.SimappLog.Infof("slice gNB[%v] = %s, tac: %d", e, site.Gnb[e].Name, site.Gnb[e].Tac) } - logger.SimappLog.Infoln(" Slice Plmn", site.Plmn) - logger.SimappLog.Infoln(" Slice Upf", site.Upf) + logger.SimappLog.Infoln("slice Plmn", site.Plmn) + logger.SimappLog.Infoln("slice Upf", site.Upf) - logger.SimappLog.Infoln(" Slice Device Groups", slice.DevGroups) + logger.SimappLog.Infoln("slice device groups", slice.DevGroups) for im := 0; im < len(slice.DevGroups); im++ { - logger.SimappLog.Infoln(" Attached Device Groups", slice.DevGroups[im]) + logger.SimappLog.Infoln("attached device groups", slice.DevGroups[im]) } b, err := json.Marshal(slice) @@ -987,7 +1014,7 @@ func dispatchNetworkSlice(configMsgChan chan configMessage, slice *NetworkSlice, reqMsgBody := bytes.NewBuffer(b) if !SimappConfig.Configuration.ConfigSlice { - logger.SimappLog.Warnln("Do not configure network slice") + logger.SimappLog.Warnln("do not configure network slice") return } var msg configMessage