Skip to content

Commit 503c21c

Browse files
committed
feat: define CRDs for VRF type
In this commit we define VRF type. A VRF is composed by a single route distinguisher (RD), and a set of route targets (RTs). Each route target is composed by the address families it affects, an action for it (e.g., import or export). The ipv4-evpn and ipv6-evpn will apply the route target actions to the EVPN context.
1 parent bdc24c5 commit 503c21c

16 files changed

+802
-107
lines changed

PROJECT

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,13 @@ resources:
2828
kind: Device
2929
path: github.com/ironcore-dev/network-operator/api/v1alpha1
3030
version: v1alpha1
31+
- api:
32+
crdVersion: v1
33+
namespaced: true
34+
controller: true
35+
domain: cloud.sap
36+
group: networking
37+
kind: VRF
38+
path: github.com/ironcore-dev/network-operator/api/v1alpha1
39+
version: v1alpha1
3140
version: "3"

api/v1alpha1/vrf_types.go

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
// SPDX-FileCopyrightText: 2025 SAP SE or an SAP affiliate company and IronCore contributors
2+
// SPDX-License-Identifier: Apache-2.0
3+
4+
package v1alpha1
5+
6+
import (
7+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
8+
ctrl "sigs.k8s.io/controller-runtime"
9+
)
10+
11+
// has a single Route Distinguisher (RD) and a set of Route Targets (RT). RTs control the import and export of routes
12+
// VRFSpec defines the basic structure of a Virtual Routing and Forwarding (VRF) instance/context. A single VRF instance
13+
// among different VRFs.
14+
type VRFSpec struct {
15+
// DeviceName is a ref to the device owning this VRF. Device must exist in the same namespace as the VRF.
16+
//
17+
// +required
18+
// +kubebuilder:validation:MinLength=1
19+
// +kubebuilder:validation:MaxLength=63
20+
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="deviceName is immutable"
21+
DeviceName string `json:"deviceName,omitempty"`
22+
23+
// Name defines the name of the VRF.
24+
//
25+
// +required
26+
// +kubebuilder:validation:MaxLength=32
27+
// +kubebuilder:validation:MinLength=1
28+
// +kubebuilder:validation:Pattern=`^[a-zA-Z0-9]+$`
29+
Name *string `json:"name,omitempty"`
30+
31+
// AdminState defines the administrative state of the VRF.
32+
//
33+
// +required
34+
// +kubebuilder:validation:Enum=Up;Down
35+
AdminState *AdminState `json:"adminState,omitempty"`
36+
37+
// RD defines the Route Distinguisher (RD) for the VRF as per RFC 4364
38+
//
39+
// +kubebuilder:validation:Pattern=`^([0-9]+:[0-9]+|([0-9]{1,3}\.){3}[0-9]{1,3}:[0-9]+)$`
40+
// +required
41+
RD *string `json:"routeDistinguisher,omitempty"`
42+
43+
// RTs defines the list of Route Targets (RTs) associated with the VRF.
44+
//
45+
// +optional
46+
RTs []RouteTarget `json:"routeTargets,omitempty"`
47+
48+
// TODO(nikatza): Discuss in weekly, depends on #30
49+
// ProviderConfigRef is a reference to a resource holding the provider-specific configuration of this VRF
50+
// (e.g., a layer-3 VNI on cisco).
51+
//
52+
// +optional
53+
// ProviderConfigRef *any `json:"providerConfigRef,omitempty"` // TODO: any is a placeholder until we discuss #30
54+
}
55+
56+
// VRFStatus defines the observed state of VRF.
57+
type VRFStatus struct {
58+
// The conditions are a list of status objects that describe the state of the D.
59+
// +listType=map
60+
// +listMapKey=type
61+
// +patchStrategy=merge
62+
// +patchMergeKey=type
63+
// +optional
64+
Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type"`
65+
}
66+
67+
// +kubebuilder:object:root=true
68+
// +kubebuilder:subresource:status
69+
// +kubebuilder:resource:path=vrfs
70+
// +kubebuilder:resource:singular=vrf
71+
// +kubebuilder:resource:shortName=vrf
72+
// +kubebuilder:printcolumn:name="VRF",type=string,JSONPath=`.spec.name`
73+
// +kubebuilder:printcolumn:name="Admin State",type=string,JSONPath=`.spec.adminState`
74+
// +kubebuilder:printcolumn:name="Device",type=string,JSONPath=`.spec.deviceName`
75+
// +kubebuilder:printcolumn:name="Ready",type=string,JSONPath=`.status.conditions[?(@.type=="Ready")].status`
76+
// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp"
77+
//
78+
// VRF is the Schema for the VRFs API
79+
type VRF struct {
80+
metav1.TypeMeta `json:",inline"`
81+
metav1.ObjectMeta `json:"metadata,omitempty,omitzero"`
82+
83+
Spec VRFSpec `json:"spec,omitempty"`
84+
Status VRFStatus `json:"status,omitempty"`
85+
}
86+
87+
// +kubebuilder:object:root=true
88+
89+
// VRFList contains a list of VRF
90+
type VRFList struct {
91+
metav1.TypeMeta `json:",inline"`
92+
metav1.ListMeta `json:"metadata,omitempty"`
93+
Items []VRF `json:"items"`
94+
}
95+
96+
// RouteTarget defines the structure for a single route target in a VRF. A RT is essentially an extended BGP
97+
// community used to control route import/export between VRFs. RTs may be also be associated with address
98+
// families (IPv4, IPv6), and might be also added to the EVPN via the ipv4-evpn and ipv6-evpn address families.
99+
type RouteTarget struct {
100+
// Value specifies the Route Target (RT) value as per RFC 4364.
101+
//
102+
// +kubebuilder:validation:Pattern=`^([0-9]+:[0-9]+|([0-9]{1,3}\.){3}[0-9]{1,3}:[0-9]+)$`
103+
Value string `json:"value,omitempty"`
104+
105+
// AddressFamily specifies the address families for the Route Target. Families ipv4-evpn and ipv6-evpn indicate
106+
// that the RT should be applied to the EVPN contexts (see RFC 7432).
107+
//
108+
// +kubebuilder:validation:MinItems=1
109+
AddressFamilies []AddressFamily `json:"addressFamilies,omitempty"`
110+
111+
// Action specifies how this RT should be used within the VRF.
112+
//
113+
// +kubebuilder:validation:Enum=none;import;export;both
114+
Action RTAction `json:"action,omitempty"`
115+
}
116+
117+
// +kubebuilder:validation:Enum=ipv4;ipv6;ipv4-evpn;ipv6-evpn
118+
type AddressFamily string
119+
120+
const (
121+
AddressFamilyIPv4 AddressFamily = "ipv4"
122+
AddressFamilyIPv6 AddressFamily = "ipv6"
123+
AddressFamilyIPv4EVPN AddressFamily = "ipv4-evpn"
124+
AddressFamilyIPv6EVPN AddressFamily = "ipv6-evpn"
125+
)
126+
127+
type RTAction string
128+
129+
const (
130+
RTNone RTAction = "none"
131+
RTImport RTAction = "import"
132+
RTExport RTAction = "export"
133+
RTBoth RTAction = "both"
134+
)
135+
136+
func init() {
137+
SchemeBuilder.Register(&VRF{}, &VRFList{})
138+
}
139+
140+
func (r *VRF) SetupWebhookWithManager(mgr ctrl.Manager) error {
141+
return ctrl.NewWebhookManagedBy(mgr).
142+
For(r).
143+
Complete()
144+
}

api/v1alpha1/zz_generated.deepcopy.go

Lines changed: 138 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

config/crd/bases/networking.cloud.sap_devices.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
33
kind: CustomResourceDefinition
44
metadata:
55
annotations:
6-
controller-gen.kubebuilder.io/version: v0.18.0
6+
controller-gen.kubebuilder.io/version: v0.19.0
77
name: devices.networking.cloud.sap
88
spec:
99
group: networking.cloud.sap

config/crd/bases/networking.cloud.sap_interfaces.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1
33
kind: CustomResourceDefinition
44
metadata:
55
annotations:
6-
controller-gen.kubebuilder.io/version: v0.18.0
6+
controller-gen.kubebuilder.io/version: v0.19.0
77
name: interfaces.networking.cloud.sap
88
spec:
99
group: networking.cloud.sap

0 commit comments

Comments
 (0)