L3 subinterface configuration for Ciso NX-OS Provider#317
L3 subinterface configuration for Ciso NX-OS Provider#317sven-rosenzweig wants to merge 3 commits intomainfrom
Conversation
Add a new "subinterface" interface type to support Layer 3 subinterfaces. Layer 3 subinterfaces allow a single physical router interface to handle traffic from multiple VLANs by creating separate logical interfaces per VLAN. Validation rules: - Encapsulation is allowed for subinterfaces only - Supported encapsulation types: 802.1Q and 802.1ad - Validate VLAN ID range - 802.1ad requires two VLAN IDs (outer and inner VLAN) - Subinterfaces cannot be configured as aggregate, switchport, or vlanRef
3ece646 to
95eaba0
Compare
| CreateFunc: func(e event.CreateEvent) bool { | ||
| return true | ||
| }, | ||
| UpdateFunc: func(e event.UpdateEvent) bool { | ||
| return false | ||
| }, | ||
| DeleteFunc: func(e event.DeleteEvent) bool { | ||
| return false | ||
| }, | ||
| GenericFunc: func(e event.GenericEvent) bool { | ||
| return false | ||
| }, |
There was a problem hiding this comment.
| CreateFunc: func(e event.CreateEvent) bool { | |
| return true | |
| }, | |
| UpdateFunc: func(e event.UpdateEvent) bool { | |
| return false | |
| }, | |
| DeleteFunc: func(e event.DeleteEvent) bool { | |
| return false | |
| }, | |
| GenericFunc: func(e event.GenericEvent) bool { | |
| return false | |
| }, | |
| UpdateFunc: func(e event.UpdateEvent) bool { | |
| return false | |
| }, | |
| GenericFunc: func(e event.GenericEvent) bool { | |
| return false | |
| }, |
This should trigger on create and delete events. Omitting the XFunc fields yields the default, which is true.
| // Watches enqueues member of subinterfaces when their parent interface changes. | ||
| Watches( | ||
| &v1alpha1.Interface{}, | ||
| handler.EnqueueRequestsFromMapFunc(r.physicalToSubinterfaces), |
There was a problem hiding this comment.
| handler.EnqueueRequestsFromMapFunc(r.physicalToSubinterfaces), | |
| handler.EnqueueRequestsFromMapFunc(r.parentToSubinterfaces), |
Again, this is not only physical interfaces (but also aggregates).
| Reason: v1alpha1.ParentInterfaceNotReadyReason, | ||
| Message: fmt.Sprintf("referenced parent interface %q for not found", key), | ||
| }) | ||
| return ctrl.Result{RequeueAfter: 0}, reconcile.TerminalError(fmt.Errorf("failed to get parent interface %q: %w", s.Interface.Spec.ParentInterfaceRef.Name, err)) |
There was a problem hiding this comment.
| return ctrl.Result{RequeueAfter: 0}, reconcile.TerminalError(fmt.Errorf("failed to get parent interface %q: %w", s.Interface.Spec.ParentInterfaceRef.Name, err)) | |
| return ctrl.Result{}, reconcile.TerminalError(fmt.Errorf("failed to get parent interface %q: %w", s.Interface.Spec.ParentInterfaceRef.Name, err)) |
The RequeueAfter: 0 should be omitted everywhere in this file.
| conditions.Set(s.Interface, metav1.Condition{ | ||
| Type: v1alpha1.ConfiguredCondition, | ||
| Status: metav1.ConditionFalse, | ||
| Reason: v1alpha1.ParentInterfaceNotReadyReason, |
There was a problem hiding this comment.
| Reason: v1alpha1.ParentInterfaceNotReadyReason, | |
| Reason: v1alpha1.ParentInterfaceNotFoundReason, |
I think this should be it's own reason.
| } | ||
| } | ||
|
|
||
| var parentInterfaceRef *v1alpha1.Interface |
There was a problem hiding this comment.
| var parentInterfaceRef *v1alpha1.Interface | |
| var parentInterface *v1alpha1.Interface |
This is not a ref. So this naming is a bit misleading.
| Encap string `json:"encap"` | ||
| AdminSt AdminSt2 `json:"adminSt,omitempty"` | ||
| Descr string `json:"descr"` | ||
| } |
There was a problem hiding this comment.
Missing fields:
| } | |
| Medium Medium `json:"mediumType"` | |
| RtvrfMbrItems *VrfMember `json:"rtvrfMbr-items,omitempty"` |
| ethernetRe = regexp.MustCompile(`(?i)^(ethernet|eth)(\d+/\d+)$`) | ||
| loopbackRe = regexp.MustCompile(`(?i)^(loopback|lo)(\d+)$`) | ||
| portchannelRe = regexp.MustCompile(`(?i)^(port-channel|po)(\d+)$`) | ||
| subinterfaceRe = regexp.MustCompile(`(?i)^(ethernet|eth)(\d+/\d+)\.(\d+)$`) |
There was a problem hiding this comment.
Should also allow port-channel subinterfaces.
Might also rename this to encapRoutedRe in accordance with the struct.
| } | ||
|
|
||
| v := "vlan-" + strconv.FormatInt(int64(req.Interface.Spec.Encapsulation.Tag), 10) | ||
| s.Encap = v |
There was a problem hiding this comment.
Something like this would be missing for the missing fields:
| s.Encap = v | |
| if req.IPv4 != nil { | |
| s.RtvrfMbrItems = NewVrfMember(name, vrf) | |
| } | |
| s.Medium = MediumBroadcast | |
| if isPointToPoint(req.Interface.Spec.IPv4) { | |
| s.Medium = MediumPointToPoint | |
| } |
| v := "vlan-" + strconv.FormatInt(int64(req.Interface.Spec.Encapsulation.Tag), 10) | ||
| s.Encap = v |
There was a problem hiding this comment.
| v := "vlan-" + strconv.FormatInt(int64(req.Interface.Spec.Encapsulation.Tag), 10) | |
| s.Encap = v | |
| s.Encap = "vlan-" + strconv.FormatInt(int64(req.Interface.Spec.Encapsulation.Tag), 10) |
No point in creating the variable first. Also, should this be a switch statement on the encap type? And what happens for QinQ subinterfaces?
There was a problem hiding this comment.
These test files also have a golden file with the cli command producing this as {$filename}.txt:
interface eth1/1.100
encapsulation dot1q 100
Implement basic CRUD operations for SubInterfaces: * Validate that the parent interface exists and is in a configured state before applying subinterface; halt reconciliation otherwise * Ensure parent interface is Layer 3 (no switchport configuration) * Watch parent interface for create/update events to trigger reconciliation when it becomes available * Cascade deletion: removing the parent interface also deletes associated subinterfaces To support the cascading deletion of interfaces, we set owner reference on subinterface to parent interface. Omitting device owner reference on subinterface as this blocks deletion until device gets deleted.
95eaba0 to
e37cd2e
Compare
Merging this branch will decrease overall coverage
Coverage by fileChanged files (no unit tests)
Please note that the "Total", "Covered", and "Missed" counts above refer to code statements instead of lines of code. The value in brackets refers to the test coverage of that file in the old version of the code. Changed unit test files
|
Implement basic CRUD for SubInterface resources:
halt reconciliation otherwise
To support the cascading deletion of interfaces, we set owner reference on subinterface to parent
interface. Omitting device owner reference on subinterface as this
blocks deletion until device gets deleted.