diff --git a/internal/context/context.go b/internal/context/context.go index fde7c88..7237df5 100644 --- a/internal/context/context.go +++ b/internal/context/context.go @@ -1,8 +1,12 @@ package context import ( + "context" "crypto/rsa" "crypto/x509" + "fmt" + "net" + "net/netip" "os" "path/filepath" "strconv" @@ -21,6 +25,10 @@ import ( type NRFContext struct { NrfNfProfile models.NrfNfManagementNfProfile Nrf_NfInstanceID string + UriScheme models.UriScheme + BindingIP netip.Addr + RegisterIP netip.Addr + SBIPort int RootPrivKey *rsa.PrivateKey RootCert *x509.Certificate NrfPrivKey *rsa.PrivateKey @@ -47,12 +55,27 @@ func InitNrfContext() error { logger.InitLog.Infof("nrfconfig Info: Version[%s] Description[%s]", config.Info.Version, config.Info.Description) configuration := config.Configuration + sbi := configuration.Sbi nrfContext.NrfNfProfile.NfInstanceId = uuid.New().String() nrfContext.NrfNfProfile.NfType = models.NrfNfManagementNfType_NRF nrfContext.NrfNfProfile.NfStatus = models.NrfNfManagementNfStatus_REGISTERED nrfContext.NfRegistNum = 0 + nrfContext.SBIPort = sbi.Port + nrfContext.UriScheme = models.UriScheme(sbi.Scheme) + + if bindingIP := os.Getenv(sbi.BindingIP); bindingIP != "" { + logger.UtilLog.Info("Parsing BindingIP address from ENV Variable.") + sbi.BindingIP = bindingIP + } + if registerIP := os.Getenv(sbi.RegisterIP); registerIP != "" { + logger.UtilLog.Info("Parsing RegisterIP address from ENV Variable.") + sbi.RegisterIP = registerIP + } + nrfContext.BindingIP = resolveIP(sbi.BindingIP) + nrfContext.RegisterIP = resolveIP(sbi.RegisterIP) + serviceNameList := configuration.ServiceNameList if config.GetOAuth() { @@ -106,12 +129,52 @@ func InitNrfContext() error { } } - NFServices := InitNFService(serviceNameList, config.Info.Version) + NFServices := nrfContext.InitNFService(serviceNameList, config.Info.Version) nrfContext.NrfNfProfile.NfServices = NFServices return nil } -func InitNFService(srvNameList []string, version string) []models.NrfNfManagementNfService { +func resolveIP(ip string) netip.Addr { + resolvedIPs, err := net.DefaultResolver.LookupNetIP(context.Background(), "ip", ip) + if err != nil { + logger.InitLog.Errorf("Lookup failed with %s: %+v", ip, err) + } + resolvedIP := resolvedIPs[0].Unmap() + if resolvedIP := resolvedIP.String(); resolvedIP != ip { + logger.UtilLog.Infof("Lookup revolved %s into %s", ip, resolvedIP) + } + return resolvedIP +} + +func (context *NRFContext) GetIPUri() string { + addr := context.RegisterIP + port := context.SBIPort + + return fmt.Sprintf("%s://%s", context.UriScheme, netip.AddrPortFrom(addr, uint16(port)).String()) +} + +func (context *NRFContext) GetIpEndPoint() []models.IpEndPoint { + if context.RegisterIP.Is6() { + return []models.IpEndPoint{ + { + Ipv6Address: context.RegisterIP.String(), + Transport: models.NrfNfManagementTransportProtocol_TCP, + Port: int32(context.SBIPort), + }, + } + } else if context.RegisterIP.Is4() { + return []models.IpEndPoint{ + { + Ipv4Address: context.RegisterIP.String(), + Transport: models.NrfNfManagementTransportProtocol_TCP, + Port: int32(context.SBIPort), + }, + } + } + return nil +} + +func (context *NRFContext) InitNFService(srvNameList []string, version string) []models.NrfNfManagementNfService { tmpVersion := strings.Split(version, ".") versionUri := "v" + tmpVersion[0] NFServices := make([]models.NrfNfManagementNfService, len(srvNameList)) @@ -126,16 +189,10 @@ func InitNFService(srvNameList []string, version string) []models.NrfNfManagemen ApiVersionInUri: versionUri, }, }, - Scheme: models.UriScheme(factory.NrfConfig.GetSbiScheme()), + Scheme: context.UriScheme, NfServiceStatus: models.NfServiceStatus_REGISTERED, - ApiPrefix: factory.NrfConfig.GetSbiUri(), - IpEndPoints: []models.IpEndPoint{ - { - Ipv4Address: factory.NrfConfig.GetSbiRegisterIP(), - Transport: models.NrfNfManagementTransportProtocol_TCP, - Port: int32(factory.NrfConfig.GetSbiPort()), - }, - }, + ApiPrefix: context.GetIPUri(), + IpEndPoints: context.GetIpEndPoint(), } } return NFServices diff --git a/internal/context/management_data.go b/internal/context/management_data.go index 7629fab..6faa947 100644 --- a/internal/context/management_data.go +++ b/internal/context/management_data.go @@ -397,7 +397,8 @@ func nnrfNFManagementOption(nf *models.NrfNfManagementNfProfile, nfprofile *mode } func GetNfInstanceURI(nfInstID string) string { - return factory.NrfConfig.GetSbiUri() + NRF_NFINST_RES_URI_PREFIX + nfInstID + url := GetSelf().GetIPUri() + return url + NRF_NFINST_RES_URI_PREFIX + nfInstID } func SetLocationHeader(nfprofile *models.NrfNfManagementNfProfile) string { diff --git a/internal/sbi/server.go b/internal/sbi/server.go index ea1ad97..b38c245 100644 --- a/internal/sbi/server.go +++ b/internal/sbi/server.go @@ -5,6 +5,7 @@ import ( "fmt" "net" "net/http" + "net/netip" "runtime/debug" "sync" "time" @@ -42,14 +43,20 @@ func NewServer(nrf ServerNrf, tlsKeyLogPath string) (*Server, error) { router: logger_util.NewGinWithLogrus(logger.GinLog), } s.router.Use(metrics.InboundMetrics()) - cfg := s.Config() - bindAddr := cfg.GetSbiBindingAddr() - logger.SBILog.Infof("Binding addr: [%s]", bindAddr) + + // cfg := s.Config() + + addr := s.Context().RegisterIP + port := uint16(s.Context().SBIPort) + + bind := netip.AddrPortFrom(addr, port).String() + + logger.SBILog.Infof("Binding addr: [%s]", bind) s.applyService() var err error - if s.httpServer, err = httpwrapper.NewHttp2Server(bindAddr, tlsKeyLogPath, s.router); err != nil { + if s.httpServer, err = httpwrapper.NewHttp2Server(bind, tlsKeyLogPath, s.router); err != nil { logger.InitLog.Errorf("Initialize HTTP server failed: %v", err) return nil, err } diff --git a/pkg/factory/config.go b/pkg/factory/config.go index 8b0eca0..042f1b8 100644 --- a/pkg/factory/config.go +++ b/pkg/factory/config.go @@ -25,7 +25,7 @@ const ( NrfDefaultRootCertPemPath = "./cert/root.pem" NrfDefaultRootPrivateKeyPath = "./cert/root.key" NrfDefaultConfigPath = "./config/nrfcfg.yaml" - NrfSbiDefaultIPv4 = "127.0.0.10" + NrfSbiDefaultIP = "127.0.0.10" NrfSbiDefaultPort = 8000 NrfSbiDefaultScheme = "https" NrfMetricsDefaultEnabled = false @@ -126,20 +126,50 @@ func (c *Configuration) validate() (bool, error) { } type Sbi struct { - Scheme string `yaml:"scheme" valid:"scheme,required"` + Scheme string `yaml:"scheme" valid:"in(http|https),optional"` RegisterIPv4 string `yaml:"registerIPv4,omitempty" valid:"host,optional"` - // IP that is serviced or registered at another NRF. - // IPv6Addr string `yaml:"ipv6Addr,omitempty"` - BindingIPv4 string `yaml:"bindingIPv4,omitempty" valid:"host,required"` // IP used to run the server in the node. - Port int `yaml:"port,omitempty" valid:"port,optional"` - Cert *Cert `yaml:"cert,omitempty" valid:"optional"` - RootCert *Cert `yaml:"rootcert,omitempty" valid:"optional"` - OAuth bool `yaml:"oauth,omitempty" valid:"optional"` + RegisterIP string `yaml:"registerIP,omitempty" valid:"host,optional"` + BindingIPv4 string `yaml:"bindingIPv4,omitempty" valid:"host,optional"` + BindingIP string `yaml:"bindingIP,omitempty" valid:"host,optional"` + Port int `yaml:"port,omitempty" valid:"port,optional"` + Cert *Cert `yaml:"cert,omitempty" valid:"optional"` + RootCert *Cert `yaml:"rootcert,omitempty" valid:"optional"` + OAuth bool `yaml:"oauth,omitempty" valid:"optional"` } func (s *Sbi) validate() (bool, error) { - result, err := govalidator.ValidateStruct(s) - return result, appendInvalid(err) + // Set a default Schme if the Configuration does not provides one + if s.Scheme == "" { + s.Scheme = NrfSbiDefaultScheme + } + + // Set BindingIP/RegisterIP from deprecated BindingIPv4/RegisterIPv4 + if s.BindingIP == "" && s.BindingIPv4 != "" { + s.BindingIP = s.BindingIPv4 + } + if s.RegisterIP == "" && s.RegisterIPv4 != "" { + s.RegisterIP = s.RegisterIPv4 + } + + // Set a default BindingIP/RegisterIP if the Configuration does not provides them + if s.BindingIP == "" && s.RegisterIP == "" { + s.BindingIP = NrfSbiDefaultIP + s.RegisterIP = NrfSbiDefaultIP + } else { + // Complete any missing BindingIP/RegisterIP from RegisterIP/BindingIP + if s.BindingIP == "" { + s.BindingIP = s.RegisterIP + } else if s.RegisterIP == "" { + s.RegisterIP = s.BindingIP + } + } + + // Set a default Port if the Configuration does not provides one + if s.Port == 0 { + s.Port = NrfSbiDefaultPort + } + + return govalidator.ValidateStruct(s) } type Metrics struct { @@ -299,50 +329,6 @@ func (c *Config) GetSbiPort() int { return NrfSbiDefaultPort } -func (c *Config) GetSbiBindingIP() string { - c.RLock() - defer c.RUnlock() - bindIP := "0.0.0.0" - if c.Configuration == nil || c.Configuration.Sbi == nil { - return bindIP - } - if c.Configuration.Sbi.BindingIPv4 != "" { - if bindIP = os.Getenv(c.Configuration.Sbi.BindingIPv4); bindIP != "" { - logger.CfgLog.Infof("Parsing ServerIPv4 [%s] from ENV Variable", bindIP) - } else { - bindIP = c.Configuration.Sbi.BindingIPv4 - } - } - return bindIP -} - -func (c *Config) GetSbiBindingAddr() string { - c.RLock() - defer c.RUnlock() - return c.GetSbiBindingIP() + ":" + strconv.Itoa(c.GetSbiPort()) -} - -func (c *Config) GetSbiRegisterIP() string { - c.RLock() - defer c.RUnlock() - if c.Configuration != nil && c.Configuration.Sbi != nil && c.Configuration.Sbi.RegisterIPv4 != "" { - return c.Configuration.Sbi.RegisterIPv4 - } - return NrfSbiDefaultIPv4 -} - -func (c *Config) GetSbiRegisterAddr() string { - c.RLock() - defer c.RUnlock() - return c.GetSbiRegisterIP() + ":" + strconv.Itoa(c.GetSbiPort()) -} - -func (c *Config) GetSbiUri() string { - c.RLock() - defer c.RUnlock() - return c.GetSbiScheme() + "://" + c.GetSbiRegisterAddr() -} - func (c *Config) GetOAuth() bool { c.RLock() defer c.RUnlock()