From 376e61b6de0385c6c63bac108d20cfb92bf86dd6 Mon Sep 17 00:00:00 2001 From: "Arrobo, Gabriel" Date: Fri, 1 Nov 2024 09:56:20 -0700 Subject: [PATCH 1/2] Refactor path for configuration file, option(s) and Docker image Signed-off-by: Arrobo, Gabriel --- .golangci.yml | 46 +++++++++--------------- Dockerfile | 10 ++---- consumer/communication.go | 9 ++++- consumer/nf_management.go | 2 +- factory/config.go | 1 + pcf.go | 3 +- producer/policyauthorization.go | 2 +- service/init.go | 63 +++++++++++++++++---------------- util/init_context.go | 4 +-- util/pcf_util.go | 5 --- 10 files changed, 66 insertions(+), 79 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index 76c350f..6160a2e 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -1,8 +1,7 @@ +# SPDX-FileCopyrightText: 2024 Intel Corporation # SPDX-FileCopyrightText: 2021 Open Networking Foundation # Copyright 2019 free5GC.org -# # SPDX-License-Identifier: Apache-2.0 -# # This file contains all available configuration options # with their default values. @@ -28,19 +27,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: - - "api_.*\\.go$" - - "model_.*\\.go$" - - "routers.go" - - "client.go" - - "configuration.go" - - "nas.go" # 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 @@ -56,7 +42,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 @@ -139,10 +125,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 @@ -160,8 +150,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 @@ -204,8 +192,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,7 +217,7 @@ linters: # - gocognit # - nestif # - gomodguard - # - nakedret + - nakedret - gci - misspell - gofumpt @@ -240,11 +226,11 @@ linters: - predeclared - noctx - dogsled - # - bodyclose + - bodyclose - asciicheck - #- stylecheck - # - unparam - # - wsl + # - stylecheck + # - unparam + # - wsl #disable-all: false fast: true @@ -255,6 +241,8 @@ issues: # excluded by default patterns execute `golangci-lint run --help` exclude: # Excluding configuration per-path, per-linter, per-text and per-source + exclude-files: + - "routers.go" exclude-rules: # Exclude some linters from running on tests files. # Independently from option `exclude` we use default exclude patterns, diff --git a/Dockerfile b/Dockerfile index 62a6cf1..ede04b2 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 \ apt-transport-https \ @@ -28,7 +26,8 @@ RUN make all FROM alpine:3.20 AS pcf -LABEL description="ONF open source 5G Core Network" \ +LABEL maintainer="Aether SD-Core " \ + description="ONF open source 5G Core Network" \ version="Stage 3" ARG DEBUG_TOOLS @@ -38,8 +37,5 @@ RUN if [ "$DEBUG_TOOLS" = "true" ]; then \ apk update && apk add --no-cache -U vim strace net-tools curl netcat-openbsd bind-tools; \ fi -# Set working dir -WORKDIR /free5gc/pcf - # Copy executable and default certs -COPY --from=builder /go/src/pcf/bin/* . +COPY --from=builder /go/src/pcf/bin/* /usr/local/bin/. diff --git a/consumer/communication.go b/consumer/communication.go index 5752088..7ee8e64 100644 --- a/consumer/communication.go +++ b/consumer/communication.go @@ -45,12 +45,19 @@ func AmfStatusChangeSubscribe(amfUri string, guamiList []models.Guami) ( } else if httpResp != nil { if httpResp.Status != localErr.Error() { err = localErr - return + return nil, err } problem := localErr.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails) problemDetails = &problem } else { err = openapi.ReportError("%s: server no response", amfUri) } + + defer func() { + if err = httpResp.Body.Close(); err != nil { + logger.Consumerlog.Errorf("error closing response body: %v", err) + } + }() + return problemDetails, err } diff --git a/consumer/nf_management.go b/consumer/nf_management.go index 29f237c..107a8dd 100644 --- a/consumer/nf_management.go +++ b/consumer/nf_management.go @@ -51,7 +51,7 @@ func BuildNFInstance(context *pcfContext.PCFContext) (profile models.NfProfile, // }, // }, } - return + return profile, err } var SendRegisterNFInstance = func(nrfUri, nfInstanceId string, profile models.NfProfile) ( diff --git a/factory/config.go b/factory/config.go index fb0de27..ba26881 100644 --- a/factory/config.go +++ b/factory/config.go @@ -23,6 +23,7 @@ type Config struct { Info *Info `yaml:"info"` Configuration *Configuration `yaml:"configuration"` Logger *logger.Logger `yaml:"logger"` + CfgLocation string } type Info struct { diff --git a/pcf.go b/pcf.go index 9ce10d4..16d53b4 100644 --- a/pcf.go +++ b/pcf.go @@ -31,7 +31,8 @@ func main() { app := cli.NewApp() app.Name = "pcf" logger.AppLog.Infoln(app.Name) - app.Usage = "-free5gccfg common configuration file -pcfcfg pcf configuration file" + app.Usage = "Policy Control Function" + app.UsageText = "pcf -cfg " app.Action = action app.Flags = PCF.GetCliCmd() diff --git a/producer/policyauthorization.go b/producer/policyauthorization.go index e026891..ca6e80c 100644 --- a/producer/policyauthorization.go +++ b/producer/policyauthorization.go @@ -1488,7 +1488,7 @@ func updateQosInMedSubComp(qosData *models.QosData, comp *models.MediaComponent, if comp.FStatus == models.FlowStatus_REMOVED { updatedQosData.MaxbrDl = "" updatedQosData.MaxbrUl = "" - return + return updatedQosData, false, false } maxBwUl := 0.0 maxBwDl := 0.0 diff --git a/service/init.go b/service/init.go index 09ad37d..381d2b9 100644 --- a/service/init.go +++ b/service/init.go @@ -14,6 +14,7 @@ import ( "os" "os/exec" "os/signal" + "path/filepath" "strconv" "strings" "sync" @@ -46,7 +47,6 @@ import ( "github.com/omec-project/util/http2_util" "github.com/omec-project/util/idgenerator" utilLogger "github.com/omec-project/util/logger" - "github.com/omec-project/util/path_util" "github.com/urfave/cli" "go.uber.org/zap" "go.uber.org/zap/zapcore" @@ -57,7 +57,7 @@ type PCF struct{} type ( // Config information. Config struct { - pcfcfg string + cfg string } ) @@ -75,12 +75,9 @@ var config Config var pcfCLi = []cli.Flag{ cli.StringFlag{ - Name: "free5gccfg", - Usage: "common config file", - }, - cli.StringFlag{ - Name: "pcfcfg", - Usage: "config file", + Name: "cfg", + Usage: "pcf config file", + Required: true, }, } @@ -90,17 +87,17 @@ func (*PCF) GetCliCmd() (flags []cli.Flag) { func (pcf *PCF) Initialize(c *cli.Context) error { config = Config{ - pcfcfg: c.String("pcfcfg"), + cfg: c.String("cfg"), } - if config.pcfcfg != "" { - if err := factory.InitConfigFactory(config.pcfcfg); err != nil { - return err - } - } else { - DefaultPcfConfigPath := path_util.Free5gcPath("free5gc/config/pcfcfg.yaml") - if err := factory.InitConfigFactory(DefaultPcfConfigPath); err != nil { - return err - } + + absPath, err := filepath.Abs(config.cfg) + if err != nil { + logger.CfgLog.Errorln(err) + return err + } + + if err := factory.InitConfigFactory(absPath); err != nil { + return err } pcf.setLogLevel() @@ -108,6 +105,9 @@ func (pcf *PCF) Initialize(c *cli.Context) error { if err := factory.CheckConfigVersion(); err != nil { return err } + + factory.PcfConfig.CfgLocation = absPath + if os.Getenv("MANAGED_BY_CONFIG_POD") == "true" { logger.InitLog.Infoln("MANAGED_BY_CONFIG_POD is true") go manageGrpcClient(factory.PcfConfig.Configuration.WebuiUri, pcf) @@ -274,7 +274,8 @@ func (pcf *PCF) Start() { os.Exit(0) }() - server, err := http2_util.NewServer(addr, util.PCF_LOG_PATH, router) + sslLog := filepath.Dir(factory.PcfConfig.CfgLocation) + "/sslkey.log" + server, err := http2_util.NewServer(addr, sslLog, router) if server == nil { logger.InitLog.Errorf("initialize HTTP server failed: %+v", err) return @@ -297,10 +298,10 @@ func (pcf *PCF) Start() { } func (pcf *PCF) Exec(c *cli.Context) error { - logger.InitLog.Debugln("args:", c.String("pcfcfg")) + logger.InitLog.Debugln("args:", c.String("cfg")) args := pcf.FilterCli(c) logger.InitLog.Debugln("filter:", args) - command := exec.Command("./pcf", args...) + command := exec.Command("pcf", args...) stdout, err := command.StdoutPipe() if err != nil { @@ -358,7 +359,7 @@ func (pcf *PCF) StartKeepAliveTimer(nfProfile models.NfProfile) { func (pcf *PCF) StopKeepAliveTimer() { if KeepAliveTimer != nil { - logger.InitLog.Infof("stopped KeepAlive Timer") + logger.InitLog.Infof("stopped KeepAlive timer") KeepAliveTimer.Stop() KeepAliveTimer = nil } @@ -545,7 +546,7 @@ func getSessionRule(devGroup *protos.DeviceGroup) (sessionRule *models.SessionRu func getPccRules(slice *protos.NetworkSlice, sessionRule *models.SessionRule) (pccPolicy context.PccPolicy) { if slice.AppFilters == nil || slice.AppFilters.PccRuleBase == nil { logger.GrpcLog.Warnf("PccRules not exist in slice: %v", slice.Name) - return + return pccPolicy } pccPolicy.IdGenerator = idgenerator.NewGenerator(1, math.MaxInt64) for _, pccrule := range slice.AppFilters.PccRuleBase { @@ -656,7 +657,7 @@ func getPccRules(slice *protos.NetworkSlice, sessionRule *models.SessionRule) (p pccPolicy.PccRules[pccrule.RuleId] = &rule } - return + return pccPolicy } func findQosData(qosdecs map[string]*models.QosData, qos models.QosData) (bool, *models.QosData) { @@ -767,13 +768,13 @@ func (pcf *PCF) UpdatePcfSubscriberPolicyData(slice *protos.NetworkSlice) { policyData.CtxLog.Infof("slice: %v deleted from SubscriberPolicyData", sliceid) delete(policyData.PccPolicy, sliceid) if len(policyData.PccPolicy) == 0 { - policyData.CtxLog.Infof("Subscriber Deleted from PcfSubscriberPolicyData map") + policyData.CtxLog.Infoln("subscriber deleted from PcfSubscriberPolicyData map") delete(self.PcfSubscriberPolicyData, imsi) } } case protos.OpType_SLICE_DELETE: - logger.GrpcLog.Infoln("received Slice with OperationType: Delete from ConfigPod") + logger.GrpcLog.Infoln("received Slice with OperationType: delete from ConfigPod") for _, imsi := range slice.DeletedImsis { policyData, ok := self.PcfSubscriberPolicyData[imsi] if !ok { @@ -788,7 +789,7 @@ func (pcf *PCF) UpdatePcfSubscriberPolicyData(slice *protos.NetworkSlice) { policyData.CtxLog.Infof("slice: %v deleted from SubscriberPolicyData", sliceid) delete(policyData.PccPolicy, sliceid) if len(policyData.PccPolicy) == 0 { - policyData.CtxLog.Infof("Subscriber Deleted from PcfSubscriberPolicyData map") + policyData.CtxLog.Infoln("subscriber deleted from PcfSubscriberPolicyData map") delete(self.PcfSubscriberPolicyData, imsi) } } @@ -836,7 +837,7 @@ func (pcf *PCF) UpdateDnnList(ns *protos.NetworkSlice) { } } } - logger.GrpcLog.Infof("DnnList Present in PCF: %v", pcfContext.DnnList) + logger.GrpcLog.Infof("DnnList present in PCF: %v", pcfContext.DnnList) } func (pcf *PCF) UpdatePlmnList(ns *protos.NetworkSlice) { @@ -874,7 +875,7 @@ func (pcf *PCF) UpdatePlmnList(ns *protos.NetworkSlice) { pcfContext.PlmnList = append(pcfContext.PlmnList, plmn) } } - logger.GrpcLog.Infof("PlmnList Present in PCF: %v", pcfContext.PlmnList) + logger.GrpcLog.Infof("PlmnList present in PCF: %v", pcfContext.PlmnList) } func (pcf *PCF) UpdateConfig(commChannel chan *protos.NetworkSliceResponse) bool { @@ -883,7 +884,7 @@ func (pcf *PCF) UpdateConfig(commChannel chan *protos.NetworkSliceResponse) bool for rsp := range commChannel { logger.GrpcLog.Infoln("received UpdateConfig in the pcf app:", rsp) for _, ns := range rsp.NetworkSlice { - logger.GrpcLog.Infoln("Network Slice Name:", ns.Name) + logger.GrpcLog.Infoln("network slice name:", ns.Name) // Update Qos Info // Update/Create/Delete PcfSubscriberPolicyData @@ -893,7 +894,7 @@ func (pcf *PCF) UpdateConfig(commChannel chan *protos.NetworkSliceResponse) bool if ns.Site != nil { site := ns.Site - logger.GrpcLog.Infof("Network Slice [%v] has site name: %v", ns.Nssai.Sst+ns.Nssai.Sd, site.SiteName) + logger.GrpcLog.Infof("network slice [%v] has site name: %v", ns.Nssai.Sst+ns.Nssai.Sd, site.SiteName) if site.Plmn != nil { pcf.UpdatePlmnList(ns) } else { diff --git a/util/init_context.go b/util/init_context.go index b782cfe..f0645f6 100644 --- a/util/init_context.go +++ b/util/init_context.go @@ -33,8 +33,6 @@ func InitpcfContext(context *context.PCFContext) { context.UriScheme = "" context.RegisterIPv4 = factory.PCF_DEFAULT_IPV4 // default localhost context.SBIPort = factory.PCF_DEFAULT_PORT_INT // default port - context.Key = PCF_KEY_PATH // default key path - context.PEM = PCF_PEM_PATH // default PEM path if sbi != nil { if sbi.Scheme != "" { context.UriScheme = models.UriScheme(sbi.Scheme) @@ -61,7 +59,7 @@ func InitpcfContext(context *context.PCFContext) { context.BindingIPv4 = os.Getenv(sbi.BindingIPv4) if context.BindingIPv4 != "" { - logger.UtilLog.Infoln("parsing ServerIPv4 address from ENV Variable") + logger.UtilLog.Infoln("parsing ServerIPv4 address from ENV variable") } else { context.BindingIPv4 = sbi.BindingIPv4 if context.BindingIPv4 == "" { diff --git a/util/pcf_util.go b/util/pcf_util.go index 8329e83..0103df6 100644 --- a/util/pcf_util.go +++ b/util/pcf_util.go @@ -21,17 +21,12 @@ import ( "github.com/omec-project/openapi/models" "github.com/omec-project/pcf/context" "github.com/omec-project/pcf/logger" - "github.com/omec-project/util/path_util" ) const TimeFormat = time.RFC3339 // Path of HTTP2 key and log file var ( - PCF_LOG_PATH = path_util.Free5gcPath("free5gc/pcfsslkey.log") - PCF_PEM_PATH = path_util.Free5gcPath("free5gc/support/TLS/pcf.pem") - PCF_KEY_PATH = path_util.Free5gcPath("free5gc/support/TLS/pcf.key") - PCF_CONFIG_PATH = path_util.Free5gcPath("free5gc/config/pcfcfg.yaml") PCF_BASIC_PATH = "https://localhost:29507" ERROR_REQUEST_PARAMETERS = "ERROR_REQUEST_PARAMETERS" USER_UNKNOWN = "USER_UNKNOWN" From faa2b6eff16fa74c9e962b22cf16a853fbffc0ed Mon Sep 17 00:00:00 2001 From: "Arrobo, Gabriel" Date: Fri, 1 Nov 2024 10:04:41 -0700 Subject: [PATCH 2/2] Change log from `error` to `fatal` because the NF cannot start without arguments Signed-off-by: Arrobo, Gabriel --- pcf.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pcf.go b/pcf.go index 16d53b4..443e4ed 100644 --- a/pcf.go +++ b/pcf.go @@ -37,7 +37,7 @@ func main() { app.Flags = PCF.GetCliCmd() if err := app.Run(os.Args); err != nil { - logger.AppLog.Errorf("PCF run error: %v", err) + logger.AppLog.Fatalf("PCF run error: %v", err) } }