From da8fdf192db2e90e18238c41d77c8665fa794b21 Mon Sep 17 00:00:00 2001 From: Kajol Asabe Date: Tue, 1 Oct 2024 21:44:17 +0530 Subject: [PATCH] Add partition wise network peering status in apinetlet --- api/core/v1alpha1/network_types.go | 2 +- api/core/v1alpha1/zz_generated.deepcopy.go | 14 ++++++- apinetlet/controllers/conversion.go | 41 +++++++++++-------- apinetlet/controllers/network_controller.go | 3 -- .../controllers/network_controller_test.go | 8 ++-- .../core/v1alpha1/networkstatus.go | 23 +++++++---- .../applyconfigurations/internal/internal.go | 8 ++-- client-go/openapi/api_violations.report | 1 - client-go/openapi/zz_generated.openapi.go | 16 ++++++-- docs/api-reference/core.md | 11 ++--- internal/apis/core/network_types.go | 2 +- .../core/v1alpha1/zz_generated.conversion.go | 4 +- internal/apis/core/zz_generated.deepcopy.go | 14 ++++++- metalnetlet/controllers/network_controller.go | 23 ++++------- .../controllers/network_controller_test.go | 8 ++-- 15 files changed, 101 insertions(+), 77 deletions(-) diff --git a/api/core/v1alpha1/network_types.go b/api/core/v1alpha1/network_types.go index 7ce301c1..c525f4b3 100644 --- a/api/core/v1alpha1/network_types.go +++ b/api/core/v1alpha1/network_types.go @@ -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. diff --git a/api/core/v1alpha1/zz_generated.deepcopy.go b/api/core/v1alpha1/zz_generated.deepcopy.go index 322f2296..a8807fcb 100644 --- a/api/core/v1alpha1/zz_generated.deepcopy.go +++ b/api/core/v1alpha1/zz_generated.deepcopy.go @@ -1929,8 +1929,18 @@ func (in *NetworkStatus) DeepCopyInto(out *NetworkStatus) { *out = *in if in.Peerings != nil { in, out := &in.Peerings, &out.Peerings - *out = make([]NetworkPeeringStatus, len(*in)) - copy(*out, *in) + *out = make(map[string][]NetworkPeeringStatus, len(*in)) + for key, val := range *in { + var outVal []NetworkPeeringStatus + if val == nil { + (*out)[key] = nil + } else { + in, out := &val, &outVal + *out = make([]NetworkPeeringStatus, len(*in)) + copy(*out, *in) + } + (*out)[key] = outVal + } } return } diff --git a/apinetlet/controllers/conversion.go b/apinetlet/controllers/conversion.go index 535a9848..b14c717b 100644 --- a/apinetlet/controllers/conversion.go +++ b/apinetlet/controllers/conversion.go @@ -80,27 +80,32 @@ func apiNetNetworkInterfaceStateToNetworkInterfaceState(state apinetv1alpha1.Net } } -func apiNetNetworkPeeringsStatusToNetworkPeeringsStatus(peerings []apinetv1alpha1.NetworkPeeringStatus, specPeerings []apinetv1alpha1.NetworkPeering) []networkingv1alpha1.NetworkPeeringStatus { +func apiNetNetworkPeeringsStatusToNetworkPeeringsStatus(partitionPeeringsMap map[string][]apinetv1alpha1.NetworkPeeringStatus, specPeerings []apinetv1alpha1.NetworkPeering) []networkingv1alpha1.NetworkPeeringStatus { var 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 { - 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), - }) + 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 diff --git a/apinetlet/controllers/network_controller.go b/apinetlet/controllers/network_controller.go index aa5f810b..ad16afe9 100644 --- a/apinetlet/controllers/network_controller.go +++ b/apinetlet/controllers/network_controller.go @@ -248,10 +248,7 @@ func (r *NetworkReconciler) applyAPINetNetwork(ctx context.Context, log logr.Log }) } } - // apiNetNetwork.Spec.Peerings = peerings - log.V(1).Info("APINet network spec peerings", "old", apiNetNetwork.Spec.Peerings, "new", peerings) - log.V(1).Info("APINet network status", "old", apiNetNetwork.Status.Peerings) isPeeringsEqual := equality.Semantic.DeepEqual(apiNetNetwork.Spec.Peerings, peerings) if !isNetworkExist || !isPeeringsEqual { diff --git a/apinetlet/controllers/network_controller_test.go b/apinetlet/controllers/network_controller_test.go index 3b0cc086..6fc8d99f 100644 --- a/apinetlet/controllers/network_controller_test.go +++ b/apinetlet/controllers/network_controller_test.go @@ -201,7 +201,7 @@ 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["partition1"] = []apinetv1alpha1.NetworkPeeringStatus{{ ID: int32(apiNetNetwork2ID), State: apinetv1alpha1.NetworkPeeringStateReady, }} @@ -209,7 +209,7 @@ var _ = Describe("NetworkController", func() { apiNetNetwork1ID, _ := strconv.Atoi(apiNetNetwork1.Spec.ID) Eventually(UpdateStatus(apiNetNetwork2, func() { - apiNetNetwork2.Status.Peerings = []apinetv1alpha1.NetworkPeeringStatus{{ + apiNetNetwork2.Status.Peerings["partition1"] = []apinetv1alpha1.NetworkPeeringStatus{{ ID: int32(apiNetNetwork1ID), State: apinetv1alpha1.NetworkPeeringStateReady, }} @@ -377,7 +377,7 @@ 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["partition1"] = []apinetv1alpha1.NetworkPeeringStatus{{ ID: int32(apiNetNetwork2ID), State: apinetv1alpha1.NetworkPeeringStateReady, }} @@ -385,7 +385,7 @@ var _ = Describe("NetworkController", func() { apiNetNetwork1ID, _ := strconv.Atoi(apiNetNetwork1.Spec.ID) Eventually(UpdateStatus(apiNetNetwork2, func() { - apiNetNetwork2.Status.Peerings = []apinetv1alpha1.NetworkPeeringStatus{{ + apiNetNetwork2.Status.Peerings["partition1"] = []apinetv1alpha1.NetworkPeeringStatus{{ ID: int32(apiNetNetwork1ID), State: apinetv1alpha1.NetworkPeeringStateReady, }} diff --git a/client-go/applyconfigurations/core/v1alpha1/networkstatus.go b/client-go/applyconfigurations/core/v1alpha1/networkstatus.go index 02623207..8cb0c087 100644 --- a/client-go/applyconfigurations/core/v1alpha1/networkstatus.go +++ b/client-go/applyconfigurations/core/v1alpha1/networkstatus.go @@ -5,10 +5,14 @@ package v1alpha1 +import ( + v1alpha1 "github.com/ironcore-dev/ironcore-net/api/core/v1alpha1" +) + // NetworkStatusApplyConfiguration represents an declarative configuration of the NetworkStatus type for use // with apply. type NetworkStatusApplyConfiguration struct { - Peerings []NetworkPeeringStatusApplyConfiguration `json:"peerings,omitempty"` + Peerings map[string][]v1alpha1.NetworkPeeringStatus `json:"peerings,omitempty"` } // NetworkStatusApplyConfiguration constructs an declarative configuration of the NetworkStatus type for use with @@ -17,15 +21,16 @@ func NetworkStatus() *NetworkStatusApplyConfiguration { return &NetworkStatusApplyConfiguration{} } -// WithPeerings adds the given value to the Peerings field in the declarative configuration +// WithPeerings puts the entries into the Peerings field in the declarative configuration // and returns the receiver, so that objects can be build by chaining "With" function invocations. -// If called multiple times, values provided by each call will be appended to the Peerings field. -func (b *NetworkStatusApplyConfiguration) WithPeerings(values ...*NetworkPeeringStatusApplyConfiguration) *NetworkStatusApplyConfiguration { - for i := range values { - if values[i] == nil { - panic("nil value passed to WithPeerings") - } - b.Peerings = append(b.Peerings, *values[i]) +// If called multiple times, the entries provided by each call will be put on the Peerings field, +// overwriting an existing map entries in Peerings field with the same key. +func (b *NetworkStatusApplyConfiguration) WithPeerings(entries map[string][]v1alpha1.NetworkPeeringStatus) *NetworkStatusApplyConfiguration { + if b.Peerings == nil && len(entries) > 0 { + b.Peerings = make(map[string][]v1alpha1.NetworkPeeringStatus, len(entries)) + } + for k, v := range entries { + b.Peerings[k] = v } return b } diff --git a/client-go/applyconfigurations/internal/internal.go b/client-go/applyconfigurations/internal/internal.go index f45ede9e..c56e4dee 100644 --- a/client-go/applyconfigurations/internal/internal.go +++ b/client-go/applyconfigurations/internal/internal.go @@ -972,10 +972,12 @@ var schemaYAML = typed.YAMLObject(`types: fields: - name: peerings type: - list: + map: elementType: - namedType: com.github.ironcore-dev.ironcore-net.api.core.v1alpha1.NetworkPeeringStatus - elementRelationship: atomic + list: + elementType: + namedType: com.github.ironcore-dev.ironcore-net.api.core.v1alpha1.NetworkPeeringStatus + elementRelationship: atomic - name: com.github.ironcore-dev.ironcore-net.api.core.v1alpha1.Node map: fields: diff --git a/client-go/openapi/api_violations.report b/client-go/openapi/api_violations.report index b7c1e0db..2be1b68a 100644 --- a/client-go/openapi/api_violations.report +++ b/client-go/openapi/api_violations.report @@ -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 diff --git a/client-go/openapi/zz_generated.openapi.go b/client-go/openapi/zz_generated.openapi.go index 4d24c205..24841bdd 100644 --- a/client-go/openapi/zz_generated.openapi.go +++ b/client-go/openapi/zz_generated.openapi.go @@ -3430,12 +3430,20 @@ func schema_ironcore_net_api_core_v1alpha1_NetworkStatus(ref common.ReferenceCal "peerings": { SchemaProps: spec.SchemaProps{ Description: "Peerings contains the states of the network peerings for the network.", - Type: []string{"array"}, - Items: &spec.SchemaOrArray{ + Type: []string{"object"}, + AdditionalProperties: &spec.SchemaOrBool{ + Allows: true, Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/ironcore-dev/ironcore-net/api/core/v1alpha1.NetworkPeeringStatus"), + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/ironcore-dev/ironcore-net/api/core/v1alpha1.NetworkPeeringStatus"), + }, + }, + }, }, }, }, diff --git a/docs/api-reference/core.md b/docs/api-reference/core.md index c9a7bc9a..47de3fda 100644 --- a/docs/api-reference/core.md +++ b/docs/api-reference/core.md @@ -1556,7 +1556,7 @@ LocalUIDReference -

