From 92b7e4be405c21e959abb24da4d787aa13a37f9a Mon Sep 17 00:00:00 2001 From: "CTFang@WireLab" Date: Thu, 16 May 2024 06:29:35 +0000 Subject: [PATCH 1/4] fix: update golagci-lint setting and fix linter error --- .golangci.yml | 318 +++++++++++++----------- backend/WebUI/api_charging.go | 23 +- backend/WebUI/api_verify.go | 16 +- backend/WebUI/api_webui.go | 85 ++++--- backend/billing/client.go | 8 +- backend/billing/server.go | 8 +- backend/webui_context/nrf_management.go | 4 +- 7 files changed, 250 insertions(+), 212 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index 02ed57d6..a6423066 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -1,35 +1,24 @@ -# This file contains all available configuration options -# with their default values. + # options for analysis running run: - # default concurrency is a available CPU number + # Number of operating system threads (`GOMAXPROCS`) that can execute golangci-lint simultaneously. + # If it is explicitly set to 0 (i.e. not the default) then golangci-lint will automatically set the value to match Linux container CPU quota. + # Default: the number of logical CPUs in the machine concurrency: 4 + # timeout for analysis, e.g. 30s, 5m, default is 1m timeout: 3m + # exit code when at least one issue was found, default is 1 issues-exit-code: 1 + # include test files or not, default is true tests: true + # list of build tags, all linters use it. Default is empty list. - build-tags: - # which dirs to skip: issues from them won't be reported; - # can use regexp here: generated.*, regexp is applied on full path; - # default value is empty list, but default dirs are skipped independently - # from this option's value (see skip-dirs-use-default). - # "/" will be replaced by current OS file path separator to properly work - # on Windows. - skip-dirs: - # 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": + build-tags: [] + + # 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 # to go.mod are needed. This setting is most useful to check that go.mod does @@ -37,20 +26,46 @@ run: # If invoked with -mod=vendor, the go command assumes that the vendor # directory holds the correct copies of dependencies and ignores # the dependency descriptions in go.mod. - #modules-download-mode: readonly|release|vendor + # + # Allowed values: readonly|vendor|mod + # Default: "" + # modules-download-mode: readonly + # Allow multiple parallel golangci-lint instances running. - # If false (default) - golangci-lint acquires file lock on start. + # If false, golangci-lint acquires file lock on start. + # Default: false allow-parallel-runners: true + + # Allow multiple golangci-lint instances running, but serialize them around a lock. + # If false, golangci-lint exits with an error if it fails to acquire file lock on start. + # Default: false + allow-serial-runners: true + + go: '1.21' + # output configuration options output: # colored-line-number|line-number|json|tab|checkstyle|code-climate, default is "colored-line-number" - format: colored-line-number + formats: + - format: "colored-line-number" + path: stdout + # 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 print-linter-name: true # make issues output unique by line, default is true uniq-by-line: true + + # Sort results by the order defined in `sort-order`. + # Default: false + sort-results: true + sort-order: + - linter + - severity + - file # filepath, line, and column. + show-stats: true + # all available settings of specific linters linters-settings: errcheck: @@ -67,26 +82,22 @@ linters-settings: # path to a file containing a list of functions to exclude from checking # see https://github.com/kisielk/errcheck#excluding-functions for details #exclude: /path/to/file.txt - funlen: - lines: 60 - statements: 40 - gocognit: - # minimal code complexity to report, 30 by default (but we recommend 10-20) - min-complexity: 10 - nestif: - # minimal complexity of if statements to report, 5 by default - min-complexity: 4 + goconst: # minimal length of string constant, 3 by default - min-len: 3 - # minimal occurrences count to trigger, 3 by default + min-len: 5 + # Minimum occurrences of constant string count to trigger issue, 3 by default min-occurrences: 3 + # Exclude strings matching the given regular expression. + # Default: "" + ignore-strings: "get|post|put|delete|patch|options|head" + gocritic: # Which checks should be enabled; can't be combined with 'disabled-checks'; # See https://go-critic.github.io/overview#checks-overview # To check which checks are enabled run `GL_DEBUG=gocritic golangci-lint run` # By default list of stable checks is used. - enabled-checks: + enabled-checks: [] #- rangeValCopy # Which checks should be disabled; can't be combined with 'enabled-checks'; default is empty disabled-checks: @@ -94,17 +105,31 @@ linters-settings: # Enable multiple checks by tags, run `GL_DEBUG=gocritic golangci-lint run` to see all tags and checks. # Empty list by default. See https://github.com/go-critic/go-critic#usage -> section "Tags". enabled-tags: + - diagnostic - performance disabled-tags: - experimental - settings: # settings passed to gocritic + + # settings passed to gocritic + # The settings key is the name of a supported gocritic checker. + # The list of supported checkers can be find in https://go-critic.github.io/overview. + settings: captLocal: # must be valid enabled check name + # Whether to restrict checker to params only. paramsOnly: true rangeValCopy: - sizeThreshold: 32 - gocyclo: - # minimal code complexity to report, 30 by default (but we recommend 10-20) - min-complexity: 10 + # Size in bytes that makes the warning trigger. Default: 128 + # This size shoulb be smaller + sizeThreshold: 512 + hugeParam: + # Size in bytes that makes the warning trigger. Default: 80 + # This size shoulb be smaller + sizeThreshold: 512 + ifElseChain: + # Min number of if-else blocks that makes the warning trigger. + # Default: 2 + minThreshold: 4 + godox: # report any comments starting with keywords, this is useful for TODO or FIXME comments that # might be left in the code accidentally and should be resolved before merging @@ -116,167 +141,176 @@ linters-settings: #- OPTIMIZE # marks code that should be optimized before merging #- HACK # marks hack-arounds that should be removed before merging - XXX # Fatal! Important problem + gofmt: # simplify code: gofmt with `-s` option, true by default simplify: true - goimports: - # put imports beginning with prefix after 3rd-party packages; - # it's a comma-separated list of prefixes - local-prefixes: github.com/org/project - golint: - # 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 - gomodguard: - allowed: - modules: # List of allowed modules - # - gopkg.in/yaml.v2 - domains: # List of allowed module domains - # - golang.org - blocked: - modules: # List of blocked modules - # - github.com/uudashr/go-module: # Blocked module - # recommendations: # Recommended modules that should be used instead (Optional) - # - golang.org/x/mod - # reason: "`mod` is the official go.mod parser library." # Reason why the recommended module should be used (Optional) - versions: # List of blocked module version constraints - # - github.com/mitchellh/go-homedir: # Blocked module with version constraint - # 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) + + # TODO + # golint: + # # minimal confidence for issues, default is 0.8 + # min-confidence: 0.8 + + # TODO + # 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 + govet: - # report about shadowed variables - check-shadowing: true + enable-all: false + # enable or disable analyzers by name + enable: + - atomicalign + - shadow + - printf + # settings per analyzer settings: - printf: # analyzer name, run `go tool vet help` to see all analyzers + # analyzer name, run `go tool vet help` to see all analyzers + printf: funcs: # run `go tool vet help printf` to see available settings for `printf` analyzer - (github.com/golangci/golangci-lint/pkg/logutils.Log).Infof - (github.com/golangci/golangci-lint/pkg/logutils.Log).Warnf - (github.com/golangci/golangci-lint/pkg/logutils.Log).Errorf - (github.com/golangci/golangci-lint/pkg/logutils.Log).Fatalf - # enable or disable analyzers by name - enable: - - atomicalign - enable-all: false - disable: - - shadow - disable-all: false + shadow: + # Whether to be strict about shadowing; can be noisy. + # Default: false + strict: true + depguard: - list-type: blacklist - include-go-root: false - packages: - - github.com/sirupsen/logrus - packages-with-error-message: - # specify an error message to output when a blacklisted package is used - - github.com/sirupsen/logrus: "logging is allowed only by logutils.Log" + rules: + # Name of a rule. + main: + # Used to determine the package matching priority. + # There are three different modes: `original`, `strict`, and `lax`. + # Default: "original" + list-mode: original + deny: + - pkg: github.com/sirupsen/logrus + desc: "logging is allowed only by logutils.Log" + lll: # max line length, lines longer will be reported. Default is 120. # '\t' is counted as 1 character by default, and can be changed with the tab-width option line-length: 120 # tab width in spaces. Default to 1. tab-width: 1 - maligned: - # print struct with more effective memory layout or not, false by default - suggest-new: true + + # Deprecate + # maligned: + # # print struct with more effective memory layout or not, false by default + # suggest-new: true + nakedret: # make an issue if func has more lines of code than this setting and it has naked returns; default is 30 max-func-lines: 30 + testpackage: # regexp pattern to skip files skip-regexp: (export|internal)_test\.go + unused: - # treat code as a program (not a library) and report unused exported identifiers; default is false. - # XXX: if you enable this setting, unused will report a lot of false-positives in text editors: - # if it's called for subdir of a project it can't find funcs usages. All text editor integrations - # with golangci-lint call it on a directory with the changed file. - check-exported: false + # Mark all struct fields that have been written to as used. + # Default: true + field-writes-are-uses: true + # Treat IncDec statement (e.g. `i++` or `i--`) as both read and write operation instead of just write. + # Default: false + post-statements-are-reads: true + # Mark all exported identifiers as used. + # Default: true + exported-is-used: true + # Mark all exported fields as used. + # default: true + exported-fields-are-used: true + # Mark all function parameters as used. + # default: true + parameters-are-used: true + # Mark all local variables as used. + # default: true + local-variables-are-used: true + # Mark all identifiers inside generated files as used. + # Default: true + generated-is-used: true + 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: sections: - standard - default - prefix(github.com/free5gc) - section-separators: - - newLine + + # Skip generated files. + # Default: true + skip-generated: true + + # Enable custom order of sections. + # If `true`, make the section order the same as the order of `sections`. + # Default: false + custom-order: true + misspell: - #locale: US - ignore-words: - wsl: - # If true append is only allowed to be cuddled if appending value is - # matching variables, fields or types on line above. Default is true. - strict-append: true - # Allow calls and assignments to be cuddled as long as the lines have any - # matching variables, fields or types. Default is true. - allow-assign-and-call: true - # Allow multiline assignments to be cuddled. Default is true. - allow-multiline-assign: true - # Allow declarations (var) to be cuddled. - allow-cuddle-declarations: false - # Allow trailing comments in ending of blocks - allow-trailing-comment: true - # Force newlines in end of case at this limit (0 = never). - force-case-trailing-whitespace: 0 - # Force cuddling of err checks with err var assignment - force-err-cuddling: false - # Allow leading comments to be separated with empty liens - allow-separated-leading-comment: false - custom: + locale: US + ignore-words: [] + + # custom: # Each custom linter should have a unique name. linters: + disable-all: true enable: + - errcheck + - goconst + - gocritic + - godox - gofmt - govet - - errcheck + - lll + - nakedret + - testpackage - staticcheck - unused + - whitespace + - gci + - misspell - gosimple - - structcheck - - varcheck + - ineffassign - - deadcode - typecheck - # Additional - - lll - - godox - # - gomnd - # - goconst - # - gocognit - # - maligned - # - nestif - # - gomodguard - - nakedret - # - golint - - gci - - misspell - gofumpt - - whitespace - unconvert - predeclared - noctx - dogsled - bodyclose - asciicheck + + # - structcheck # Deprecate + # - varcheck # Deprecate + # - deadcode # Deprecate + # - gomnd + # - maligned # - stylecheck # - unparam - # - wsl - #disable-all: false + # Enable only fast linters from enabled linters set (first run won't be fast) + # Default: false fast: true + + issues: # List of regexps of issue texts to exclude, empty list by default. # But independently from this option we use default exclude patterns, # it can be disabled by `exclude-use-default: false`. To list all # excluded by default patterns execute `golangci-lint run --help` - exclude: + exclude: [] # Excluding configuration per-path, per-linter, per-text and per-source - exclude-rules: + exclude-rules: [] # Exclude some linters from running on tests files. # Independently from option `exclude` we use default exclude patterns, # it can be disabled by this option. To list all @@ -287,7 +321,7 @@ issues: # regular expressions become case sensitive. exclude-case-sensitive: false # The list of ids of default excludes to include or disable. By default it's empty. - include: + include: [] #- EXC0002 # disable excluding of issues about comments from golint # Maximum issues count per one linter. Set to 0 to disable. Default is 50. #max-issues-per-linter: 0 diff --git a/backend/WebUI/api_charging.go b/backend/WebUI/api_charging.go index 22db196e..e706a80f 100644 --- a/backend/WebUI/api_charging.go +++ b/backend/WebUI/api_charging.go @@ -21,6 +21,11 @@ import ( "github.com/free5gc/webconsole/backend/webui_context" ) +const ( + ChargingOffline = "Offline" + ChargingOnline = "Online" +) + // Get vol from CDR // TS 32.297: Charging Data Record (CDR) file format and transfer func parseCDR(supi string) (map[int64]RatingGroupDataUsage, error) { @@ -84,7 +89,7 @@ func GetChargingData(c *gin.Context) { } logger.BillingLog.Traceln(chargingMethod) - if chargingMethod != "Offline" && chargingMethod != "Online" { + if chargingMethod != ChargingOffline && chargingMethod != ChargingOnline { c.JSON(http.StatusBadRequest, gin.H{"cause": "not support chargingMethod" + chargingMethod}) return } @@ -176,9 +181,9 @@ func GetChargingRecord(c *gin.Context) { "ueId": supi, "ratingGroup": rg, } - chargingDataInterface, err := mongoapi.RestfulAPIGetOne(chargingDataColl, filter) - if err != nil { - logger.ProcLog.Errorf("PostSubscriberByID err: %+v", err) + chargingDataInterface, err_get := mongoapi.RestfulAPIGetOne(chargingDataColl, filter) + if err_get != nil { + logger.ProcLog.Errorf("PostSubscriberByID err: %+v", err_get) } if len(chargingDataInterface) == 0 { logger.BillingLog.Warningf("ratingGroup: %d not found in mongoapi, may change the rg id", rg) @@ -193,10 +198,10 @@ func GetChargingRecord(c *gin.Context) { logger.BillingLog.Debugf("add ratingGroup: %d, supi: %s, method: %s", rg, supi, chargingData.ChargingMethod) switch chargingData.ChargingMethod { - case "Offline": - unitcost, err := strconv.ParseInt(chargingData.UnitCost, 10, 64) - if err != nil { - logger.BillingLog.Error("Offline unitCost strconv: ", err.Error()) + case ChargingOffline: + unitcost, err_parse := strconv.ParseInt(chargingData.UnitCost, 10, 64) + if err_parse != nil { + logger.BillingLog.Error("Offline unitCost strconv: ", err_parse.Error()) unitcost = 1 } @@ -218,7 +223,7 @@ func GetChargingRecord(c *gin.Context) { pdu_level.unitcost = unitcost } offlineChargingSliceTypeMap[key] = pdu_level - case "Online": + case ChargingOnline: tmpInt, err1 := strconv.Atoi(chargingData.Quota) if err1 != nil { logger.BillingLog.Error("Quota strconv: ", err1, rg, du, chargingData) diff --git a/backend/WebUI/api_verify.go b/backend/WebUI/api_verify.go index 27ad8eb1..174cee9d 100644 --- a/backend/WebUI/api_verify.go +++ b/backend/WebUI/api_verify.go @@ -40,15 +40,15 @@ func GetSmfUserPlaneInfo() (interface{}, error) { // TODO: support fetching data from multiple SMF if smfUris := webuiSelf.GetOamUris(models.NfType_SMF); smfUris != nil { requestUri := fmt.Sprintf("%s/nsmf-oam/v1/user-plane-info/", smfUris[0]) - req, err := http.NewRequestWithContext(ctx, http.MethodGet, requestUri, nil) - if err != nil { - logger.ProcLog.Error(err) - return jsonData, err + req, err_req := http.NewRequestWithContext(ctx, http.MethodGet, requestUri, nil) + if err_req != nil { + logger.ProcLog.Error(err_req) + return jsonData, err_req } - resp, err := httpsClient.Do(req) - if err != nil { - logger.ProcLog.Error(err) - return jsonData, err + resp, err_rsp := httpsClient.Do(req) + if err_rsp != nil { + logger.ProcLog.Error(err_rsp) + return jsonData, err_rsp } defer func() { if closeErr := resp.Body.Close(); closeErr != nil { diff --git a/backend/WebUI/api_webui.go b/backend/WebUI/api_webui.go index 6e2d453a..38496868 100644 --- a/backend/WebUI/api_webui.go +++ b/backend/WebUI/api_webui.go @@ -713,7 +713,7 @@ func PutTenantByID(c *gin.Context) { } var tenantData Tenant - if err := c.ShouldBindJSON(&tenantData); err != nil { + if err = c.ShouldBindJSON(&tenantData); err != nil { c.JSON(http.StatusBadRequest, gin.H{}) return } @@ -721,8 +721,8 @@ func PutTenantByID(c *gin.Context) { tenantBsonM := toBsonM(tenantData) filterTenantIdOnly = bson.M{"tenantId": tenantId} - if _, err := mongoapi.RestfulAPIPost(tenantDataColl, filterTenantIdOnly, tenantBsonM); err != nil { - logger.ProcLog.Errorf("PutTenantByID err: %+v", err) + if _, err_post := mongoapi.RestfulAPIPost(tenantDataColl, filterTenantIdOnly, tenantBsonM); err_post != nil { + logger.ProcLog.Errorf("PutTenantByID err: %+v", err_post) c.JSON(http.StatusInternalServerError, gin.H{}) return } @@ -894,8 +894,8 @@ func PostUserByID(c *gin.Context) { userBsonM := toBsonM(userData) filterUserIdOnly := bson.M{"tenantId": userData.TenantId, "userId": userData.UserId} - if _, err := mongoapi.RestfulAPIPost(userDataColl, filterUserIdOnly, userBsonM); err != nil { - logger.ProcLog.Errorf("PostUserByID err: %+v", err) + if _, err_post := mongoapi.RestfulAPIPost(userDataColl, filterUserIdOnly, userBsonM); err_post != nil { + logger.ProcLog.Errorf("PostUserByID err: %+v", err_post) c.JSON(http.StatusInternalServerError, gin.H{}) return } @@ -946,9 +946,9 @@ func PutUserByID(c *gin.Context) { if newUserData.Email != "" && newUserData.Email != userData.Email { filterEmail := bson.M{"email": newUserData.Email} - sameEmailInterface, err := mongoapi.RestfulAPIGetOne(userDataColl, filterEmail) - if err != nil { - logger.ProcLog.Errorf("PutUserByID err: %+v", err) + sameEmailInterface, err_get := mongoapi.RestfulAPIGetOne(userDataColl, filterEmail) + if err_get != nil { + logger.ProcLog.Errorf("PutUserByID err: %+v", err_get) c.JSON(http.StatusInternalServerError, gin.H{}) return } @@ -960,9 +960,9 @@ func PutUserByID(c *gin.Context) { } if newUserData.EncryptedPassword != "" { - hash, err := bcrypt.GenerateFromPassword([]byte(newUserData.EncryptedPassword), 12) - if err != nil { - logger.ProcLog.Errorf("PutUserByID err: %+v", err) + hash, err_gen := bcrypt.GenerateFromPassword([]byte(newUserData.EncryptedPassword), 12) + if err_gen != nil { + logger.ProcLog.Errorf("PutUserByID err: %+v", err_gen) c.JSON(http.StatusInternalServerError, gin.H{}) return } @@ -970,8 +970,8 @@ func PutUserByID(c *gin.Context) { } userBsonM := toBsonM(userData) - if _, err := mongoapi.RestfulAPIPost(userDataColl, filterUserIdOnly, userBsonM); err != nil { - logger.ProcLog.Errorf("PutUserByID err: %+v", err) + if _, err_post := mongoapi.RestfulAPIPost(userDataColl, filterUserIdOnly, userBsonM); err_post != nil { + logger.ProcLog.Errorf("PutUserByID err: %+v", err_post) c.JSON(http.StatusInternalServerError, gin.H{}) return } @@ -1035,16 +1035,15 @@ func GetSubscribers(c *gin.Context) { tenantId := amData["tenantId"] filterUeIdOnly := bson.M{"ueId": ueId} - authSubsDataInterface, err := mongoapi.RestfulAPIGetOne(authSubsDataColl, filterUeIdOnly) - if err != nil { - logger.ProcLog.Errorf("GetSubscribers err: %+v", err) + authSubsDataInterface, err_get := mongoapi.RestfulAPIGetOne(authSubsDataColl, filterUeIdOnly) + if err_get != nil { + logger.ProcLog.Errorf("GetSubscribers err: %+v", err_get) c.JSON(http.StatusInternalServerError, gin.H{}) return } var authSubsData AuthSub - err = json.Unmarshal(mapToByte(authSubsDataInterface), &authSubsData) - if err != nil { + if err = json.Unmarshal(mapToByte(authSubsDataInterface), &authSubsData); err != nil { logger.ProcLog.Errorf("GetSubscribers err: %+v", err) c.JSON(http.StatusInternalServerError, gin.H{}) return @@ -1140,55 +1139,55 @@ func GetSubscriberByID(c *gin.Context) { } var authSubsData models.AuthenticationSubscription - if err := json.Unmarshal(mapToByte(authSubsDataInterface), &authSubsData); err != nil { + if err = json.Unmarshal(mapToByte(authSubsDataInterface), &authSubsData); err != nil { logger.ProcLog.Errorf("GetSubscriberByID err: %+v", err) c.JSON(http.StatusInternalServerError, gin.H{}) return } var amDataData models.AccessAndMobilitySubscriptionData - if err := json.Unmarshal(mapToByte(amDataDataInterface), &amDataData); err != nil { + if err = json.Unmarshal(mapToByte(amDataDataInterface), &amDataData); err != nil { logger.ProcLog.Errorf("GetSubscriberByID err: %+v", err) c.JSON(http.StatusInternalServerError, gin.H{}) return } var smDataData []models.SessionManagementSubscriptionData - if err := json.Unmarshal(sliceToByte(smDataDataInterface), &smDataData); err != nil { + if err = json.Unmarshal(sliceToByte(smDataDataInterface), &smDataData); err != nil { logger.ProcLog.Errorf("GetSubscriberByID err: %+v", err) c.JSON(http.StatusInternalServerError, gin.H{}) return } var smfSelData models.SmfSelectionSubscriptionData - if err := json.Unmarshal(mapToByte(smfSelDataInterface), &smfSelData); err != nil { + if err = json.Unmarshal(mapToByte(smfSelDataInterface), &smfSelData); err != nil { logger.ProcLog.Errorf("GetSubscriberByID err: %+v", err) c.JSON(http.StatusInternalServerError, gin.H{}) return } var amPolicyData models.AmPolicyData - if err := json.Unmarshal(mapToByte(amPolicyDataInterface), &amPolicyData); err != nil { + if err = json.Unmarshal(mapToByte(amPolicyDataInterface), &amPolicyData); err != nil { logger.ProcLog.Errorf("GetSubscriberByID err: %+v", err) c.JSON(http.StatusInternalServerError, gin.H{}) return } var smPolicyData models.SmPolicyData - if err := json.Unmarshal(mapToByte(smPolicyDataInterface), &smPolicyData); err != nil { + if err = json.Unmarshal(mapToByte(smPolicyDataInterface), &smPolicyData); err != nil { logger.ProcLog.Errorf("GetSubscriberByID err: %+v", err) c.JSON(http.StatusInternalServerError, gin.H{}) return } var flowRules []FlowRule - if err := json.Unmarshal(sliceToByte(flowRuleDataInterface), &flowRules); err != nil { + if err = json.Unmarshal(sliceToByte(flowRuleDataInterface), &flowRules); err != nil { logger.ProcLog.Errorf("GetSubscriberByID err: %+v", err) c.JSON(http.StatusInternalServerError, gin.H{}) return } var qosFlows []QosFlow - if err := json.Unmarshal(sliceToByte(qosFlowInterface), &qosFlows); err != nil { + if err = json.Unmarshal(sliceToByte(qosFlowInterface), &qosFlows); err != nil { logger.ProcLog.Errorf("GetSubscriberByID err: %+v", err) c.JSON(http.StatusInternalServerError, gin.H{}) return } var chargingDatas []ChargingData - if err := json.Unmarshal(sliceToByte(chargingDatasInterface), &chargingDatas); err != nil { + if err = json.Unmarshal(sliceToByte(chargingDatasInterface), &chargingDatas); err != nil { logger.ProcLog.Errorf("GetSubscriberByID err: %+v", err) c.JSON(http.StatusInternalServerError, gin.H{}) return @@ -1327,9 +1326,9 @@ func PostSubscriberByID(c *gin.Context) { // Lookup same UE ID of other tenant's subscription. if claims != nil { - authSubsDataInterface, err := mongoapi.RestfulAPIGetOne(authSubsDataColl, filterUeIdOnly) - if err != nil { - logger.ProcLog.Errorf("PostSubscriberByID err: %+v", err) + authSubsDataInterface, err_get := mongoapi.RestfulAPIGetOne(authSubsDataColl, filterUeIdOnly) + if err_get != nil { + logger.ProcLog.Errorf("PostSubscriberByID err: %+v", err_get) c.JSON(http.StatusInternalServerError, gin.H{}) return } @@ -1536,7 +1535,7 @@ func dbOperation(ueId string, servingPlmnId string, method string, subsData *Sub chargingDataBsonM := toBsonM(chargingData) // Clear quota for offline charging flow - if chargingData.ChargingMethod == "Offline" { + if chargingData.ChargingMethod == ChargingOffline { chargingDataBsonM["quota"] = "0" } @@ -1583,8 +1582,8 @@ func dbOperation(ueId string, servingPlmnId string, method string, subsData *Sub chargingDataBsonM["ueId"] = ueId chargingDataBsonM["servingPlmnId"] = servingPlmnId - if _, err := mongoapi.RestfulAPIPutOne(chargingDataColl, chargingFilter, chargingDataBsonM); err != nil { - logger.ProcLog.Errorf("PostSubscriberByID err: %+v", err) + if _, err_put := mongoapi.RestfulAPIPutOne(chargingDataColl, chargingFilter, chargingDataBsonM); err != nil { + logger.ProcLog.Errorf("PostSubscriberByID err: %+v", err_put) } } } @@ -1728,16 +1727,16 @@ func PatchSubscriberByID(c *gin.Context) { c.JSON(http.StatusNoContent, gin.H{}) } -func removeCdrFile(CdrFilePath string) { - files, err := filepath.Glob(CdrFilePath + "*.cdr") +func removeCdrFile(cdrFilePath string) { + files, err := filepath.Glob(cdrFilePath + "*.cdr") if err != nil { - logger.BillingLog.Warnf("CDR file not found in %s", CdrFilePath) + logger.BillingLog.Warnf("CDR file not found in %s", cdrFilePath) } for _, file := range files { - if _, err := os.Stat(file); err == nil { + if _, err = os.Stat(file); err == nil { logger.BillingLog.Infof("Remove CDR file: " + file) - if err := os.Remove(file); err != nil { + if err = os.Remove(file); err != nil { logger.BillingLog.Warnf("Failed to remove CDR file: %s\n", file) } } @@ -1907,16 +1906,16 @@ func ChangePasswordInfo(c *gin.Context) { } if newUserData.EncryptedPassword != "" { - hash, err := bcrypt.GenerateFromPassword([]byte(newUserData.EncryptedPassword), 12) - if err != nil { - logger.ProcLog.Errorf("GenerateFromPassword err: %+v", err) + hash, err_gen := bcrypt.GenerateFromPassword([]byte(newUserData.EncryptedPassword), 12) + if err_gen != nil { + logger.ProcLog.Errorf("GenerateFromPassword err: %+v", err_gen) } userData.EncryptedPassword = string(hash) } userBsonM := toBsonM(userData) - if _, err := mongoapi.RestfulAPIPost(userDataColl, filterEmailOnly, userBsonM); err != nil { - logger.ProcLog.Errorf("PutUserByID err: %+v", err) + if _, err_put := mongoapi.RestfulAPIPost(userDataColl, filterEmailOnly, userBsonM); err_put != nil { + logger.ProcLog.Errorf("PutUserByID err: %+v", err_put) } c.JSON(http.StatusOK, userData) diff --git a/backend/billing/client.go b/backend/billing/client.go index e042e215..1b6bcb66 100644 --- a/backend/billing/client.go +++ b/backend/billing/client.go @@ -41,18 +41,18 @@ func PullCDRFile(c *ftp.ServerConn, fileName string) ([]byte, error) { } defer func() { - if err := r.Close(); err != nil { + if err = r.Close(); err != nil { logger.BillingLog.Error(err) } }() logger.BillingLog.Info("Pull CDR file success") - if err := c.Quit(); err != nil { + if err = c.Quit(); err != nil { return nil, err } - cdr, err1 := io.ReadAll(r) + cdr, err_read := io.ReadAll(r) - return cdr, err1 + return cdr, err_read } diff --git a/backend/billing/server.go b/backend/billing/server.go index d31cb1d7..3b36b78d 100644 --- a/backend/billing/server.go +++ b/backend/billing/server.go @@ -50,8 +50,8 @@ func OpenServer(wg *sync.WaitGroup) *BillingDomain { wg: wg, } if _, err := os.Stat("/tmp/webconsole"); err != nil { - if err := os.Mkdir("/tmp/webconsole", os.ModePerm); err != nil { - logger.BillingLog.Error(err) + if err_mk := os.Mkdir("/tmp/webconsole", os.ModePerm); err_mk != nil { + logger.BillingLog.Error(err_mk) } } @@ -90,8 +90,8 @@ func OpenServer(wg *sync.WaitGroup) *BillingDomain { return nil } - if err := os.WriteFile(confFile, file, 0o600); err != nil { //nolint: gomnd - logger.BillingLog.Errorf("Couldn't create conf file %v", confFile) + if err = os.WriteFile(confFile, file, 0o600); err != nil { + logger.BillingLog.Errorf("Couldn't create conf file %v, err: %+v", confFile, err) return nil } diff --git a/backend/webui_context/nrf_management.go b/backend/webui_context/nrf_management.go index 1e6224f7..f9ee9a01 100644 --- a/backend/webui_context/nrf_management.go +++ b/backend/webui_context/nrf_management.go @@ -75,9 +75,9 @@ func SendNFRegistration() error { return nil } -func RetrySendNFRegistration(MaxRetry int) error { +func RetrySendNFRegistration(maxRetry int) error { retryCount := 0 - for retryCount < MaxRetry { + for retryCount < maxRetry { err := SendNFRegistration() if err == nil { return nil From 539dfe2a5c353e81145a1efd683103c8e24b6d6a Mon Sep 17 00:00:00 2001 From: "CTFang@WireLab" Date: Thu, 16 May 2024 06:39:42 +0000 Subject: [PATCH 2/4] fix: remove unused setting in golangci.yml --- .golangci.yml | 64 +++++++++++++++++++++------------------------------ 1 file changed, 26 insertions(+), 38 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index a6423066..b2bd7d2e 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -146,18 +146,6 @@ linters-settings: # simplify code: gofmt with `-s` option, true by default simplify: true - # TODO - # golint: - # # minimal confidence for issues, default is 0.8 - # min-confidence: 0.8 - - # TODO - # 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 - govet: enable-all: false # enable or disable analyzers by name @@ -198,11 +186,6 @@ linters-settings: line-length: 120 # tab width in spaces. Default to 1. tab-width: 1 - - # Deprecate - # maligned: - # # print struct with more effective memory layout or not, false by default - # suggest-new: true nakedret: # make an issue if func has more lines of code than this setting and it has naked returns; default is 30 @@ -289,14 +272,7 @@ linters: - dogsled - bodyclose - asciicheck - - # - structcheck # Deprecate - # - varcheck # Deprecate - # - deadcode # Deprecate - # - gomnd - # - maligned - # - stylecheck - # - unparam + - dupl # Enable only fast linters from enabled linters set (first run won't be fast) # Default: false @@ -338,25 +314,37 @@ issues: new-from-rev: "" # Show only new issues created in git patch with set file path. #new-from-patch: path/to/patch/file + severity: - # Default value is empty string. - # Set the default severity for issues. If severity rules are defined and the issues - # do not match or no severity is provided to the rule this will be the default - # severity applied. Severities should match the supported severity names of the - # selected out format. + # Set the default severity for issues. + # + # If severity rules are defined and the issues do not match or no severity is provided to the rule + # this will be the default severity applied. + # Severities should match the supported severity names of the selected out format. # - Code climate: https://docs.codeclimate.com/docs/issues#issue-severity - # - Checkstyle: https://checkstyle.sourceforge.io/property_types.html#severity - # - Github: https://help.github.com/en/actions/reference/workflow-commands-for-github-actions#setting-an-error-message + # - Checkstyle: https://checkstyle.sourceforge.io/property_types.html#SeverityLevel + # - GitHub: https://help.github.com/en/actions/reference/workflow-commands-for-github-actions#setting-an-error-message + # - TeamCity: https://www.jetbrains.com/help/teamcity/service-messages.html#Inspection+Instance + # + # `@linter` can be used as severity value to keep the severity from linters (e.g. revive, gosec, ...) + # + # Default: "" default-severity: error + # The default value is false. # If set to true severity-rules regular expressions become case sensitive. case-sensitive: false - # Default value is empty list. - # When a list of severity rules are provided, severity information will be added to lint - # issues. Severity rules have the same filtering capability as exclude rules except you - # are allowed to specify one matcher per severity rule. + + # When a list of severity rules are provided, severity information will be added to lint issues. + # Severity rules have the same filtering capability as exclude rules + # except you are allowed to specify one matcher per severity rule. + # + # `@linter` can be used as severity value to keep the severity from linters (e.g. revive, gosec, ...) + # # Only affects out formats that support setting severity information. + # + # Default: [] rules: - linters: - - gomnd - severity: ignore + - dupl + severity: info From 8553d72c70f85857f3e03041f7f4b06bed7ba6cf Mon Sep 17 00:00:00 2001 From: "CTFang@WireLab" Date: Tue, 21 May 2024 03:31:33 +0000 Subject: [PATCH 3/4] feat: add gomnd in golangci-lint --- .golangci.yml | 35 +++++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index b2bd7d2e..2e5e8d95 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -241,6 +241,37 @@ linters-settings: locale: US ignore-words: [] + gomnd: + # !important in golangci-lint v1.58.0, gomnd is replaced by mnd + # List of enabled checks, see https://github.com/tommy-muehle/go-mnd/#checks for description. + # Default: ["argument", "case", "condition", "operation", "return", "assign"] + checks: + # - argument + - case + # - condition + - operation + - return + # - assign + # List of numbers to exclude from analysis. + # The numbers should be written as string. + # Values always ignored: "1", "1.0", "0" and "0.0" + # Default: [] + ignored-numbers: [] + # List of file patterns to exclude from analysis. + # Values always ignored: `.+_test.go` + # Default: [] + ignored-files: [] + # List of function patterns to exclude from analysis. + # Following functions are always ignored: `time.Date`, + # `strconv.FormatInt`, `strconv.FormatUint`, `strconv.FormatFloat`, + # `strconv.ParseInt`, `strconv.ParseUint`, `strconv.ParseFloat`. + # Default: [] + ignored-functions: + - 'os\.Mkdir' + - 'os\.MkdirAll' + - '^math\.' + - '^http\.StatusText$' + # custom: # Each custom linter should have a unique name. @@ -262,7 +293,7 @@ linters: - gci - misspell - gosimple - + - gomnd - ineffassign - typecheck - gofumpt @@ -346,5 +377,5 @@ severity: # Default: [] rules: - linters: - - dupl + - gomnd severity: info From 21055d60617331e37ef872c9c81bb3d55b903e7e Mon Sep 17 00:00:00 2001 From: "CTFang@WireLab" Date: Wed, 22 May 2024 06:16:37 +0000 Subject: [PATCH 4/4] feat: use config file in billing server --- backend/billing/server.go | 63 ++++++++++++++++----------------------- backend/factory/config.go | 21 ++++++++----- config/webuicfg.yaml | 11 +++++-- 3 files changed, 47 insertions(+), 48 deletions(-) diff --git a/backend/billing/server.go b/backend/billing/server.go index 3b36b78d..0517333f 100644 --- a/backend/billing/server.go +++ b/backend/billing/server.go @@ -4,10 +4,12 @@ package billing import ( "encoding/json" "os" + "path" "strconv" "sync" "github.com/fclairamb/ftpserver/config" + ftpconf "github.com/fclairamb/ftpserver/config/confpar" "github.com/fclairamb/ftpserver/server" ftpserver "github.com/fclairamb/ftpserverlib" @@ -21,55 +23,40 @@ type BillingDomain struct { wg *sync.WaitGroup } -type Access struct { - User string `json:"user"` - Pass string `json:"pass"` - Fs string `json:"fs"` - Params map[string]string `json:"params"` -} - -type PortRange struct { - Start int `json:"start"` - End int `json:"end"` -} - -type FtpConfig struct { - Version int `json:"version"` - Accesses []Access `json:"accesses"` - Listen_address string `json:"listen_address"` - - Passive_transfer_port_range PortRange `json:"passive_transfer_port_range"` -} - // The ftp server is for CDR Push method, that is the CHF will send the CDR file to the FTP server func OpenServer(wg *sync.WaitGroup) *BillingDomain { - // Arguments vars - confFile := "/tmp/webconsole/ftpserver.json" - b := &BillingDomain{ wg: wg, } - if _, err := os.Stat("/tmp/webconsole"); err != nil { - if err_mk := os.Mkdir("/tmp/webconsole", os.ModePerm); err_mk != nil { + + billingConfig := factory.WebuiConfig.Configuration.BillingServer + + basePath := billingConfig.BastPath + confFile := path.Join(basePath, "ftpserver.json") + + if _, err := os.Stat(basePath); err != nil { + if err_mk := os.Mkdir(basePath, os.ModePerm); err_mk != nil { logger.BillingLog.Error(err_mk) } } - billingConfig := factory.WebuiConfig.Configuration.BillingServer addr := billingConfig.HostIPv4 + ":" + strconv.Itoa(billingConfig.ListenPort) params := map[string]string{ - "basePath": "/tmp/webconsole", + "basePath": basePath, } - if billingConfig.Tls != nil { - params["cert"] = billingConfig.Tls.Pem - params["key"] = billingConfig.Tls.Key + logger.BillingLog.Infof("Open BillingServer on %+v", basePath) + + if billingConfig.Cert != nil { + params["cert"] = billingConfig.Cert.Pem + params["key"] = billingConfig.Cert.Key + logger.BillingLog.Infof("Use tls: %+v, %+v", params["cert"], params["key"]) } - ftpConfig := FtpConfig{ + ftpConfig := ftpconf.Content{ Version: 1, - Accesses: []Access{ + Accesses: []*ftpconf.Access{ { User: "admin", Pass: "free5gc", @@ -77,11 +64,11 @@ func OpenServer(wg *sync.WaitGroup) *BillingDomain { Params: params, }, }, - Passive_transfer_port_range: PortRange{ - Start: 2123, - End: 2130, + PassiveTransferPortRange: &ftpconf.PortRange{ + Start: billingConfig.PortRange.Start, + End: billingConfig.PortRange.End, }, - Listen_address: addr, + ListenAddress: addr, } file, err := json.MarshalIndent(ftpConfig, "", " ") @@ -100,7 +87,7 @@ func OpenServer(wg *sync.WaitGroup) *BillingDomain { logger.BillingLog.Error("Can't load conf", "Err", errConfig) return nil } - logger.BillingLog.Warnf("conf %+v", conf.Content.Accesses[0].Params) + // Loading the driver var errNewServer error b.driver, errNewServer = server.NewServer(conf, logger.FtpServerLog) @@ -118,7 +105,7 @@ func OpenServer(wg *sync.WaitGroup) *BillingDomain { b.ftpServer.Logger = logger.FtpServerLog go b.Serve() - logger.BillingLog.Info("Billing server Start") + logger.BillingLog.Info("Billing server started") return b } diff --git a/backend/factory/config.go b/backend/factory/config.go index a4dd3c9f..f4db6bb0 100644 --- a/backend/factory/config.go +++ b/backend/factory/config.go @@ -35,7 +35,7 @@ func (c *Config) Validate() (bool, error) { } type Info struct { - Version string `yaml:"version,omitempty" valid:"required,in(1.0.2)"` + Version string `yaml:"version,omitempty" valid:"required,in(1.0.3)"` Description string `yaml:"description,omitempty" valid:"type(string)"` } @@ -58,17 +58,24 @@ type WebServer struct { PORT string `yaml:"port" valid:"required"` } -type Tls struct { +type Cert struct { Pem string `yaml:"pem,omitempty" valid:"type(string),minstringlength(1),required"` Key string `yaml:"key,omitempty" valid:"type(string),minstringlength(1),required"` } +type PortRange struct { + Start int `yaml:"start,omitempty" valid:"required" json:"start"` + End int `yaml:"end,omitempty" valid:"required" json:"end"` +} + type BillingServer struct { - Enable bool `yaml:"enable,omitempty" valid:"required,type(bool)"` - HostIPv4 string `yaml:"hostIPv4,omitempty" valid:"required,host"` - Port int `yaml:"port,omitempty" valid:"optional,port"` - ListenPort int `yaml:"listenPort,omitempty" valid:"required,port"` - Tls *Tls `yaml:"tls,omitempty" valid:"optional"` + Enable bool `yaml:"enable,omitempty" valid:"required,type(bool)"` + HostIPv4 string `yaml:"hostIPv4,omitempty" valid:"required,host"` + ListenPort int `yaml:"listenPort,omitempty" valid:"required,port"` + PortRange PortRange `yaml:"portRange,omitempty" valid:"required"` + BastPath string `yaml:"basePath,omitempty" valid:"type(string),required"` + Cert *Cert `yaml:"cert,omitempty" valid:"optional"` + Port int `yaml:"port,omitempty" valid:"optional,port"` } type Mongodb struct { diff --git a/config/webuicfg.yaml b/config/webuicfg.yaml index 232a56f8..3b3e3169 100644 --- a/config/webuicfg.yaml +++ b/config/webuicfg.yaml @@ -1,5 +1,5 @@ info: - version: 1.0.2 + version: 1.0.3 description: WebUI initial local configuration configuration: @@ -15,10 +15,15 @@ configuration: enable: true hostIPv4: 127.0.0.1 listenPort: 2121 - port: 2122 - tls: + portRange: # passive port range + start: 2123 + end: 2130 + basePath: /tmp/webconsole + port: 2122 # CGF's FTP server port (not used for now) + cert: pem: cert/chf.pem key: cert/chf.key + logger: # log output setting enable: true # true or false