Skip to content

Commit 0690313

Browse files
Add PrefixSet resource and controller
1 parent 9dc65df commit 0690313

23 files changed

+1458
-28
lines changed

PROJECT

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,4 +187,12 @@ resources:
187187
kind: EVPNInstance
188188
path: github.com/ironcore-dev/network-operator/api/core/v1alpha1
189189
version: v1alpha1
190+
- api:
191+
crdVersion: v1
192+
namespaced: true
193+
controller: true
194+
domain: networking.metal.ironcore.dev
195+
kind: PrefixSet
196+
path: github.com/ironcore-dev/network-operator/api/core/v1alpha1
197+
version: v1alpha1
190198
version: "3"

Tiltfile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,9 @@ k8s_resource(new_name='vlan-10', objects=['vlan-10:vlan'], trigger_mode=TRIGGER_
105105
k8s_yaml('./config/samples/v1alpha1_evi.yaml')
106106
k8s_resource(new_name='vxlan-100010', objects=['vxlan-100010:evpninstance'], resource_deps=['vlan-10'], trigger_mode=TRIGGER_MODE_MANUAL, auto_init=False)
107107

108+
k8s_yaml('./config/samples/v1alpha1_prefixset.yaml')
109+
k8s_resource(new_name='ccloud-prefixset', objects=['ccloud-prefixset:prefixset'], trigger_mode=TRIGGER_MODE_MANUAL, auto_init=False)
110+
108111
print('🚀 network-operator development environment')
109112
print('👉 Edit the code inside the api/, cmd/, or internal/ directories')
110113
print('👉 Tilt will automatically rebuild and redeploy when changes are detected')
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
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+
)
9+
10+
// PrefixSetSpec defines the desired state of PrefixSet
11+
type PrefixSetSpec struct {
12+
// DeviceName is the name of the Device this object belongs to. The Device object must exist in the same namespace.
13+
// Immutable.
14+
// +required
15+
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="DeviceRef is immutable"
16+
DeviceRef LocalObjectReference `json:"deviceRef"`
17+
18+
// ProviderConfigRef is a reference to a resource holding the provider-specific configuration of this interface.
19+
// This reference is used to link the Banner to its provider-specific configuration.
20+
// +optional
21+
ProviderConfigRef *TypedLocalObjectReference `json:"providerConfigRef,omitempty"`
22+
23+
// Name is the name of the PrefixSet.
24+
// Immutable.
25+
// +required
26+
// +kubebuilder:validation:MinLength=1
27+
// +kubebuilder:validation:MaxLength=32
28+
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="Name is immutable"
29+
Name string `json:"name"`
30+
31+
// A list of entries to apply.
32+
// The address families (IPv4, IPv6) of all prefixes in the list must match.
33+
// +required
34+
// +listType=map
35+
// +listMapKey=sequence
36+
// +kubebuilder:validation:MinItems=1
37+
// +kubebuilder:validation:MaxItems=100
38+
Entries []PrefixEntry `json:"entries"`
39+
}
40+
41+
type PrefixEntry struct {
42+
// The sequence number of the Prefix entry.
43+
// +required
44+
// +kubebuilder:validation:Minimum=1
45+
Sequence int32 `json:"sequence"`
46+
47+
// IP prefix. Can be IPv4 or IPv6.
48+
// Use 0.0.0.0/0 (::/0) to represent 'any'.
49+
// +required
50+
Prefix IPPrefix `json:"prefix"`
51+
52+
// Optional mask length range for the prefix.
53+
// If not specified, only the exact prefix length is matched.
54+
// +optional
55+
MaskLengthRange *MaskLengthRange `json:"maskLengthRange,omitempty"`
56+
}
57+
58+
type MaskLengthRange struct {
59+
// Minimum mask length.
60+
// +required
61+
// +kubebuilder:validation:Minimum=0
62+
// +kubebuilder:validation:Maximum=128
63+
Min int8 `json:"min"`
64+
65+
// Maximum mask length.
66+
// +required
67+
// +kubebuilder:validation:Minimum=0
68+
// +kubebuilder:validation:Maximum=128
69+
Max int8 `json:"max"`
70+
}
71+
72+
// PrefixSetStatus defines the observed state of PrefixSet.
73+
type PrefixSetStatus struct {
74+
// The conditions are a list of status objects that describe the state of the PrefixSet.
75+
//+listType=map
76+
//+listMapKey=type
77+
//+patchStrategy=merge
78+
//+patchMergeKey=type
79+
//+optional
80+
Conditions []metav1.Condition `json:"conditions,omitempty"`
81+
}
82+
83+
// +kubebuilder:object:root=true
84+
// +kubebuilder:subresource:status
85+
// +kubebuilder:resource:path=prefixsets
86+
// +kubebuilder:resource:singular=prefixset
87+
// +kubebuilder:printcolumn:name="Device",type=string,JSONPath=`.spec.deviceRef.name`
88+
// +kubebuilder:printcolumn:name="Ready",type=string,JSONPath=`.status.conditions[?(@.type=="Ready")].status`
89+
// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp"
90+
91+
// PrefixSet is the Schema for the prefixsets API
92+
type PrefixSet struct {
93+
metav1.TypeMeta `json:",inline"`
94+
metav1.ObjectMeta `json:"metadata,omitempty"`
95+
96+
// Specification of the desired state of the resource.
97+
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
98+
// +required
99+
Spec PrefixSetSpec `json:"spec,omitempty"`
100+
101+
// Status of the resource. This is set and updated automatically.
102+
// Read-only.
103+
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
104+
// +optional
105+
Status PrefixSetStatus `json:"status,omitzero"`
106+
}
107+
108+
// GetConditions implements conditions.Getter.
109+
func (p *PrefixSet) GetConditions() []metav1.Condition {
110+
return p.Status.Conditions
111+
}
112+
113+
// SetConditions implements conditions.Setter.
114+
func (p *PrefixSet) SetConditions(conditions []metav1.Condition) {
115+
p.Status.Conditions = conditions
116+
}
117+
118+
// Is4 reports whether entries of the PrefixSet are IPv4 addresses.
119+
func (p *PrefixSet) Is4() bool {
120+
// Note: We can safely check only the first entry because
121+
// validation ensures all entries are of the same IP family.
122+
return len(p.Spec.Entries) > 0 && p.Spec.Entries[0].Prefix.Addr().Is4()
123+
}
124+
125+
// Is6 reports whether entries of the PrefixSet are IPv6 addresses.
126+
func (p *PrefixSet) Is6() bool {
127+
// Note: We can safely check only the first entry because
128+
// validation ensures all entries are of the same IP family.
129+
return len(p.Spec.Entries) > 0 && p.Spec.Entries[0].Prefix.Addr().Is6()
130+
}
131+
132+
// +kubebuilder:object:root=true
133+
134+
// PrefixSetList contains a list of PrefixSet
135+
type PrefixSetList struct {
136+
metav1.TypeMeta `json:",inline"`
137+
metav1.ListMeta `json:"metadata,omitzero"`
138+
Items []PrefixSet `json:"items"`
139+
}
140+
141+
func init() {
142+
SchemeBuilder.Register(&PrefixSet{}, &PrefixSetList{})
143+
}

api/core/v1alpha1/zz_generated.deepcopy.go

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

0 commit comments

Comments
 (0)