add implementation for new ips module

This commit is contained in:
ionutboangiu
2025-05-29 11:41:34 +03:00
committed by Dan Christian Bogos
parent 1b4324157d
commit eed6b8a51a
45 changed files with 2935 additions and 36 deletions

View File

@@ -402,6 +402,8 @@ func NewAttrReloadCacheWithOpts() *AttrReloadCacheWithAPIOpts {
return &AttrReloadCacheWithAPIOpts{
ResourceProfileIDs: []string{MetaAny},
ResourceIDs: []string{MetaAny},
IPProfileIDs: []string{MetaAny},
IPIDs: []string{MetaAny},
StatsQueueIDs: []string{MetaAny},
StatsQueueProfileIDs: []string{MetaAny},
ThresholdIDs: []string{MetaAny},
@@ -420,6 +422,7 @@ func NewAttrReloadCacheWithOpts() *AttrReloadCacheWithAPIOpts {
AttributeFilterIndexIDs: []string{MetaAny},
ResourceFilterIndexIDs: []string{MetaAny},
IPFilterIndexIDs: []string{MetaAny},
StatFilterIndexIDs: []string{MetaAny},
ThresholdFilterIndexIDs: []string{MetaAny},
RouteFilterIndexIDs: []string{MetaAny},
@@ -439,6 +442,8 @@ func NewAttrReloadCacheWithOptsFromMap(arg map[string][]string, tnt string, opts
ResourceProfileIDs: arg[CacheResourceProfiles],
ResourceIDs: arg[CacheResources],
IPProfileIDs: arg[CacheIPProfiles],
IPIDs: arg[CacheIPs],
StatsQueueProfileIDs: arg[CacheStatQueueProfiles],
StatsQueueIDs: arg[CacheStatQueues],
ThresholdProfileIDs: arg[CacheThresholdProfiles],
@@ -453,6 +458,7 @@ func NewAttrReloadCacheWithOptsFromMap(arg map[string][]string, tnt string, opts
ActionProfileIDs: arg[CacheActionProfiles],
AccountIDs: arg[CacheAccounts],
ResourceFilterIndexIDs: arg[CacheResourceFilterIndexes],
IPFilterIndexIDs: arg[CacheIPFilterIndexes],
StatFilterIndexIDs: arg[CacheStatFilterIndexes],
ThresholdFilterIndexIDs: arg[CacheThresholdFilterIndexes],
RouteFilterIndexIDs: arg[CacheRouteFilterIndexes],
@@ -474,6 +480,8 @@ type AttrReloadCacheWithAPIOpts struct {
ResourceProfileIDs []string `json:",omitempty"`
ResourceIDs []string `json:",omitempty"`
IPProfileIDs []string `json:",omitempty"`
IPIDs []string `json:",omitempty"`
StatsQueueIDs []string `json:",omitempty"`
StatsQueueProfileIDs []string `json:",omitempty"`
ThresholdIDs []string `json:",omitempty"`
@@ -492,6 +500,7 @@ type AttrReloadCacheWithAPIOpts struct {
AttributeFilterIndexIDs []string `json:",omitempty"`
ResourceFilterIndexIDs []string `json:",omitempty"`
IPFilterIndexIDs []string `json:",omitempty"`
StatFilterIndexIDs []string `json:",omitempty"`
ThresholdFilterIndexIDs []string `json:",omitempty"`
RouteFilterIndexIDs []string `json:",omitempty"`
@@ -507,6 +516,8 @@ func (a *AttrReloadCacheWithAPIOpts) Map() map[string][]string {
return map[string][]string{
CacheResourceProfiles: a.ResourceProfileIDs,
CacheResources: a.ResourceIDs,
CacheIPProfiles: a.IPProfileIDs,
CacheIPs: a.IPIDs,
CacheStatQueueProfiles: a.StatsQueueProfileIDs,
CacheStatQueues: a.StatsQueueIDs,
CacheThresholdProfiles: a.ThresholdProfileIDs,
@@ -523,6 +534,7 @@ func (a *AttrReloadCacheWithAPIOpts) Map() map[string][]string {
CacheActionProfiles: a.ActionProfileIDs,
CacheAccounts: a.AccountIDs,
CacheResourceFilterIndexes: a.ResourceFilterIndexIDs,
CacheIPFilterIndexes: a.IPFilterIndexIDs,
CacheStatFilterIndexes: a.StatFilterIndexIDs,
CacheThresholdFilterIndexes: a.ThresholdFilterIndexIDs,
CacheRouteFilterIndexes: a.RouteFilterIndexIDs,

View File

@@ -114,6 +114,8 @@ func TestNewAttrReloadCacheWithOpts(t *testing.T) {
newAttrReloadCache := &AttrReloadCacheWithAPIOpts{
ResourceProfileIDs: []string{MetaAny},
ResourceIDs: []string{MetaAny},
IPProfileIDs: []string{MetaAny},
IPIDs: []string{MetaAny},
StatsQueueIDs: []string{MetaAny},
StatsQueueProfileIDs: []string{MetaAny},
ThresholdIDs: []string{MetaAny},
@@ -127,6 +129,7 @@ func TestNewAttrReloadCacheWithOpts(t *testing.T) {
RateProfileIDs: []string{MetaAny},
AttributeFilterIndexIDs: []string{MetaAny},
ResourceFilterIndexIDs: []string{MetaAny},
IPFilterIndexIDs: []string{MetaAny},
StatFilterIndexIDs: []string{MetaAny},
ThresholdFilterIndexIDs: []string{MetaAny},
RouteFilterIndexIDs: []string{MetaAny},

View File

@@ -37,14 +37,16 @@ var (
CacheCapsEvents, CacheReplicationHosts})
DataDBPartitions = NewStringSet([]string{
CacheResourceProfiles, CacheResources, CacheEventResources, CacheStatQueueProfiles, CacheStatQueues,
CacheThresholdProfiles, CacheThresholds, CacheFilters, CacheRouteProfiles, CacheAttributeProfiles, CacheTrendProfiles,
CacheChargerProfiles, CacheActionProfiles, CacheRankingProfiles, CacheRankings, CacheTrends,
CacheResourceFilterIndexes, CacheStatFilterIndexes, CacheThresholdFilterIndexes, CacheRouteFilterIndexes,
CacheAttributeFilterIndexes, CacheChargerFilterIndexes, CacheLoadIDs,
CacheRateProfiles, CacheRateProfilesFilterIndexes, CacheRateFilterIndexes,
CacheActionProfilesFilterIndexes, CacheAccountsFilterIndexes, CacheReverseFilterIndexes,
CacheAccounts})
CacheResourceProfiles, CacheResources, CacheEventResources, CacheIPProfiles, CacheIPs,
CacheEventIPs, CacheStatQueueProfiles, CacheStatQueues, CacheThresholdProfiles,
CacheThresholds, CacheFilters, CacheRouteProfiles, CacheAttributeProfiles,
CacheTrendProfiles, CacheChargerProfiles, CacheActionProfiles, CacheRankingProfiles,
CacheRankings, CacheTrends, CacheResourceFilterIndexes, CacheIPFilterIndexes, CacheStatFilterIndexes,
CacheThresholdFilterIndexes, CacheRouteFilterIndexes, CacheAttributeFilterIndexes,
CacheChargerFilterIndexes, CacheLoadIDs, CacheRateProfiles, CacheRateProfilesFilterIndexes,
CacheRateFilterIndexes, CacheActionProfilesFilterIndexes, CacheAccountsFilterIndexes,
CacheReverseFilterIndexes, CacheAccounts,
})
// CachePartitions enables creation of cache partitions
CachePartitions = JoinStringSet(extraDBPartition, DataDBPartitions)
@@ -52,6 +54,8 @@ var (
CacheInstanceToPrefix = map[string]string{
CacheResourceProfiles: ResourceProfilesPrefix,
CacheResources: ResourcesPrefix,
CacheIPProfiles: IPProfilesPrefix,
CacheIPs: IPsPrefix,
CacheStatQueueProfiles: StatQueueProfilePrefix,
CacheStatQueues: StatQueuePrefix,
CacheTrendProfiles: TrendProfilePrefix,
@@ -68,6 +72,7 @@ var (
CacheActionProfiles: ActionProfilePrefix,
CacheAccounts: AccountPrefix,
CacheResourceFilterIndexes: ResourceFilterIndexes,
CacheIPFilterIndexes: IPFilterIndexes,
CacheStatFilterIndexes: StatFilterIndexes,
CacheThresholdFilterIndexes: ThresholdFilterIndexes,
CacheRouteFilterIndexes: RouteFilterIndexes,
@@ -86,6 +91,7 @@ var (
CacheIndexesToPrefix = map[string]string{ // used by match index to get all the ids when index selects is disabled and for compute indexes
CacheThresholdFilterIndexes: ThresholdProfilePrefix,
CacheResourceFilterIndexes: ResourceProfilesPrefix,
CacheIPFilterIndexes: IPProfilesPrefix,
CacheStatFilterIndexes: StatQueueProfilePrefix,
CacheRouteFilterIndexes: RouteProfilePrefix,
CacheAttributeFilterIndexes: AttributeProfilePrefix,
@@ -99,6 +105,7 @@ var (
CacheInstanceToCacheIndex = map[string]string{
CacheThresholdProfiles: CacheThresholdFilterIndexes,
CacheResourceProfiles: CacheResourceFilterIndexes,
CacheIPProfiles: CacheIPFilterIndexes,
CacheStatQueueProfiles: CacheStatFilterIndexes,
CacheRouteProfiles: CacheRouteFilterIndexes,
CacheAttributeProfiles: CacheAttributeFilterIndexes,
@@ -244,6 +251,8 @@ const (
ConfigPrefix = "cfg_"
ResourcesPrefix = "res_"
ResourceProfilesPrefix = "rsp_"
IPsPrefix = "ips_"
IPProfilesPrefix = "ipp_"
ThresholdPrefix = "thd_"
FilterPrefix = "ftr_"
CDRsStatsPrefix = "cst_"
@@ -407,6 +416,7 @@ const (
RatingProfiles = "RatingProfiles"
AccountActions = "AccountActions"
ResourcesStr = "Resources"
IPsStr = "IPs"
Stats = "Stats"
Rankings = "Rankings"
Trends = "Trends"
@@ -455,6 +465,7 @@ const (
AccountID = "AccountID"
AccountIDs = "AccountIDs"
ResourceID = "ResourceID"
IPID = "IPID"
TotalUsage = "TotalUsage"
StatID = "StatID"
BalanceType = "BalanceType"
@@ -485,6 +496,7 @@ const (
SessionSCosts = "SessionSCosts"
RQF = "RQF"
ResourceStr = "Resource"
IPStr = "IP"
User = "User"
Subscribers = "Subscribers"
//Destinations = "Destinations"
@@ -501,6 +513,8 @@ const (
Limit = "Limit"
UsageTTL = "UsageTTL"
AllocationMessage = "AllocationMessage"
AddressPool = "AddressPool"
Allocation = "Allocation"
Stored = "Stored"
RatingSubject = "RatingSubject"
Categories = "Categories"
@@ -664,6 +678,7 @@ const (
VersionName = "Version"
MetaTenant = "*tenant"
ResourceUsageStr = "ResourceUsage"
IPUsageStr = "IPUsage"
MetaDuration = "*duration"
MetaLibPhoneNumber = "*libphonenumber"
MetaTimeString = "*time_string"
@@ -975,6 +990,7 @@ const (
MetaAccounts = "*accounts"
MetaActions = "*actions"
MetaResourceProfile = "*resource_profiles"
MetaIPProfiles = "*ip_profiles"
MetaStatQueueProfiles = "*statqueue_profiles"
MetaStatQueues = "*statqueues"
MetaRankingProfiles = "*ranking_profiles"
@@ -1014,6 +1030,7 @@ const (
AttributeS = "AttributeS"
RouteS = "RouteS"
ResourceS = "ResourceS"
IPs = "IPs"
StatService = "StatS"
FilterS = "FilterS"
ThresholdS = "ThresholdS"
@@ -1041,6 +1058,7 @@ const (
ChargerSLow = "chargers"
RoutesLow = "routes"
ResourcesLow = "resources"
IPsLow = "ips"
StatServiceLow = "stats"
ThresholdsLow = "thresholds"
AnalyzerSLow = "analyzers"
@@ -1097,6 +1115,7 @@ const (
MetaTpActionProfiles = "*tp_action_profiles"
MetaTpRateProfiles = "*tp_rate_profiles"
MetaTpResources = "*tp_resources"
MetaTpIPs = "*tp_ips"
MetaTpChargers = "*tp_chargers"
MetaDurationSeconds = "*duration_seconds"
MetaDurationNanoseconds = "*duration_nanoseconds"
@@ -1117,6 +1136,8 @@ const (
TpStats = "TpStats"
TpResources = "TpResources"
TpResource = "TpResource"
TpIPs = "TpIPs"
TpIP = "TpIP"
TpChargers = "TpChargers"
TpRateProfiles = "TpRateProfiles"
TpActionProfiles = "TpActionProfiles"
@@ -1135,6 +1156,7 @@ const (
RankingSv1 = "RankingSv1"
StatSv1 = "StatSv1"
ResourceSv1 = "ResourceSv1"
IPsV1 = "IPsV1"
RouteSv1 = "RouteSv1"
AttributeSv1 = "AttributeSv1"
SessionSv1 = "SessionSv1"
@@ -1162,6 +1184,7 @@ const (
MetaGreaterThan = "*gt"
MetaGreaterOrEqual = "*gte"
MetaResources = "*resources"
MetaIPs = "*ips"
MetaEqual = "*eq"
MetaIPNet = "*ipnet"
MetaAPIBan = "*apiban"
@@ -1210,6 +1233,8 @@ const (
ReplicatorSv1GetTrend = "ReplicatorSv1.GetTrend"
ReplicatorSv1GetResource = "ReplicatorSv1.GetResource"
ReplicatorSv1GetResourceProfile = "ReplicatorSv1.GetResourceProfile"
ReplicatorSv1GetIP = "ReplicatorSv1.GetIP"
ReplicatorSv1GetIPProfile = "ReplicatorSv1.GetIPProfile"
ReplicatorSv1GetRouteProfile = "ReplicatorSv1.GetRouteProfile"
ReplicatorSv1GetAttributeProfile = "ReplicatorSv1.GetAttributeProfile"
ReplicatorSv1GetChargerProfile = "ReplicatorSv1.GetChargerProfile"
@@ -1230,6 +1255,8 @@ const (
ReplicatorSv1SetTrend
ReplicatorSv1SetResource = "ReplicatorSv1.SetResource"
ReplicatorSv1SetResourceProfile = "ReplicatorSv1.SetResourceProfile"
ReplicatorSv1SetIP = "ReplicatorSv1.SetIP"
ReplicatorSv1SetIPProfile = "ReplicatorSv1.SetIPProfile"
ReplicatorSv1SetRouteProfile = "ReplicatorSv1.SetRouteProfile"
ReplicatorSv1SetAttributeProfile = "ReplicatorSv1.SetAttributeProfile"
ReplicatorSv1SetChargerProfile = "ReplicatorSv1.SetChargerProfile"
@@ -1249,6 +1276,8 @@ const (
ReplicatorSv1RemoveTrend = "ReplicatorSv1.RemoveTrend"
ReplicatorSv1RemoveResource = "ReplicatorSv1.RemoveResource"
ReplicatorSv1RemoveResourceProfile = "ReplicatorSv1.RemoveResourceProfile"
ReplicatorSv1RemoveIP = "ReplicatorSv1.RemoveIP"
ReplicatorSv1RemoveIPProfile = "ReplicatorSv1.RemoveIPProfile"
ReplicatorSv1RemoveRouteProfile = "ReplicatorSv1.RemoveRouteProfile"
ReplicatorSv1RemoveAttributeProfile = "ReplicatorSv1.RemoveAttributeProfile"
ReplicatorSv1RemoveChargerProfile = "ReplicatorSv1.RemoveChargerProfile"
@@ -1278,6 +1307,7 @@ const (
AdminSv1GetReverseFilterHealth = "AdminSv1.GetReverseFilterHealth"
AdminSv1GetThresholdsIndexesHealth = "AdminSv1.GetThresholdsIndexesHealth"
AdminSv1GetResourcesIndexesHealth = "AdminSv1.GetResourcesIndexesHealth"
AdminSv1GetIPsIndexesHealth = "AdminSv1.GetIPsIndexesHealth"
AdminSv1GetStatsIndexesHealth = "AdminSv1.GetStatsIndexesHealth"
AdminSv1GetRoutesIndexesHealth = "AdminSv1.GetRoutesIndexesHealth"
AdminSv1GetChargersIndexesHealth = "AdminSv1.GetChargersIndexesHealth"
@@ -1584,6 +1614,24 @@ const (
AdminSv1GetResourceProfilesCount = "AdminSv1.GetResourceProfilesCount"
)
// IPs APIs
const (
IPsV1AuthorizeIPs = "IPsV1.AuthorizeIPs"
IPsV1GetIPsForEvent = "IPsV1.GetIPsForEvent"
IPsV1AllocateIPs = "IPsV1.AllocateIPs"
IPsV1ReleaseIPs = "IPsV1.ReleaseIPs"
IPsV1Ping = "IPsV1.Ping"
IPsV1GetIPWithConfig = "IPsV1.GetIPWithConfig"
IPsV1GetIP = "IPsV1.GetIP"
IPsV1GetIPs = "IPsV1.GetIPs"
AdminSv1SetIPProfile = "AdminSv1.SetIPProfile"
AdminSv1GetIPProfiles = "AdminSv1.GetIPProfiles"
AdminSv1RemoveIPProfile = "AdminSv1.RemoveIPProfile"
AdminSv1GetIPProfile = "AdminSv1.GetIPProfile"
AdminSv1GetIPProfileIDs = "AdminSv1.GetIPProfileIDs"
AdminSv1GetIPProfilesCount = "AdminSv1.GetIPProfilesCount"
)
// SessionS APIs
const (
SessionSv1AuthorizeEvent = "SessionSv1.AuthorizeEvent"
@@ -1762,6 +1810,7 @@ const (
// CSV file name
const (
ResourcesCsv = "Resources.csv"
IPsCsv = "IPs.csv"
StatsCsv = "Stats.csv"
RankingsCsv = "Rankings.csv"
TrendsCsv = "Trends.csv"
@@ -1778,6 +1827,7 @@ const (
// Table Name
const (
TBLTPResources = "tp_resources"
TBLTPIPs = "tp_ips"
TBLTPStats = "tp_stats"
TBLTPRankings = "tp_rankings"
TBLTPTrends = "tp_trends"
@@ -1803,6 +1853,9 @@ const (
CacheResources = "*resources"
CacheResourceProfiles = "*resource_profiles"
CacheEventResources = "*event_resources"
CacheIPs = "*ips"
CacheIPProfiles = "*ip_profiles"
CacheEventIPs = "*event_ips"
CacheStatQueueProfiles = "*statqueue_profiles"
CacheStatQueues = "*statqueues"
CacheRankingProfiles = "*ranking_profiles"
@@ -1819,6 +1872,7 @@ const (
CacheActionProfiles = "*action_profiles"
CacheAccounts = "*accounts"
CacheResourceFilterIndexes = "*resource_filter_indexes"
CacheIPFilterIndexes = "*ip_filter_indexes"
CacheStatFilterIndexes = "*stat_filter_indexes"
CacheThresholdFilterIndexes = "*threshold_filter_indexes"
CacheRouteFilterIndexes = "*route_filter_indexes"
@@ -1850,6 +1904,7 @@ const (
// Prefix for indexing
const (
ResourceFilterIndexes = "rfi_"
IPFilterIndexes = "ifi_"
StatFilterIndexes = "sfi_"
ThresholdFilterIndexes = "tfi_"
AttributeFilterIndexes = "afi_"
@@ -2535,6 +2590,11 @@ const (
OptsResourcesUsageID = "*rsUsageID"
OptsResourcesUsageTTL = "*rsUsageTTL"
// IPs
OptsIPsUnits = "*ipUnits"
OptsIPsUsageID = "*ipUsageID"
OptsIPsTTL = "*ipTTL"
// Routes
OptsRoutesProfilesCount = "*rouProfilesCount"
OptsRoutesLimit = "*rouLimit"

267
utils/ips.go Normal file
View File

@@ -0,0 +1,267 @@
/*
Real-time Online/Offline Charging System (OCS) for Telecom & ISP environments
Copyright (C) ITsysCOM GmbH
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>
*/
package utils
import (
"slices"
"time"
)
// IPProfile defines the configuration of the IP.
type IPProfile struct {
Tenant string
ID string
FilterIDs []string
TTL time.Duration
Type string
AddressPool string
Allocation string
Stored bool
Weights DynamicWeights
}
// Clone creates a deep copy of IPProfile for thread-safe use.
func (ip *IPProfile) Clone() *IPProfile {
if ip == nil {
return nil
}
return &IPProfile{
Tenant: ip.Tenant,
ID: ip.ID,
FilterIDs: slices.Clone(ip.FilterIDs),
TTL: ip.TTL,
Type: ip.Type,
AddressPool: ip.AddressPool,
Allocation: ip.Allocation,
Stored: ip.Stored,
Weights: ip.Weights.Clone(),
}
}
// CacheClone returns a clone of IPProfile used by ltcache CacheCloner
func (ip *IPProfile) CacheClone() any {
return ip.Clone()
}
// IPProfileWithAPIOpts wraps IPProfile with APIOpts.
type IPProfileWithAPIOpts struct {
*IPProfile
APIOpts map[string]any
}
// TenantID returns the concatenated tenant and ID.
func (ip *IPProfile) TenantID() string {
return ConcatenatedKey(ip.Tenant, ip.ID)
}
// IPUsage represents an usage counted.
type IPUsage struct {
Tenant string
ID string
ExpiryTime time.Time
Units float64
}
// TenantID returns the concatenated key between tenant and ID.
func (u *IPUsage) TenantID() string {
return ConcatenatedKey(u.Tenant, u.ID)
}
// isActive checks ExpiryTime at some time
func (u *IPUsage) IsActive(atTime time.Time) bool {
return u.ExpiryTime.IsZero() || u.ExpiryTime.Sub(atTime) > 0
}
// Clone duplicates ru
func (u *IPUsage) Clone() *IPUsage {
if u == nil {
return nil
}
clone := *u
return &clone
}
// IP represents ...
type IP struct {
Tenant string
ID string
Usages map[string]*IPUsage
TTLIdx []string
}
// Clone clones *IP (lkID excluded)
func (ip *IP) Clone() *IP {
if ip == nil {
return nil
}
clone := &IP{
Tenant: ip.Tenant,
ID: ip.ID,
TTLIdx: slices.Clone(ip.TTLIdx),
}
if ip.Usages != nil {
clone.Usages = make(map[string]*IPUsage, len(ip.Usages))
for key, usage := range ip.Usages {
clone.Usages[key] = usage.Clone()
}
}
return clone
}
// CacheClone returns a clone of IP used by ltcache CacheCloner
func (ip *IP) CacheClone() any {
return ip.Clone()
}
// IPWithAPIOpts wraps IP with APIOpts.
type IPWithAPIOpts struct {
*IP
APIOpts map[string]any
}
// TenantID returns the unique ID in a multi-tenant environment
func (ip *IP) TenantID() string {
return ConcatenatedKey(ip.Tenant, ip.ID)
}
// TotalUsage returns the sum of all usage units
// Exported to be used in FilterS
func (ip *IP) TotalUsage() float64 {
var tu float64
for _, ru := range ip.Usages {
tu += ru.Units
}
return tu
}
func (ip *IPProfile) Set(path []string, val any, _ bool) error {
if len(path) != 1 {
return ErrWrongPath
}
var err error
switch path[0] {
default:
return ErrWrongPath
case Tenant:
ip.Tenant = IfaceAsString(val)
case ID:
ip.ID = IfaceAsString(val)
case FilterIDs:
var valA []string
valA, err = IfaceAsStringSlice(val)
ip.FilterIDs = append(ip.FilterIDs, valA...)
case TTL:
ip.TTL, err = IfaceAsDuration(val)
case Type:
ip.Type = IfaceAsString(val)
case AddressPool:
ip.AddressPool = IfaceAsString(val)
case Allocation:
ip.Allocation = IfaceAsString(val)
case Stored:
ip.Stored, err = IfaceAsBool(val)
case Weights:
if val != "" {
ip.Weights, err = NewDynamicWeightsFromString(IfaceAsString(val), InfieldSep, ANDSep)
}
}
return err
}
func (ip *IPProfile) Merge(v2 any) {
vi := v2.(*IPProfile)
if len(vi.Tenant) != 0 {
ip.Tenant = vi.Tenant
}
if len(vi.ID) != 0 {
ip.ID = vi.ID
}
ip.FilterIDs = append(ip.FilterIDs, vi.FilterIDs...)
if len(vi.Allocation) != 0 {
ip.Allocation = vi.Allocation
}
if vi.TTL != 0 {
ip.TTL = vi.TTL
}
if vi.Type != "" {
ip.Type = vi.Type
}
if vi.AddressPool != "" {
ip.AddressPool = vi.AddressPool
}
if vi.Stored {
ip.Stored = vi.Stored
}
ip.Weights = append(ip.Weights, vi.Weights...)
}
func (ip *IPProfile) String() string { return ToJSON(ip) }
func (ip *IPProfile) FieldAsString(fldPath []string) (string, error) {
val, err := ip.FieldAsInterface(fldPath)
if err != nil {
return "", err
}
return IfaceAsString(val), nil
}
func (ip *IPProfile) FieldAsInterface(fldPath []string) (any, error) {
if len(fldPath) != 1 {
return nil, ErrNotFound
}
switch fldPath[0] {
default:
fld, idx := GetPathIndex(fldPath[0])
if idx != nil {
switch fld {
case FilterIDs:
if *idx < len(ip.FilterIDs) {
return ip.FilterIDs[*idx], nil
}
}
}
return nil, ErrNotFound
case Tenant:
return ip.Tenant, nil
case ID:
return ip.ID, nil
case FilterIDs:
return ip.FilterIDs, nil
case TTL:
return ip.TTL, nil
case Type:
return ip.Type, nil
case AddressPool:
return ip.AddressPool, nil
case Allocation:
return ip.Allocation, nil
case Stored:
return ip.Stored, nil
case Weights:
return ip.Weights, nil
}
}
// IPProfileLockKey returns the ID used to lock a resourceProfile with guardian
func IPProfileLockKey(tnt, id string) string {
return ConcatenatedKey(CacheIPProfiles, tnt, id)
}
// IPLockKey returns the ID used to lock a resource with guardian
func IPLockKey(tnt, id string) string {
return ConcatenatedKey(CacheIPs, tnt, id)
}