Skip to content
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
84 changes: 15 additions & 69 deletions cmd/metal-api/internal/metal/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ import (
"slices"
"strconv"
"strings"

"github.com/samber/lo"
)

// SwitchPortStatus is a type alias for a string that represents the status of a switch port.
Expand Down Expand Up @@ -56,8 +54,7 @@ type Nic struct {

// NicState represents the desired and actual state of a network interface
// controller (NIC). The Desired field indicates the intended state of the
// NIC, while Actual indicates its current operational state. The Desired
// state will be removed when the actual state is equal to the desired state.
// NIC, while Actual indicates its current operational state.
type NicState struct {
Desired *SwitchPortStatus `rethinkdb:"desired" json:"desired"`
Actual SwitchPortStatus `rethinkdb:"actual" json:"actual"`
Expand All @@ -75,91 +72,40 @@ type SwitchBGPPortState struct {

// SetState updates the NicState with the given SwitchPortStatus. It returns
// a new NicState and a bool indicating if the state was changed.
//
// If the given status matches the current Actual state, it checks if Desired
// is set and matches too. If so, Desired is set to nil since the desired
// state has been reached.
//
// If the given status differs from the current Actual state, Desired is left
// unchanged if it differs from the new state so the desired state is still tracked.
// The Actual state is updated to the given status.
//
// This allows tracking both the desired and actual states, while clearing
// Desired once the desired state is achieved.
func (ns *NicState) SetState(s SwitchPortStatus) (NicState, bool) {
func (ns *NicState) SetState(status SwitchPortStatus) (NicState, bool) {
if ns == nil {
Comment thread
iljarotar marked this conversation as resolved.
return NicState{
Actual: s,
Actual: status,
Desired: nil,
}, true
}
if ns.Actual == s {
if ns.Desired != nil {
if *ns.Desired == s {
// we now have the desired state, so set the desired state to nil
return NicState{
Actual: s,
Desired: nil,
}, true
} else {
// we already have the reported state, but the desired one is different
// so nothing changed
return *ns, false
}
}
// nothing changed
return *ns, false
}
// we got another state as we had before
if ns.Desired != nil {
if *ns.Desired == s {
// we now have the desired state, so set the desired state to nil
return NicState{
Actual: s,
Desired: nil,
}, true
} else {
// a new state was reported, but the desired one is different
// so we have to update the state but keep the desired state
return NicState{
Actual: s,
Desired: ns.Desired,
}, true
}
}
changed := ns.Actual != status
return NicState{
Actual: s,
Desired: nil,
}, true
Actual: status,
Desired: ns.Desired,
}, changed
}

// WantState sets the desired state for the NIC. It returns a new NicState
// struct with the desired state set and a bool indicating if the state changed.
// If the current state already matches the desired state, it returns a state
// with a cleared desired field.
func (ns *NicState) WantState(s SwitchPortStatus) (NicState, bool) {
if ns == nil {
return NicState{
Actual: SwitchPortStatusUnknown,
Desired: &s,
}, true
}
if ns.Actual == s {
// we want a state we already have
if ns.Desired != nil {
return NicState{
Actual: s,
Desired: nil,
}, true
}
return *ns, false
if ns.Desired == nil {
return NicState{
Desired: &s,
Actual: ns.Actual,
}, true
}
// return a new state with the desired state set and a bool indicating a state change
// only if the desired state is different from the current one
changed := s != *ns.Desired
return NicState{
Actual: ns.Actual,
Desired: &s,
}, lo.FromPtr(ns.Desired) != s
Actual: ns.Actual,
}, changed
}

// GetIdentifier returns the identifier of a nic.
Expand Down
Loading
Loading