diff --git a/pkg/infradb/bridge.go b/pkg/infradb/bridge.go index fea9913d..5da14d8c 100644 --- a/pkg/infradb/bridge.go +++ b/pkg/infradb/bridge.go @@ -52,6 +52,7 @@ type LogicalBridgeMetadata struct{} // LogicalBridge holds Logical Bridge info type LogicalBridge struct { + Domain Name string Spec *LogicalBridgeSpec Status *LogicalBridgeStatus @@ -240,25 +241,47 @@ func (in *LogicalBridge) parseMeta(lbMeta *LogicalBridgeMetadata) { } } -// prepareObjectsForReplay prepares an object for replay by setting the unsuccessful components -// in pending state and returning a list of the components that need to be contacted for the -// replay of the particular object that called the function. -func (in *LogicalBridge) prepareObjectsForReplay(componentName string, lbSubs []*eventbus.Subscriber) []*eventbus.Subscriber { - // We assume that the list of Components that are returned - // from DB is ordered based on the priority as that was the - // way that has been stored in the DB in first place. - lbComponents := in.Status.Components - tempSubs := []*eventbus.Subscriber{} - for i, comp := range lbComponents { - if comp.Name == componentName || comp.CompStatus != common.ComponentStatusSuccess { - in.Status.Components[i] = common.Component{Name: comp.Name, CompStatus: common.ComponentStatusPending, Details: ""} - tempSubs = append(tempSubs, lbSubs[i]) - } +func (in *LogicalBridge) getStatusComponents() []common.Component { + return in.Status.Components +} + +func (in *LogicalBridge) setStatusComponents(components []common.Component) { + copy(in.Status.Components, components) +} + +func (in *LogicalBridge) isOperationalStatus(operStatus OperStatus) bool { + switch operStatus { + case OperStatusUp: + return in.Status.LBOperStatus == LogicalBridgeOperStatusUp + case OperStatusDown: + return in.Status.LBOperStatus == LogicalBridgeOperStatusDown + case OperStatusToBeDeleted: + return in.Status.LBOperStatus == LogicalBridgeOperStatusToBeDeleted + case OperStatusUnspecified: + return in.Status.LBOperStatus == LogicalBridgeOperStatusUnspecified + default: + log.Println("isOperationalStatus(): operational status has not been identified") + return false } - if in.Status.LBOperStatus == LogicalBridgeOperStatusUp { +} + +func (in *LogicalBridge) setOperationalStatus(operStatus OperStatus) { + switch operStatus { + case OperStatusUp: + in.Status.LBOperStatus = LogicalBridgeOperStatusUp + case OperStatusDown: in.Status.LBOperStatus = LogicalBridgeOperStatusDown + case OperStatusToBeDeleted: + in.Status.LBOperStatus = LogicalBridgeOperStatusToBeDeleted + case OperStatusUnspecified: + in.Status.LBOperStatus = LogicalBridgeOperStatusUnspecified + default: + log.Println("setOperationalStatus(): operational status has not been identified") } +} +// TODO: This function can probably be moved to the domain.go as the ResourceVersion +// field is common for all the child objects (VRF,LB, BP, SVI) +func (in *LogicalBridge) setNewResourceVersion() { in.ResourceVersion = generateVersion() - return tempSubs } diff --git a/pkg/infradb/domain.go b/pkg/infradb/domain.go new file mode 100644 index 00000000..ce658338 --- /dev/null +++ b/pkg/infradb/domain.go @@ -0,0 +1,66 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright (c) 2023-2024 Intel Corporation, or its subsidiaries. +// Copyright (c) 2024 Ericsson AB. + +package infradb + +import ( + "github.com/opiproject/opi-evpn-bridge/pkg/infradb/common" + "github.com/opiproject/opi-evpn-bridge/pkg/infradb/subscriberframework/eventbus" +) + +// IDomain holds the utilities for child objects +type IDomain interface { + getStatusComponents() []common.Component + setStatusComponents([]common.Component) + isOperationalStatus(OperStatus) bool + setOperationalStatus(OperStatus) + setNewResourceVersion() +} + +// OperStatus operational Status +type OperStatus int32 + +const ( + // OperStatusUnspecified for "unknown" state + OperStatusUnspecified OperStatus = iota + // OperStatusUp for "up" state + OperStatusUp = iota + // OperStatusDown for "down" state + OperStatusDown = iota + // OperStatusToBeDeleted for "to be deleted" state + OperStatusToBeDeleted = iota +) + +// Domain holds domain info +type Domain struct { + IDomain IDomain +} + +// prepareObjectsForReplay prepares an object for replay by setting the unsuccessful components +// in pending state and returning a list of the components that need to be contacted for the +// replay of the particular object that called the function. +func (in *Domain) prepareObjectsForReplay(componentName string, vrfSubs []*eventbus.Subscriber) []*eventbus.Subscriber { + // We assume that the list of Components that are returned + // from DB is ordered based on the priority as that was the + // way that has been stored in the DB in first place. + + vrfComponents := in.IDomain.getStatusComponents() + auxComponents := in.IDomain.getStatusComponents() + tempSubs := []*eventbus.Subscriber{} + for i, comp := range vrfComponents { + if comp.Name == componentName || comp.CompStatus != common.ComponentStatusSuccess { + auxComponents[i] = common.Component{Name: comp.Name, CompStatus: common.ComponentStatusPending, Details: ""} + tempSubs = append(tempSubs, vrfSubs[i]) + } + } + + in.IDomain.setStatusComponents(auxComponents) + + if in.IDomain.isOperationalStatus(OperStatusUp) { + in.IDomain.setOperationalStatus(OperStatusDown) + } + + in.IDomain.setNewResourceVersion() + return tempSubs +} diff --git a/pkg/infradb/port.go b/pkg/infradb/port.go index 77db2ab3..ff1f9779 100644 --- a/pkg/infradb/port.go +++ b/pkg/infradb/port.go @@ -66,6 +66,7 @@ type BridgePortMetadata struct { // BridgePort holds Bridge Port info type BridgePort struct { + Domain Name string Spec *BridgePortSpec Status *BridgePortStatus @@ -215,25 +216,47 @@ func (in *BridgePort) parseMeta(bpMeta *BridgePortMetadata) { } } -// prepareObjectsForReplay prepares an object for replay by setting the unsuccessful components -// in pending state and returning a list of the components that need to be contacted for the -// replay of the particular object that called the function. -func (in *BridgePort) prepareObjectsForReplay(componentName string, bpSubs []*eventbus.Subscriber) []*eventbus.Subscriber { - // We assume that the list of Components that are returned - // from DB is ordered based on the priority as that was the - // way that has been stored in the DB in first place. - bpComponents := in.Status.Components - tempSubs := []*eventbus.Subscriber{} - for i, comp := range bpComponents { - if comp.Name == componentName || comp.CompStatus != common.ComponentStatusSuccess { - in.Status.Components[i] = common.Component{Name: comp.Name, CompStatus: common.ComponentStatusPending, Details: ""} - tempSubs = append(tempSubs, bpSubs[i]) - } +func (in *BridgePort) getStatusComponents() []common.Component { + return in.Status.Components +} + +func (in *BridgePort) setStatusComponents(components []common.Component) { + copy(in.Status.Components, components) +} + +func (in *BridgePort) isOperationalStatus(operStatus OperStatus) bool { + switch operStatus { + case OperStatusUp: + return in.Status.BPOperStatus == BridgePortOperStatusUp + case OperStatusDown: + return in.Status.BPOperStatus == BridgePortOperStatusDown + case OperStatusToBeDeleted: + return in.Status.BPOperStatus == BridgePortOperStatusToBeDeleted + case OperStatusUnspecified: + return in.Status.BPOperStatus == BridgePortOperStatusUnspecified + default: + log.Println("isOperationalStatus(): operational status has not been identified") + return false } - if in.Status.BPOperStatus == BridgePortOperStatusUp { +} + +func (in *BridgePort) setOperationalStatus(operStatus OperStatus) { + switch operStatus { + case OperStatusUp: + in.Status.BPOperStatus = BridgePortOperStatusUp + case OperStatusDown: in.Status.BPOperStatus = BridgePortOperStatusDown + case OperStatusToBeDeleted: + in.Status.BPOperStatus = BridgePortOperStatusToBeDeleted + case OperStatusUnspecified: + in.Status.BPOperStatus = BridgePortOperStatusUnspecified + default: + log.Println("setOperationalStatus(): operational status has not been identified") } +} +// TODO: This function can probably be moved to the domain.go as the ResourceVersion +// field is common for all the child objects (VRF,LB, BP, SVI) +func (in *BridgePort) setNewResourceVersion() { in.ResourceVersion = generateVersion() - return tempSubs } diff --git a/pkg/infradb/replay.go b/pkg/infradb/replay.go index b6845c68..d4a418da 100644 --- a/pkg/infradb/replay.go +++ b/pkg/infradb/replay.go @@ -109,6 +109,8 @@ func gatherObjectsAndSubsToReplay(componentName string, objectTypesToReplay []st lbSubs := eventbus.EBus.GetSubscribers("logical-bridge") vrfSubs := eventbus.EBus.GetSubscribers("vrf") + domain := &Domain{} + for _, objType := range objectTypesToReplay { switch objType { case "vrf": @@ -138,7 +140,8 @@ func gatherObjectsAndSubsToReplay(componentName string, objectTypesToReplay []st // tempSubs holds the subscribers list to be contacted for every VRF object each time // for replay - tempSubs := vrf.prepareObjectsForReplay(componentName, vrfSubs) + domain.IDomain = vrf + tempSubs := domain.prepareObjectsForReplay(componentName, vrfSubs) err = infradb.client.Set(vrf.Name, vrf) if err != nil { @@ -172,7 +175,8 @@ func gatherObjectsAndSubsToReplay(componentName string, objectTypesToReplay []st // tempSubs holds the subscribers list to be contacted for every VRF object each time // for replay - tempSubs := lb.prepareObjectsForReplay(componentName, lbSubs) + domain.IDomain = lb + tempSubs := domain.prepareObjectsForReplay(componentName, lbSubs) err = infradb.client.Set(lb.Name, lb) if err != nil { @@ -205,7 +209,8 @@ func gatherObjectsAndSubsToReplay(componentName string, objectTypesToReplay []st // tempSubs holds the subscribers list to be contacted for every VRF object each time // for replay - tempSubs := svi.prepareObjectsForReplay(componentName, sviSubs) + domain.IDomain = svi + tempSubs := domain.prepareObjectsForReplay(componentName, sviSubs) err = infradb.client.Set(svi.Name, svi) if err != nil { @@ -238,7 +243,8 @@ func gatherObjectsAndSubsToReplay(componentName string, objectTypesToReplay []st // tempSubs holds the subscribers list to be contacted for every VRF object each time // for replay - tempSubs := bp.prepareObjectsForReplay(componentName, bpSubs) + domain.IDomain = bp + tempSubs := domain.prepareObjectsForReplay(componentName, bpSubs) err = infradb.client.Set(bp.Name, bp) if err != nil { diff --git a/pkg/infradb/svi.go b/pkg/infradb/svi.go index 114d5722..51472d1e 100644 --- a/pkg/infradb/svi.go +++ b/pkg/infradb/svi.go @@ -56,6 +56,7 @@ type SviMetadata struct { // Svi holds SVI info type Svi struct { + Domain Name string Spec *SviSpec Status *SviStatus @@ -197,25 +198,47 @@ func (in *Svi) parseMeta(sviMeta *SviMetadata) { } } -// prepareObjectsForReplay prepares an object for replay by setting the unsuccessful components -// in pending state and returning a list of the components that need to be contacted for the -// replay of the particular object that called the function. -func (in *Svi) prepareObjectsForReplay(componentName string, sviSubs []*eventbus.Subscriber) []*eventbus.Subscriber { - // We assume that the list of Components that are returned - // from DB is ordered based on the priority as that was the - // way that has been stored in the DB in first place. - sviComponents := in.Status.Components - tempSubs := []*eventbus.Subscriber{} - for i, comp := range sviComponents { - if comp.Name == componentName || comp.CompStatus != common.ComponentStatusSuccess { - in.Status.Components[i] = common.Component{Name: comp.Name, CompStatus: common.ComponentStatusPending, Details: ""} - tempSubs = append(tempSubs, sviSubs[i]) - } +func (in *Svi) getStatusComponents() []common.Component { + return in.Status.Components +} + +func (in *Svi) setStatusComponents(components []common.Component) { + copy(in.Status.Components, components) +} + +func (in *Svi) isOperationalStatus(operStatus OperStatus) bool { + switch operStatus { + case OperStatusUp: + return in.Status.SviOperStatus == SviOperStatusUp + case OperStatusDown: + return in.Status.SviOperStatus == SviOperStatusDown + case OperStatusToBeDeleted: + return in.Status.SviOperStatus == SviOperStatusToBeDeleted + case OperStatusUnspecified: + return in.Status.SviOperStatus == SviOperStatusUnspecified + default: + log.Println("isOperationalStatus(): operational status has not been identified") + return false } - if in.Status.SviOperStatus == SviOperStatusUp { +} + +func (in *Svi) setOperationalStatus(operStatus OperStatus) { + switch operStatus { + case OperStatusUp: + in.Status.SviOperStatus = SviOperStatusUp + case OperStatusDown: in.Status.SviOperStatus = SviOperStatusDown + case OperStatusToBeDeleted: + in.Status.SviOperStatus = SviOperStatusToBeDeleted + case OperStatusUnspecified: + in.Status.SviOperStatus = SviOperStatusUnspecified + default: + log.Println("setOperationalStatus(): operational status has not been identified") } +} +// TODO: This function can probably be moved to the domain.go as the ResourceVersion +// field is common for all the child objects (VRF,LB, BP, SVI) +func (in *Svi) setNewResourceVersion() { in.ResourceVersion = generateVersion() - return tempSubs } diff --git a/pkg/infradb/vrf.go b/pkg/infradb/vrf.go index bfa0d782..1832c3ed 100644 --- a/pkg/infradb/vrf.go +++ b/pkg/infradb/vrf.go @@ -57,6 +57,7 @@ type VrfMetadata struct { // Vrf holds VRF info type Vrf struct { + Domain Name string Spec *VrfSpec Status *VrfStatus @@ -269,25 +270,47 @@ func (in *Vrf) parseMeta(vrfMeta *VrfMetadata) { } } -// prepareObjectsForReplay prepares an object for replay by setting the unsuccessful components -// in pending state and returning a list of the components that need to be contacted for the -// replay of the particular object that called the function. -func (in *Vrf) prepareObjectsForReplay(componentName string, vrfSubs []*eventbus.Subscriber) []*eventbus.Subscriber { - // We assume that the list of Components that are returned - // from DB is ordered based on the priority as that was the - // way that has been stored in the DB in first place. - vrfComponents := in.Status.Components - tempSubs := []*eventbus.Subscriber{} - for i, comp := range vrfComponents { - if comp.Name == componentName || comp.CompStatus != common.ComponentStatusSuccess { - in.Status.Components[i] = common.Component{Name: comp.Name, CompStatus: common.ComponentStatusPending, Details: ""} - tempSubs = append(tempSubs, vrfSubs[i]) - } +func (in *Vrf) getStatusComponents() []common.Component { + return in.Status.Components +} + +func (in *Vrf) setStatusComponents(components []common.Component) { + copy(in.Status.Components, components) +} + +func (in *Vrf) isOperationalStatus(operStatus OperStatus) bool { + switch operStatus { + case OperStatusUp: + return in.Status.VrfOperStatus == VrfOperStatusUp + case OperStatusDown: + return in.Status.VrfOperStatus == VrfOperStatusDown + case OperStatusToBeDeleted: + return in.Status.VrfOperStatus == VrfOperStatusToBeDeleted + case OperStatusUnspecified: + return in.Status.VrfOperStatus == VrfOperStatusUnspecified + default: + log.Println("isOperationalStatus(): operational status has not been identified") + return false } - if in.Status.VrfOperStatus == VrfOperStatusUp { +} + +func (in *Vrf) setOperationalStatus(operStatus OperStatus) { + switch operStatus { + case OperStatusUp: + in.Status.VrfOperStatus = VrfOperStatusUp + case OperStatusDown: in.Status.VrfOperStatus = VrfOperStatusDown + case OperStatusToBeDeleted: + in.Status.VrfOperStatus = VrfOperStatusToBeDeleted + case OperStatusUnspecified: + in.Status.VrfOperStatus = VrfOperStatusUnspecified + default: + log.Println("setOperationalStatus(): operational status has not been identified") } +} +// TODO: This function can probably be moved to the domain.go as the ResourceVersion +// field is common for all the child objects (VRF,LB, BP, SVI) +func (in *Vrf) setNewResourceVersion() { in.ResourceVersion = generateVersion() - return tempSubs }