Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Add NRF Consumer support OAuth2 #18

Merged
merged 5 commits into from
Dec 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ require (
github.com/antihax/optional v1.0.0
github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d
github.com/cydev/zero v0.0.0-20160322155811-4a4535dd56e7
github.com/free5gc/openapi v1.0.7-0.20230802173229-2b3ded4db293
github.com/free5gc/openapi v1.0.7-0.20231216094313-e15a4ff046f6
github.com/free5gc/util v1.0.5-0.20231001095115-433858e5be94
github.com/gin-contrib/cors v1.3.1
github.com/gin-gonic/gin v1.9.1
Expand Down Expand Up @@ -57,7 +57,7 @@ require (
golang.org/x/crypto v0.14.0 // indirect
golang.org/x/net v0.17.0 // indirect
golang.org/x/oauth2 v0.0.0-20210810183815-faf39c7919d5 // indirect
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 // indirect
golang.org/x/sync v0.1.0 // indirect
golang.org/x/sys v0.13.0 // indirect
golang.org/x/text v0.13.0 // indirect
google.golang.org/appengine v1.6.6 // indirect
Expand Down
7 changes: 3 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/evanphx/json-patch v0.5.2 h1:xVCHIVMUu1wtM/VkR9jVZ45N3FhZfYMMYGorLCR8P3k=
github.com/evanphx/json-patch v0.5.2/go.mod h1:ZWS5hhDbVDyob71nXKNL0+PWn6ToqBHMikGIFbs31qQ=
github.com/free5gc/openapi v1.0.7-0.20230802173229-2b3ded4db293 h1:BSIvKCYu7646sE8J9R1L8v2R435otUik3wOFN33csfs=
github.com/free5gc/openapi v1.0.7-0.20230802173229-2b3ded4db293/go.mod h1:iw/N0E+FlX44EEx24IBi2EdZW8v+bkj3ETWPGnlK9DI=
github.com/free5gc/openapi v1.0.7-0.20231216094313-e15a4ff046f6 h1:8P/wOkTAQMgZJe9pUUNSTE5PWeAdlMrsU9kLsI+VAVE=
github.com/free5gc/openapi v1.0.7-0.20231216094313-e15a4ff046f6/go.mod h1:qv9KqEucoZSeENPRFGxfTe+33ZWYyiYFx1Rj+H0DoWA=
github.com/free5gc/util v1.0.5-0.20231001095115-433858e5be94 h1:tNylIqH/m5Kq+3KuC+jjXGl06Y6EmM8yq61ZUgNrPBY=
github.com/free5gc/util v1.0.5-0.20231001095115-433858e5be94/go.mod h1:aMszJZbCkcg5xaGgzya+55jz+OPMsJqPLq5Z3fWDFPE=
github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU=
Expand Down Expand Up @@ -330,7 +330,6 @@ golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81R
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
Expand All @@ -350,7 +349,6 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 h1:uVc8UZUe6tr40fFVnUP5Oj+veunVezqYl9z7DYw9xzw=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
Expand Down Expand Up @@ -552,6 +550,7 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
Expand Down
16 changes: 16 additions & 0 deletions internal/context/context.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package context

import (
"context"
"fmt"
"math"
"os"
Expand All @@ -12,6 +13,7 @@ import (

"github.com/free5gc/openapi"
"github.com/free5gc/openapi/models"
"github.com/free5gc/openapi/oauth"
"github.com/free5gc/pcf/internal/logger"
"github.com/free5gc/pcf/pkg/factory"
"github.com/free5gc/util/idgenerator"
Expand All @@ -31,6 +33,7 @@ type PCFContext struct {
PcfServiceUris map[models.ServiceName]string
PcfSuppFeats map[models.ServiceName]openapi.SupportedFeature
NrfUri string
NrfCertPem string
DefaultUdrURI string
Locality string
// UePool map[string]*UeContext
Expand All @@ -45,6 +48,8 @@ type PCFContext struct {

// lock
DefaultUdrURILock sync.RWMutex

OAuth2Required bool
}

type AMFStatusSubscriptionData struct {
Expand Down Expand Up @@ -86,6 +91,7 @@ func InitpcfContext(context *PCFContext) {

sbi := configuration.Sbi
context.NrfUri = configuration.NrfUri
context.NrfCertPem = configuration.NrfCertPem
context.UriScheme = ""
context.RegisterIPv4 = factory.PcfSbiDefaultIPv4 // default localhost
context.SBIPort = factory.PcfSbiDefaultPort // default port
Expand Down Expand Up @@ -426,3 +432,13 @@ func DeleteIpv6index(Ipv6index int32) {
func (c *PCFContext) NewAmfStatusSubscription(subscriptionID string, subscriptionData AMFStatusSubscriptionData) {
c.AMFStatusSubsData.Store(subscriptionID, subscriptionData)
}

func (c *PCFContext) GetTokenCtx(scope, targetNF string) (
context.Context, *models.ProblemDetails, error,
) {
if !c.OAuth2Required {
return context.TODO(), nil, nil
}
return oauth.GetTokenCtx(models.NfType_PCF,
c.NfId, c.NrfUri, scope, targetNF)
}
2 changes: 1 addition & 1 deletion internal/sbi/consumer/communication.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ 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
Expand Down
6 changes: 3 additions & 3 deletions internal/sbi/consumer/influenceDataSubscription.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ func CreateInfluenceDataSubscription(ue *pcf_context.UeContext, request models.S
ApplicationDataInfluenceDataSubsToNotifyPost(context.Background(), trafficInfluSub)
if localErr == nil {
locationHeader := httpResp.Header.Get("Location")
subscriptionID := locationHeader[strings.LastIndex(locationHeader, "/")+1:]
subscriptionID = locationHeader[strings.LastIndex(locationHeader, "/")+1:]
logger.ConsumerLog.Debugf("Influence Data Subscription ID: %s", subscriptionID)
return subscriptionID, nil, nil
} else if httpResp != nil {
Expand All @@ -38,7 +38,7 @@ func CreateInfluenceDataSubscription(ue *pcf_context.UeContext, request models.S
}()
if httpResp.Status != localErr.Error() {
err = localErr
return
return subscriptionID, problemDetails, err
}
problem := localErr.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails)
problemDetails = &problem
Expand Down Expand Up @@ -85,7 +85,7 @@ func RemoveInfluenceDataSubscription(ue *pcf_context.UeContext, subscriptionID s
}()
if httpResp.Status != localErr.Error() {
err = localErr
return
return nil, err
}
problem := localErr.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails)
problemDetails = &problem
Expand Down
9 changes: 7 additions & 2 deletions internal/sbi/consumer/nf_discovery.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
package consumer

import (
"context"
"fmt"
"net/http"

"github.com/antihax/optional"

"github.com/free5gc/openapi/Nnrf_NFDiscovery"
"github.com/free5gc/openapi/models"
pcf_context "github.com/free5gc/pcf/internal/context"
"github.com/free5gc/pcf/internal/logger"
"github.com/free5gc/pcf/internal/util"
)
Expand All @@ -22,7 +22,12 @@ func SendSearchNFInstances(
configuration.SetBasePath(nrfUri)
client := Nnrf_NFDiscovery.NewAPIClient(configuration)

result, res, err := client.NFInstancesStoreApi.SearchNFInstances(context.TODO(), targetNfType, requestNfType, &param)
ctx, _, err := pcf_context.GetSelf().GetTokenCtx("nnrf-disc", "NRF")
if err != nil {
return nil, err
}

result, res, err := client.NFInstancesStoreApi.SearchNFInstances(ctx, targetNfType, requestNfType, &param)
if err != nil {
logger.ConsumerLog.Errorf("SearchNFInstances failed: %+v", err)
}
Expand Down
30 changes: 25 additions & 5 deletions internal/sbi/consumer/nf_management.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,9 @@ func SendRegisterNFInstance(nrfUri, nfInstanceId string, profile models.NfProfil
client := Nnrf_NFManagement.NewAPIClient(configuration)

var res *http.Response
var nf models.NfProfile
for {
_, res, err = client.NFInstanceIDDocumentApi.RegisterNFInstance(context.TODO(), nfInstanceId, profile)
nf, res, err = client.NFInstanceIDDocumentApi.RegisterNFInstance(context.TODO(), nfInstanceId, profile)
if err != nil || res == nil {
// TODO : add log
fmt.Println(fmt.Errorf("PCF register to NRF Error[%v]", err.Error()))
Expand All @@ -76,6 +77,20 @@ func SendRegisterNFInstance(nrfUri, nfInstanceId string, profile models.NfProfil
resourceUri := res.Header.Get("Location")
resouceNrfUri = resourceUri[:strings.Index(resourceUri, "/nnrf-nfm/")]
retrieveNfInstanceID = resourceUri[strings.LastIndex(resourceUri, "/")+1:]

oauth2 := false
if nf.CustomInfo != nil {
v, ok := nf.CustomInfo["oauth2"].(bool)
if ok {
oauth2 = v
logger.MainLog.Infoln("OAuth2 setting receive from NRF:", oauth2)
}
}
pcf_context.GetSelf().OAuth2Required = oauth2

if oauth2 && pcf_context.GetSelf().NrfCertPem == "" {
logger.CfgLog.Error("OAuth2 enable but no nrfCertPem provided in config.")
}
break
} else {
fmt.Println("NRF return wrong status code", status)
Expand All @@ -87,6 +102,11 @@ func SendRegisterNFInstance(nrfUri, nfInstanceId string, profile models.NfProfil
func SendDeregisterNFInstance() (problemDetails *models.ProblemDetails, err error) {
logger.ConsumerLog.Infof("Send Deregister NFInstance")

ctx, pd, err := pcf_context.GetSelf().GetTokenCtx("nnrf-nfm", "NRF")
if err != nil {
return pd, err
}

pcfSelf := pcf_context.GetSelf()
// Set client and set url
configuration := Nnrf_NFManagement.NewConfiguration()
Expand All @@ -95,22 +115,22 @@ func SendDeregisterNFInstance() (problemDetails *models.ProblemDetails, err erro

var res *http.Response

res, err = client.NFInstanceIDDocumentApi.DeregisterNFInstance(context.Background(), pcfSelf.NfId)
res, err = client.NFInstanceIDDocumentApi.DeregisterNFInstance(ctx, pcfSelf.NfId)
if err == nil {
return
return nil, nil
} else if res != nil {
defer func() {
if resCloseErr := res.Body.Close(); resCloseErr != nil {
logger.ConsumerLog.Errorf("DeregisterNFInstance response cannot close: %+v", resCloseErr)
}
}()
if res.Status != err.Error() {
return
return nil, err
}
problem := err.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails)
problemDetails = &problem
} else {
err = openapi.ReportError("server no response")
}
return
return problemDetails, err
}
2 changes: 1 addition & 1 deletion internal/sbi/producer/policyauthorization.go
Original file line number Diff line number Diff line change
Expand Up @@ -1480,7 +1480,7 @@ func updateQosInMedSubComp(qosData *models.QosData, comp *models.MediaComponent,
if comp.FStatus == models.FlowStatus_REMOVED {
updatedQosData.MaxbrDl = ""
updatedQosData.MaxbrUl = ""
return
return updatedQosData, ulExist, dlExist
}
maxBwUl := 0.0
maxBwDl := 0.0
Expand Down
2 changes: 1 addition & 1 deletion internal/util/pcc_rule.go
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ func isUpPathChgEventExist(trafficInfluData *models.TrafficInfluData) bool {
trafficInfluData.DnaiChgType != ""
}

// subclause 4.2.6.2.6.2 in 3GPP TS 29.512.
// subclause 4.2.6.2.6.2 in 3GPP TS 29.512.
func setUpPathChgEvent(trafficInfluData *models.TrafficInfluData) *models.UpPathChgEvent {
return &models.UpPathChgEvent{
NotificationUri: trafficInfluData.UpPathChgNotifUri,
Expand Down
1 change: 1 addition & 0 deletions pkg/factory/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ type Configuration struct {
TimeFormat string `yaml:"timeFormat,omitempty" valid:"required"`
DefaultBdtRefId string `yaml:"defaultBdtRefId,omitempty" valid:"required, type(string)"`
NrfUri string `yaml:"nrfUri,omitempty" valid:"required, url"`
NrfCertPem string `yaml:"nrfCertPem,omitempty" valid:"optional"`
ServiceList []Service `yaml:"serviceList,omitempty" valid:"required"`
Mongodb *Mongodb `yaml:"mongodb" valid:"required"`
Locality string `yaml:"locality,omitempty" valid:"-"`
Expand Down