Skip to content

Commit

Permalink
Add partition wise network peering status in apinet Network resource (
Browse files Browse the repository at this point in the history
  • Loading branch information
kasabe28 authored Oct 11, 2024
1 parent b7df21c commit 6de703a
Show file tree
Hide file tree
Showing 15 changed files with 216 additions and 108 deletions.
2 changes: 1 addition & 1 deletion api/core/v1alpha1/network_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ type PeeringPrefix struct {

type NetworkStatus struct {
// Peerings contains the states of the network peerings for the network.
Peerings []NetworkPeeringStatus `json:"peerings,omitempty"`
Peerings map[string][]NetworkPeeringStatus `json:"peerings,omitempty"`
}

// NetworkState is the state of a network.
Expand Down
14 changes: 12 additions & 2 deletions api/core/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

43 changes: 24 additions & 19 deletions apinetlet/controllers/conversion.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,27 +80,32 @@ func apiNetNetworkInterfaceStateToNetworkInterfaceState(state apinetv1alpha1.Net
}
}

func apiNetNetworkPeeringsStatusToNetworkPeeringsStatus(peerings []apinetv1alpha1.NetworkPeeringStatus, specPeerings []apinetv1alpha1.NetworkPeering) []networkingv1alpha1.NetworkPeeringStatus {
networkPeeringsStatus := []networkingv1alpha1.NetworkPeeringStatus{}
for _, peering := range peerings {
idx := slices.IndexFunc(specPeerings, func(specPeering apinetv1alpha1.NetworkPeering) bool {
return specPeering.ID == strconv.Itoa(int(peering.ID))
})
if idx != -1 {
prefixStatus := []networkingv1alpha1.PeeringPrefixStatus{}
if peering.State == apinetv1alpha1.NetworkPeeringStateReady {
for _, peeringPrefix := range specPeerings[idx].Prefixes {
prefixStatus = append(prefixStatus, networkingv1alpha1.PeeringPrefixStatus{
Name: peeringPrefix.Name,
Prefix: (*commonv1alpha1.IPPrefix)(peeringPrefix.Prefix),
})
func apiNetNetworkPeeringsStatusToNetworkPeeringsStatus(partitionPeeringsMap map[string][]apinetv1alpha1.NetworkPeeringStatus, specPeerings []apinetv1alpha1.NetworkPeering) []networkingv1alpha1.NetworkPeeringStatus {
var networkPeeringsStatus []networkingv1alpha1.NetworkPeeringStatus
for _, peerings := range partitionPeeringsMap {
if len(peerings) == 0 {
continue
}
for _, peering := range peerings {
idx := slices.IndexFunc(specPeerings, func(specPeering apinetv1alpha1.NetworkPeering) bool {
return specPeering.ID == strconv.Itoa(int(peering.ID))
})
if idx != -1 {
var prefixStatus []networkingv1alpha1.PeeringPrefixStatus
if peering.State == apinetv1alpha1.NetworkPeeringStateReady {
for _, peeringPrefix := range specPeerings[idx].Prefixes {
prefixStatus = append(prefixStatus, networkingv1alpha1.PeeringPrefixStatus{
Name: peeringPrefix.Name,
Prefix: (*commonv1alpha1.IPPrefix)(peeringPrefix.Prefix),
})
}
}
networkPeeringsStatus = append(networkPeeringsStatus, networkingv1alpha1.NetworkPeeringStatus{
Name: specPeerings[idx].Name,
State: networkingv1alpha1.NetworkPeeringState(peering.State),
Prefixes: prefixStatus,
})
}
networkPeeringsStatus = append(networkPeeringsStatus, networkingv1alpha1.NetworkPeeringStatus{
Name: specPeerings[idx].Name,
State: networkingv1alpha1.NetworkPeeringState(peering.State),
Prefixes: prefixStatus,
})
}
}
return networkPeeringsStatus
Expand Down
72 changes: 50 additions & 22 deletions apinetlet/controllers/network_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@ package controllers
import (
"context"
"fmt"
"reflect"
"slices"

"github.com/go-logr/logr"

apinetv1alpha1 "github.com/ironcore-dev/ironcore-net/api/core/v1alpha1"
"github.com/ironcore-dev/ironcore-net/apimachinery/equality"
apinetletclient "github.com/ironcore-dev/ironcore-net/apinetlet/client"
"github.com/ironcore-dev/ironcore-net/apinetlet/handler"
"github.com/ironcore-dev/ironcore-net/apinetlet/provider"
Expand Down Expand Up @@ -118,12 +120,17 @@ func (r *NetworkReconciler) delete(ctx context.Context, log logr.Logger, network
return ctrl.Result{Requeue: true}, nil
}

func (r *NetworkReconciler) updateNetworkStatus(ctx context.Context, network *networkingv1alpha1.Network, apiNetNetwork *apinetv1alpha1.Network, state networkingv1alpha1.NetworkState) error {
func (r *NetworkReconciler) updateNetworkStatus(ctx context.Context, log logr.Logger, network *networkingv1alpha1.Network, apiNetNetwork *apinetv1alpha1.Network, state networkingv1alpha1.NetworkState) error {
networkBase := network.DeepCopy()
network.Status.State = state
network.Status.Peerings = apiNetNetworkPeeringsStatusToNetworkPeeringsStatus(apiNetNetwork.Status.Peerings, apiNetNetwork.Spec.Peerings)
if err := r.Status().Patch(ctx, network, client.MergeFrom(networkBase)); err != nil {
return fmt.Errorf("unable to patch network: %w", err)
statusPeerings := apiNetNetworkPeeringsStatusToNetworkPeeringsStatus(apiNetNetwork.Status.Peerings, apiNetNetwork.Spec.Peerings)
log.V(1).Info("network status peerings", "old", network.Status.Peerings, "new", statusPeerings)
if network.Status.State != state || !reflect.DeepEqual(network.Status.Peerings, statusPeerings) {
log.V(1).Info("Patching network status")
network.Status.State = state
network.Status.Peerings = statusPeerings
if err := r.Status().Patch(ctx, network, client.MergeFrom(networkBase)); err != nil {
return fmt.Errorf("unable to patch network: %w", err)
}
}
return nil
}
Expand All @@ -144,7 +151,7 @@ func (r *NetworkReconciler) reconcile(ctx context.Context, log logr.Logger, netw
apiNetNetwork, err := r.applyAPINetNetwork(ctx, log, network)
if err != nil {
if network.Status.State != networkingv1alpha1.NetworkStateAvailable {
if err := r.updateNetworkStatus(ctx, network, apiNetNetwork, networkingv1alpha1.NetworkStatePending); err != nil {
if err := r.updateNetworkStatus(ctx, log, network, apiNetNetwork, networkingv1alpha1.NetworkStatePending); err != nil {
log.Error(err, "Error updating network state")
}
}
Expand All @@ -164,7 +171,7 @@ func (r *NetworkReconciler) reconcile(ctx context.Context, log logr.Logger, netw
}

log.V(1).Info("Updating network status")
if err := r.updateNetworkStatus(ctx, network, apiNetNetwork, networkingv1alpha1.NetworkStateAvailable); err != nil {
if err := r.updateNetworkStatus(ctx, log, network, apiNetNetwork, networkingv1alpha1.NetworkStateAvailable); err != nil {
return ctrl.Result{}, fmt.Errorf("error updating network status: %w", err)
}
log.V(1).Info("Updated network status")
Expand All @@ -187,16 +194,29 @@ func (r *NetworkReconciler) setNetworkProviderID(
}

func (r *NetworkReconciler) applyAPINetNetwork(ctx context.Context, log logr.Logger, network *networkingv1alpha1.Network) (*apinetv1alpha1.Network, error) {
apiNetNetwork := &apinetv1alpha1.Network{
TypeMeta: metav1.TypeMeta{
APIVersion: apinetv1alpha1.SchemeGroupVersion.String(),
Kind: "Network",
},
ObjectMeta: metav1.ObjectMeta{
Namespace: r.APINetNamespace,
Name: string(network.UID),
Labels: apinetletclient.SourceLabels(r.Scheme(), r.RESTMapper(), network),
},
isNetworkExist := false
apiNetNetwork := &apinetv1alpha1.Network{}
apiNetNetworkKey := client.ObjectKey{Namespace: r.APINetNamespace, Name: string(network.UID)}
log.V(1).Info("Check if APINet network already exists")
if err := r.APINetClient.Get(ctx, apiNetNetworkKey, apiNetNetwork); err != nil {
if !apierrors.IsNotFound(err) {
return nil, fmt.Errorf("error getting apinet network %s: %w", apiNetNetworkKey.Name, err)
} else {
apiNetNetwork = &apinetv1alpha1.Network{
TypeMeta: metav1.TypeMeta{
APIVersion: apinetv1alpha1.SchemeGroupVersion.String(),
Kind: "Network",
},
ObjectMeta: metav1.ObjectMeta{
Namespace: r.APINetNamespace,
Name: string(network.UID),
Labels: apinetletclient.SourceLabels(r.Scheme(), r.RESTMapper(), network),
},
}
}
} else {
log.V(1).Info("APINet network already exists")
isNetworkExist = true
}

var peerings []apinetv1alpha1.NetworkPeering
Expand Down Expand Up @@ -228,17 +248,25 @@ func (r *NetworkReconciler) applyAPINetNetwork(ctx context.Context, log logr.Log
})
}
}
apiNetNetwork.Spec.Peerings = peerings

log.V(1).Info("Applying APINet network")
if err := r.APINetClient.Patch(ctx, apiNetNetwork, client.Apply, fieldOwner, client.ForceOwnership); err != nil {
return nil, fmt.Errorf("error applying APINet network: %w", err)
isPeeringsEqual := equality.Semantic.DeepEqual(apiNetNetwork.Spec.Peerings, peerings)

if !isNetworkExist || !isPeeringsEqual {
log.V(1).Info("Applying APINet network")

if !isPeeringsEqual {
apiNetNetwork.Spec.Peerings = peerings
}
apiNetNetwork.ManagedFields = nil
if err := r.APINetClient.Patch(ctx, apiNetNetwork, client.Apply, fieldOwner, client.ForceOwnership); err != nil {
return nil, fmt.Errorf("error applying apinet network: %w", err)
}
}
return apiNetNetwork, nil
}

func (r *NetworkReconciler) getAPINetNetworkPeeringPrefixes(ctx context.Context, peeringPrefixes []networkingv1alpha1.PeeringPrefix, networkNamespace string) ([]apinetv1alpha1.PeeringPrefix, error) {
apinetPeeringPrefixes := []apinetv1alpha1.PeeringPrefix{}
var apinetPeeringPrefixes []apinetv1alpha1.PeeringPrefix
for _, prefix := range peeringPrefixes {
if prefix.Prefix != nil {
apinetPeeringPrefixes = append(apinetPeeringPrefixes, apinetv1alpha1.PeeringPrefix{
Expand Down
12 changes: 8 additions & 4 deletions apinetlet/controllers/network_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -201,15 +201,17 @@ var _ = Describe("NetworkController", func() {
By("patching apinet network peering status")
apiNetNetwork2ID, _ := strconv.Atoi(apiNetNetwork2.Spec.ID)
Eventually(UpdateStatus(apiNetNetwork1, func() {
apiNetNetwork1.Status.Peerings = []apinetv1alpha1.NetworkPeeringStatus{{
apiNetNetwork1.Status.Peerings = make(map[string][]apinetv1alpha1.NetworkPeeringStatus)
apiNetNetwork1.Status.Peerings["partition1"] = []apinetv1alpha1.NetworkPeeringStatus{{
ID: int32(apiNetNetwork2ID),
State: apinetv1alpha1.NetworkPeeringStateReady,
}}
})).Should(Succeed())

apiNetNetwork1ID, _ := strconv.Atoi(apiNetNetwork1.Spec.ID)
Eventually(UpdateStatus(apiNetNetwork2, func() {
apiNetNetwork2.Status.Peerings = []apinetv1alpha1.NetworkPeeringStatus{{
apiNetNetwork2.Status.Peerings = make(map[string][]apinetv1alpha1.NetworkPeeringStatus)
apiNetNetwork2.Status.Peerings["partition1"] = []apinetv1alpha1.NetworkPeeringStatus{{
ID: int32(apiNetNetwork1ID),
State: apinetv1alpha1.NetworkPeeringStateReady,
}}
Expand Down Expand Up @@ -377,15 +379,17 @@ var _ = Describe("NetworkController", func() {
By("patching apinet network peering status")
apiNetNetwork2ID, _ := strconv.Atoi(apiNetNetwork2.Spec.ID)
Eventually(UpdateStatus(apiNetNetwork1, func() {
apiNetNetwork1.Status.Peerings = []apinetv1alpha1.NetworkPeeringStatus{{
apiNetNetwork1.Status.Peerings = make(map[string][]apinetv1alpha1.NetworkPeeringStatus)
apiNetNetwork1.Status.Peerings["partition1"] = []apinetv1alpha1.NetworkPeeringStatus{{
ID: int32(apiNetNetwork2ID),
State: apinetv1alpha1.NetworkPeeringStateReady,
}}
})).Should(Succeed())

apiNetNetwork1ID, _ := strconv.Atoi(apiNetNetwork1.Spec.ID)
Eventually(UpdateStatus(apiNetNetwork2, func() {
apiNetNetwork2.Status.Peerings = []apinetv1alpha1.NetworkPeeringStatus{{
apiNetNetwork2.Status.Peerings = make(map[string][]apinetv1alpha1.NetworkPeeringStatus)
apiNetNetwork2.Status.Peerings["partition1"] = []apinetv1alpha1.NetworkPeeringStatus{{
ID: int32(apiNetNetwork1ID),
State: apinetv1alpha1.NetworkPeeringStateReady,
}}
Expand Down
23 changes: 14 additions & 9 deletions client-go/applyconfigurations/core/v1alpha1/networkstatus.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 5 additions & 3 deletions client-go/applyconfigurations/internal/internal.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion client-go/openapi/api_violations.report
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ API rule violation: list_type_missing,github.com/ironcore-dev/ironcore-net/api/c
API rule violation: list_type_missing,github.com/ironcore-dev/ironcore-net/api/core/v1alpha1,NetworkPolicySpec,Ingress
API rule violation: list_type_missing,github.com/ironcore-dev/ironcore-net/api/core/v1alpha1,NetworkPolicySpec,PolicyTypes
API rule violation: list_type_missing,github.com/ironcore-dev/ironcore-net/api/core/v1alpha1,NetworkSpec,Peerings
API rule violation: list_type_missing,github.com/ironcore-dev/ironcore-net/api/core/v1alpha1,NetworkStatus,Peerings
API rule violation: list_type_missing,github.com/ironcore-dev/ironcore-net/api/core/v1alpha1,NodeSelector,NodeSelectorTerms
API rule violation: list_type_missing,github.com/ironcore-dev/ironcore-net/api/core/v1alpha1,NodeSelectorRequirement,Values
API rule violation: list_type_missing,github.com/ironcore-dev/ironcore-net/api/core/v1alpha1,NodeSelectorTerm,MatchExpressions
Expand Down
16 changes: 12 additions & 4 deletions client-go/openapi/zz_generated.openapi.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 4 additions & 7 deletions docs/api-reference/core.md
Original file line number Diff line number Diff line change
Expand Up @@ -1556,7 +1556,7 @@ LocalUIDReference
</em>
</td>
<td>
<p>NetworkRef is the network the load balancer is assigned to.</p>
<p>NetworkRef is the network to which network policy is applied.</p>
</td>
</tr>
<tr>
Expand Down Expand Up @@ -3800,9 +3800,6 @@ to the peered network, if no prefixes are specified no filtering will be done.</
</table>
<h3 id="core.apinet.ironcore.dev/v1alpha1.NetworkPeeringStatus">NetworkPeeringStatus
</h3>
<p>
(<em>Appears on:</em><a href="#core.apinet.ironcore.dev/v1alpha1.NetworkStatus">NetworkStatus</a>)
</p>
<div>
<p>NetworkPeeringStatus is the status of a network peering.</p>
</div>
Expand Down Expand Up @@ -4201,8 +4198,8 @@ string
<td>
<code>peerings</code><br/>
<em>
<a href="#core.apinet.ironcore.dev/v1alpha1.NetworkPeeringStatus">
[]NetworkPeeringStatus
<a href="#core.apinet.ironcore.dev/v1alpha1.[]ironcore-net/api/core/v1alpha1.NetworkPeeringStatus">
map[string][]ironcore-net/api/core/v1alpha1.NetworkPeeringStatus
</a>
</em>
</td>
Expand Down Expand Up @@ -4570,7 +4567,7 @@ string
(<em>Appears on:</em><a href="#core.apinet.ironcore.dev/v1alpha1.NetworkPeering">NetworkPeering</a>)
</p>
<div>
<p>PeeringPrefixes defines prefixes to be exposed to the peered network</p>
<p>PeeringPrefix defines prefixes to be exposed to the peered network</p>
</div>
<table>
<thead>
Expand Down
2 changes: 1 addition & 1 deletion internal/apis/core/network_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ type PeeringPrefix struct {
}
type NetworkStatus struct {
// Peerings contains the states of the network peerings for the network.
Peerings []NetworkPeeringStatus
Peerings map[string][]NetworkPeeringStatus
}

// NetworkState is the state of a network.
Expand Down
Loading

0 comments on commit 6de703a

Please sign in to comment.