NetworkRef is the network the load balancer is assigned to.

+

NetworkRef is the network to which network policy is applied.

@@ -3800,9 +3800,6 @@ to the peered network, if no prefixes are specified no filtering will be done.

NetworkPeeringStatus

-

-(Appears on:NetworkStatus) -

NetworkPeeringStatus is the status of a network peering.

@@ -4201,8 +4198,8 @@ string peerings
- -[]NetworkPeeringStatus + +map[string][]ironcore-net/api/core/v1alpha1.NetworkPeeringStatus @@ -4570,7 +4567,7 @@ string (Appears on:NetworkPeering)

-

PeeringPrefixes defines prefixes to be exposed to the peered network

+

PeeringPrefix defines prefixes to be exposed to the peered network

diff --git a/internal/apis/core/network_types.go b/internal/apis/core/network_types.go index 23b435d2..cdbebac8 100644 --- a/internal/apis/core/network_types.go +++ b/internal/apis/core/network_types.go @@ -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. diff --git a/internal/apis/core/v1alpha1/zz_generated.conversion.go b/internal/apis/core/v1alpha1/zz_generated.conversion.go index ff3025ca..2720988c 100644 --- a/internal/apis/core/v1alpha1/zz_generated.conversion.go +++ b/internal/apis/core/v1alpha1/zz_generated.conversion.go @@ -2694,7 +2694,7 @@ func Convert_core_NetworkSpec_To_v1alpha1_NetworkSpec(in *core.NetworkSpec, out } func autoConvert_v1alpha1_NetworkStatus_To_core_NetworkStatus(in *v1alpha1.NetworkStatus, out *core.NetworkStatus, s conversion.Scope) error { - out.Peerings = *(*[]core.NetworkPeeringStatus)(unsafe.Pointer(&in.Peerings)) + out.Peerings = *(*map[string][]core.NetworkPeeringStatus)(unsafe.Pointer(&in.Peerings)) return nil } @@ -2704,7 +2704,7 @@ func Convert_v1alpha1_NetworkStatus_To_core_NetworkStatus(in *v1alpha1.NetworkSt } func autoConvert_core_NetworkStatus_To_v1alpha1_NetworkStatus(in *core.NetworkStatus, out *v1alpha1.NetworkStatus, s conversion.Scope) error { - out.Peerings = *(*[]v1alpha1.NetworkPeeringStatus)(unsafe.Pointer(&in.Peerings)) + out.Peerings = *(*map[string][]v1alpha1.NetworkPeeringStatus)(unsafe.Pointer(&in.Peerings)) return nil } diff --git a/internal/apis/core/zz_generated.deepcopy.go b/internal/apis/core/zz_generated.deepcopy.go index 2447be90..82b96241 100644 --- a/internal/apis/core/zz_generated.deepcopy.go +++ b/internal/apis/core/zz_generated.deepcopy.go @@ -1929,8 +1929,18 @@ func (in *NetworkStatus) DeepCopyInto(out *NetworkStatus) { *out = *in if in.Peerings != nil { in, out := &in.Peerings, &out.Peerings - *out = make([]NetworkPeeringStatus, len(*in)) - copy(*out, *in) + *out = make(map[string][]NetworkPeeringStatus, len(*in)) + for key, val := range *in { + var outVal []NetworkPeeringStatus + if val == nil { + (*out)[key] = nil + } else { + in, out := &val, &outVal + *out = make([]NetworkPeeringStatus, len(*in)) + copy(*out, *in) + } + (*out)[key] = outVal + } } return } diff --git a/metalnetlet/controllers/network_controller.go b/metalnetlet/controllers/network_controller.go index d4a61203..42dc78c0 100644 --- a/metalnetlet/controllers/network_controller.go +++ b/metalnetlet/controllers/network_controller.go @@ -114,12 +114,14 @@ func (r *NetworkReconciler) delete(ctx context.Context, log logr.Logger, network } func (r *NetworkReconciler) updateApinetNetworkStatus(ctx context.Context, log logr.Logger, network *apinetv1alpha1.Network, metalnetNetwork *metalnetv1alpha1.Network) error { - newStatusPeerings := metalnetNetworkPeeringsStatusToNetworkPeeringsStatus(metalnetNetwork.Status.Peerings) - log.V(1).Info("apinet status", "old", network.Status.Peerings, "new", newStatusPeerings) - if !equality.Semantic.DeepEqual(network.Status.Peerings, newStatusPeerings) { - log.V(1).Info("Patching apinet network status", "status", newStatusPeerings) + apinetStatusPeerings := metalnetNetworkPeeringsStatusToNetworkPeeringsStatus(metalnetNetwork.Status.Peerings) + if !equality.Semantic.DeepEqual(network.Status.Peerings[r.PartitionName], apinetStatusPeerings) { + log.V(1).Info("Patching apinet network status", "status", apinetStatusPeerings) networkBase := network.DeepCopy() - network.Status.Peerings = newStatusPeerings + if network.Status.Peerings == nil { + network.Status.Peerings = make(map[string][]apinetv1alpha1.NetworkPeeringStatus, 0) + } + network.Status.Peerings[r.PartitionName] = apinetStatusPeerings if err := r.Status().Patch(ctx, network, client.MergeFrom(networkBase)); err != nil { return fmt.Errorf("unable to patch network: %w", err) } @@ -219,7 +221,6 @@ func (r *NetworkReconciler) reconcile(ctx context.Context, log logr.Logger, netw } log.V(1).Info("Updating apinet network status") - log.V(1).Info("network status", "apinet", network.Status, "metalnet", metalnetNetwork.Status) if err := r.updateApinetNetworkStatus(ctx, log, network, metalnetNetwork); err != nil { return ctrl.Result{}, fmt.Errorf("error updating apinet networkstatus: %w", err) } @@ -251,13 +252,3 @@ func (r *NetworkReconciler) SetupWithManager(mgr ctrl.Manager, metalnetCache cac ). Complete(r) } - -// func (r *NetworkReconciler) networkStatusChangedPredicate() predicate.Predicate { -// return predicate.Funcs{ -// UpdateFunc: func(evt event.UpdateEvent) bool { -// oldNetwork := evt.ObjectOld.(*apinetv1alpha1.Network) -// newNetwork := evt.ObjectNew.(*apinetv1alpha1.Network) -// return !slices.Equal(oldNetwork.Status.Peerings, newNetwork.Status.Peerings) -// }, -// } -// } diff --git a/metalnetlet/controllers/network_controller_test.go b/metalnetlet/controllers/network_controller_test.go index 0ad416b3..bbac3c9b 100644 --- a/metalnetlet/controllers/network_controller_test.go +++ b/metalnetlet/controllers/network_controller_test.go @@ -114,17 +114,17 @@ var _ = Describe("NetworkController", func() { By("ensuring apinet network status peerings are also updated") Eventually(Object(network1)).Should(SatisfyAll( - HaveField("Status.Peerings", []apinetv1alpha1.NetworkPeeringStatus{{ + HaveField("Status.Peerings", HaveKeyWithValue(partitionName, []apinetv1alpha1.NetworkPeeringStatus{{ ID: network2Vni, State: apinetv1alpha1.NetworkPeeringStateReady, - }}), + }})), )) Eventually(Object(network2)).Should(SatisfyAll( - HaveField("Status.Peerings", []apinetv1alpha1.NetworkPeeringStatus{{ + HaveField("Status.Peerings", HaveKeyWithValue(partitionName, []apinetv1alpha1.NetworkPeeringStatus{{ ID: network1Vni, State: apinetv1alpha1.NetworkPeeringStateReady, - }}), + }})), )) By("deleting the networks")