Skip to content

Commit d3f7f4b

Browse files
Add ManagementAccess resource and controller
1 parent 7d46274 commit d3f7f4b

22 files changed

+1126
-471
lines changed

PROJECT

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,4 +100,13 @@ resources:
100100
kind: Syslog
101101
path: github.com/ironcore-dev/network-operator/api/v1alpha1
102102
version: v1alpha1
103+
- api:
104+
crdVersion: v1
105+
namespaced: true
106+
controller: true
107+
domain: cloud.sap
108+
group: networking
109+
kind: ManagementAccess
110+
path: github.com/ironcore-dev/network-operator/api/v1alpha1
111+
version: v1alpha1
103112
version: "3"

Tiltfile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,9 @@ k8s_resource(new_name='snmp', objects=['snmp:snmp'], trigger_mode=TRIGGER_MODE_M
5858
k8s_yaml('./config/samples/v1alpha1_syslog.yaml')
5959
k8s_resource(new_name='syslog', objects=['syslog:syslog'], trigger_mode=TRIGGER_MODE_MANUAL, auto_init=False)
6060

61+
k8s_yaml('./config/samples/v1alpha1_managementaccess.yaml')
62+
k8s_resource(new_name='managementaccess', objects=['managementaccess:managementaccess'], trigger_mode=TRIGGER_MODE_MANUAL, auto_init=False)
63+
6164
print('🚀 network-operator development environment')
6265
print('👉 Edit the code inside the api/, cmd/, or internal/ directories')
6366
print('👉 Tilt will automatically rebuild and redeploy when changes are detected')

api/v1alpha1/device_types.go

Lines changed: 0 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,6 @@ type DeviceSpec struct {
1818
// It can be used to provide initial configuration templates or scripts that are applied during the device provisioning.
1919
// +optional
2020
Bootstrap *Bootstrap `json:"bootstrap,omitempty"`
21-
22-
// Configuration for the gRPC server on the device.
23-
// Currently, only a single "default" gRPC server is supported.
24-
// +optional
25-
GRPC *GRPC `json:"grpc,omitempty"`
2621
}
2722

2823
type Endpoint struct {
@@ -59,63 +54,6 @@ type Bootstrap struct {
5954
Template *TemplateSource `json:"template"`
6055
}
6156

62-
type GRPC struct {
63-
// The TCP port on which the gRPC server should listen.
64-
// The range of port-id is from 1024 to 65535.
65-
// Port 9339 is the default.
66-
// +kubebuilder:validation:Minimum=1024
67-
// +kubebuilder:validation:Maximum=65535
68-
// +kubebuilder:validation:ExclusiveMaximum=false
69-
// +kubebuilder:default=9339
70-
// +optional
71-
Port int32 `json:"port"`
72-
73-
// Name of the certificate that is associated with the gRPC service.
74-
// The certificate is provisioned through other interfaces on the device,
75-
// such as e.g. the gNOI certificate management service.
76-
// +optional
77-
CertificateID string `json:"certificateId,omitempty"`
78-
79-
// Enable the gRPC agent to accept incoming (dial-in) RPC requests from a given network instance.
80-
// +optional
81-
NetworkInstance string `json:"networkInstance,omitempty"`
82-
83-
// Additional gNMI configuration for the gRPC server.
84-
// This may not be supported by all devices.
85-
// +optional
86-
GNMI *GNMI `json:"gnmi,omitempty"`
87-
}
88-
89-
type GNMI struct {
90-
// The maximum number of concurrent gNMI calls that can be made to the gRPC server on the switch for each VRF.
91-
// Configure a limit from 1 through 16. The default limit is 8.
92-
// +kubebuilder:validation:Minimum=1
93-
// +kubebuilder:validation:Maximum=16
94-
// +kubebuilder:validation:ExclusiveMaximum=false
95-
// +kubebuilder:default=8
96-
// +optional
97-
MaxConcurrentCall int8 `json:"maxConcurrentCall"`
98-
99-
// Configure the keepalive timeout for inactive or unauthorized connections.
100-
// The gRPC agent is expected to periodically send an empty response to the client, on which the client is expected to respond with an empty request.
101-
// If the client does not respond within the keepalive timeout, the gRPC agent should close the connection.
102-
// The default interval value is 10 minutes.
103-
// +kubebuilder:validation:Type=string
104-
// +kubebuilder:validation:Pattern="^([0-9]+(\\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$"
105-
// +kubebuilder:default="10m"
106-
// +optional
107-
KeepAliveTimeout metav1.Duration `json:"keepAliveTimeout"`
108-
109-
// Configure the minimum sample interval for the gNMI telemetry stream.
110-
// Once per stream sample interval, the switch sends the current values for all specified paths.
111-
// The default value is 10 seconds.
112-
// +kubebuilder:validation:Type=string
113-
// +kubebuilder:validation:Pattern="^([0-9]+(\\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$"
114-
// +kubebuilder:default="10s"
115-
// +optional
116-
MinSampleInterval metav1.Duration `json:"minSampleInterval"`
117-
}
118-
11957
// TemplateSource defines a source for template content.
12058
// It can be provided inline, or as a reference to a Secret or ConfigMap.
12159
//
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
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+
// ManagementAccessSpec defines the desired state of ManagementAccess
11+
type ManagementAccessSpec 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 Interface to its provider-specific configuration.
20+
// +optional
21+
ProviderConfigRef *TypedLocalObjectReference `json:"providerConfigRef,omitempty"`
22+
23+
// Configuration for the gRPC server on the device.
24+
// Currently, only a single "default" gRPC server is supported.
25+
// +optional
26+
// +kubebuilder:default={enabled:true, port:9339}
27+
GRPC GRPC `json:"grpc,omitempty"`
28+
}
29+
30+
type GRPC struct {
31+
// Enable or disable the gRPC server on the device.
32+
// If not specified, the gRPC server is enabled by default.
33+
// +optional
34+
// +kubebuilder:default=true
35+
Enabled bool `json:"enabled"`
36+
37+
// The TCP port on which the gRPC server should listen.
38+
// The range of port-id is from 1024 to 65535.
39+
// Port 9339 is the default.
40+
// +optional
41+
// +kubebuilder:default=9339
42+
// +kubebuilder:validation:Minimum=1024
43+
// +kubebuilder:validation:Maximum=65535
44+
// +kubebuilder:validation:ExclusiveMaximum=false
45+
Port int32 `json:"port"`
46+
47+
// Name of the certificate that is associated with the gRPC service.
48+
// The certificate is provisioned through other interfaces on the device,
49+
// such as e.g. the gNOI certificate management service.
50+
// +optional
51+
// +kubebuilder:validation:MinLength=1
52+
// +kubebuilder:validation:MaxLength=63
53+
CertificateID string `json:"certificateId,omitempty"`
54+
55+
// Enable the gRPC agent to accept incoming (dial-in) RPC requests from a given vrf.
56+
// +optional
57+
// +kubebuilder:default="default"
58+
// +kubebuilder:validation:MinLength=1
59+
// +kubebuilder:validation:MaxLength=63
60+
VrfName string `json:"vrfName"`
61+
62+
// Additional gNMI configuration for the gRPC server.
63+
// This may not be supported by all devices.
64+
// +optional
65+
// +kubebuilder:default={maxConcurrentCall:8, keepAliveTimeout:"10m", minSampleInterval:"10s"}
66+
GNMI GNMI `json:"gnmi,omitzero"`
67+
}
68+
69+
type GNMI struct {
70+
// The maximum number of concurrent gNMI calls that can be made to the gRPC server on the switch for each VRF.
71+
// Configure a limit from 1 through 16. The default limit is 8.
72+
// +optional
73+
// +kubebuilder:default=8
74+
// +kubebuilder:validation:Minimum=1
75+
// +kubebuilder:validation:Maximum=16
76+
// +kubebuilder:validation:ExclusiveMaximum=false
77+
MaxConcurrentCall int8 `json:"maxConcurrentCall"`
78+
79+
// Configure the keepalive timeout for inactive or unauthorized connections.
80+
// The gRPC agent is expected to periodically send an empty response to the client, on which the client is expected to respond with an empty request.
81+
// If the client does not respond within the keepalive timeout, the gRPC agent should close the connection.
82+
// The default interval value is 10 minutes.
83+
// +optional
84+
// +kubebuilder:default="10m"
85+
// +kubebuilder:validation:Type=string
86+
// +kubebuilder:validation:Pattern="^([0-9]+(\\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$"
87+
KeepAliveTimeout metav1.Duration `json:"keepAliveTimeout"`
88+
89+
// Configure the minimum sample interval for the gNMI telemetry stream.
90+
// Once per stream sample interval, the switch sends the current values for all specified paths.
91+
// The default value is 10 seconds.
92+
// +kubebuilder:validation:Type=string
93+
// +kubebuilder:validation:Pattern="^([0-9]+(\\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$"
94+
// +kubebuilder:default="10s"
95+
MinSampleInterval metav1.Duration `json:"minSampleInterval"`
96+
}
97+
98+
// ManagementAccessStatus defines the observed state of ManagementAccess.
99+
type ManagementAccessStatus struct {
100+
// The conditions are a list of status objects that describe the state of the ManagementAccess.
101+
//+listType=map
102+
//+listMapKey=type
103+
//+patchStrategy=merge
104+
//+patchMergeKey=type
105+
//+optional
106+
Conditions []metav1.Condition `json:"conditions,omitempty"`
107+
}
108+
109+
// +kubebuilder:object:root=true
110+
// +kubebuilder:subresource:status
111+
// +kubebuilder:resource:path=managementaccesses
112+
// +kubebuilder:resource:singular=managementaccess
113+
// +kubebuilder:printcolumn:name="Device",type=string,JSONPath=`.spec.deviceName`
114+
// +kubebuilder:printcolumn:name="Ready",type=string,JSONPath=`.status.conditions[?(@.type=="Ready")].status`
115+
// +kubebuilder:printcolumn:name="Age",type="date",JSONPath=".metadata.creationTimestamp"
116+
117+
// ManagementAccess is the Schema for the managementaccesses API
118+
type ManagementAccess struct {
119+
metav1.TypeMeta `json:",inline"`
120+
metav1.ObjectMeta `json:"metadata,omitempty"`
121+
122+
// Specification of the desired state of the resource.
123+
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
124+
// +required
125+
Spec ManagementAccessSpec `json:"spec,omitempty"`
126+
127+
// Status of the resource. This is set and updated automatically.
128+
// Read-only.
129+
// More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
130+
// +optional
131+
Status ManagementAccessStatus `json:"status,omitempty,omitzero"`
132+
}
133+
134+
// +kubebuilder:object:root=true
135+
136+
// ManagementAccessList contains a list of ManagementAccess
137+
type ManagementAccessList struct {
138+
metav1.TypeMeta `json:",inline"`
139+
metav1.ListMeta `json:"metadata,omitempty"`
140+
Items []ManagementAccess `json:"items"`
141+
}
142+
143+
func init() {
144+
SchemeBuilder.Register(&ManagementAccess{}, &ManagementAccessList{})
145+
}

api/v1alpha1/zz_generated.deepcopy.go

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

cmd/main.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,17 @@ func main() {
314314
setupLog.Error(err, "unable to create controller", "controller", "Syslog")
315315
os.Exit(1)
316316
}
317+
318+
if err := (&controller.ManagementAccessReconciler{
319+
Client: mgr.GetClient(),
320+
Scheme: mgr.GetScheme(),
321+
Recorder: mgr.GetEventRecorderFor("managementaccess-controller"),
322+
WatchFilterValue: watchFilterValue,
323+
Provider: prov,
324+
}).SetupWithManager(mgr); err != nil {
325+
setupLog.Error(err, "unable to create controller", "controller", "ManagementAccess")
326+
os.Exit(1)
327+
}
317328
// +kubebuilder:scaffold:builder
318329

319330
if metricsCertWatcher != nil {

0 commit comments

Comments
 (0)