From 2ab090db3136bb96e2d7d36acdd261c3f9f6fc3e Mon Sep 17 00:00:00 2001 From: Adam Trizuljak Date: Thu, 3 Sep 2026 10:22:44 +0200 Subject: [PATCH 1/4] Implement NTP Openconfig provider - Add OpenConfig provider implementation for the NTP resource (`internal/provider/openconfig/ntp.go`) and a gnmi testdata file (`test/gnmi/testdata/openconfig/ntp.txtar`) - Get the IP address of the `NTPSpec.SourceInterface` from the device using the GRPC client and use it to populate the `source-address` field in Openconfig - Add a simple Containerlab setup with one SRLinux node + the associated network-operator `NTP` resource If the management interface is used for NTP we can't obtain the address from an `Interface` resource, because we don't create such resource for the management interface. Therefore the provider reads the interface state directly from the device over GRPC and uses its IP address to populate the `source-address` field. Signed-off-by: Adam Trizuljak --- Tiltfile | 3 + api/core/v1alpha1/ntp_types.go | 1 + .../ntp.networking.metal.ironcore.dev.yaml | 5 +- .../networking.metal.ironcore.dev_ntp.yaml | 5 +- docs/api-reference/index.md | 2 +- examples/openconfig-containerlab/.gitignore | 1 + .../01-devices/v1alpha1-leaf1-clab-ntp.yaml | 19 ++ .../openconfig-containerlab/topology.clab.yml | 14 ++ internal/provider/openconfig/interface.go | 25 +++ internal/provider/openconfig/ntp.go | 91 +++++++++ test/gnmi/testdata/openconfig/ntp.txtar | 191 ++++++++++++++++++ 11 files changed, 352 insertions(+), 5 deletions(-) create mode 100644 examples/openconfig-containerlab/.gitignore create mode 100644 examples/openconfig-containerlab/kubernetes/01-devices/v1alpha1-leaf1-clab-ntp.yaml create mode 100644 examples/openconfig-containerlab/topology.clab.yml create mode 100644 internal/provider/openconfig/ntp.go create mode 100644 test/gnmi/testdata/openconfig/ntp.txtar diff --git a/Tiltfile b/Tiltfile index 75a8f3a23..4b0140ab7 100644 --- a/Tiltfile +++ b/Tiltfile @@ -207,6 +207,9 @@ k8s_resource(new_name='mac-entry', objects=['mac-entry:probe'], trigger_mode=TRI k8s_resource(new_name='route-prefix', objects=['route-prefix:probe'], trigger_mode=TRIGGER_MODE_MANUAL, auto_init=False, labels=['samples']) k8s_resource(new_name='vtep-peers', objects=['vtep-peers:probe'], trigger_mode=TRIGGER_MODE_MANUAL, auto_init=False, labels=['samples']) +k8s_yaml('./examples/openconfig-containerlab/kubernetes/01-devices/v1alpha1-leaf1-clab-ntp.yaml') +k8s_resource(new_name='ntp-clab', objects=['ntp-clab:ntp'], trigger_mode=TRIGGER_MODE_MANUAL, auto_init=False, labels=['containerlab']) + print('🚀 network-operator development environment') print('👉 Edit the code inside the api/, cmd/, or internal/ directories') print('👉 Tilt will automatically rebuild and redeploy when changes are detected') diff --git a/api/core/v1alpha1/ntp_types.go b/api/core/v1alpha1/ntp_types.go index f6ffaddc9..74a0b5287 100644 --- a/api/core/v1alpha1/ntp_types.go +++ b/api/core/v1alpha1/ntp_types.go @@ -56,6 +56,7 @@ type NTPServer struct { Prefer bool `json:"prefer,omitempty"` // The name of the vrf used to communicate with the NTP server. + // Maps to network-instance in Openconfig // +optional // +kubebuilder:validation:MinLength=1 // +kubebuilder:validation:MaxLength=63 diff --git a/charts/network-operator/templates/crd/ntp.networking.metal.ironcore.dev.yaml b/charts/network-operator/templates/crd/ntp.networking.metal.ironcore.dev.yaml index caf783013..c862c4c56 100644 --- a/charts/network-operator/templates/crd/ntp.networking.metal.ironcore.dev.yaml +++ b/charts/network-operator/templates/crd/ntp.networking.metal.ironcore.dev.yaml @@ -140,8 +140,9 @@ spec: or not. type: boolean vrfName: - description: The name of the vrf used to communicate with the - NTP server. + description: |- + The name of the vrf used to communicate with the NTP server. + Maps to network-instance in Openconfig maxLength: 63 minLength: 1 type: string diff --git a/config/crd/bases/networking.metal.ironcore.dev_ntp.yaml b/config/crd/bases/networking.metal.ironcore.dev_ntp.yaml index 184698a73..5b932c59a 100644 --- a/config/crd/bases/networking.metal.ironcore.dev_ntp.yaml +++ b/config/crd/bases/networking.metal.ironcore.dev_ntp.yaml @@ -137,8 +137,9 @@ spec: or not. type: boolean vrfName: - description: The name of the vrf used to communicate with the - NTP server. + description: |- + The name of the vrf used to communicate with the NTP server. + Maps to network-instance in Openconfig maxLength: 63 minLength: 1 type: string diff --git a/docs/api-reference/index.md b/docs/api-reference/index.md index ed271ca0e..3ee77c5cf 100644 --- a/docs/api-reference/index.md +++ b/docs/api-reference/index.md @@ -2890,7 +2890,7 @@ _Appears in:_ | --- | --- | --- | --- | | `address` _string_ | Hostname/IP address of the NTP server. | | MaxLength: 253
MinLength: 1
Required: \{\}
| | `prefer` _boolean_ | Indicates whether this server should be preferred or not. | false | Optional: \{\}
| -| `vrfName` _string_ | The name of the vrf used to communicate with the NTP server. | | MaxLength: 63
MinLength: 1
Optional: \{\}
| +| `vrfName` _string_ | The name of the vrf used to communicate with the NTP server.
Maps to network-instance in Openconfig | | MaxLength: 63
MinLength: 1
Optional: \{\}
| #### NTPSpec diff --git a/examples/openconfig-containerlab/.gitignore b/examples/openconfig-containerlab/.gitignore new file mode 100644 index 000000000..b1411b9a2 --- /dev/null +++ b/examples/openconfig-containerlab/.gitignore @@ -0,0 +1 @@ +clab-nav-srl diff --git a/examples/openconfig-containerlab/kubernetes/01-devices/v1alpha1-leaf1-clab-ntp.yaml b/examples/openconfig-containerlab/kubernetes/01-devices/v1alpha1-leaf1-clab-ntp.yaml new file mode 100644 index 000000000..5bb465ca7 --- /dev/null +++ b/examples/openconfig-containerlab/kubernetes/01-devices/v1alpha1-leaf1-clab-ntp.yaml @@ -0,0 +1,19 @@ +apiVersion: networking.metal.ironcore.dev/v1alpha1 +kind: NTP +metadata: + labels: + app.kubernetes.io/name: network-operator + app.kubernetes.io/managed-by: kustomize + networking.metal.ironcore.dev/device-name: leaf1-clab + name: ntp-clab +spec: + deviceRef: + name: leaf1 + sourceInterfaceName: mgmt0 + servers: + - address: de.pool.ntp.org + prefer: true + vrfName: mgmt + - address: pool.ntp.org + prefer: false + vrfName: mgmt diff --git a/examples/openconfig-containerlab/topology.clab.yml b/examples/openconfig-containerlab/topology.clab.yml new file mode 100644 index 000000000..e2a5f4287 --- /dev/null +++ b/examples/openconfig-containerlab/topology.clab.yml @@ -0,0 +1,14 @@ +name: nav-srl + +topology: + nodes: + leaf1: + kind: nokia_srlinux + image: ghcr.io/nokia/srlinux:26.7.1 + startup-config: |- + system name host-name srl + system aaa authentication admin-user password admin + system grpc-server mgmt yang-models openconfig + ports: + - 8022:22 + - 9339:57400 diff --git a/internal/provider/openconfig/interface.go b/internal/provider/openconfig/interface.go index 6e77112eb..59226fd20 100644 --- a/internal/provider/openconfig/interface.go +++ b/internal/provider/openconfig/interface.go @@ -6,6 +6,7 @@ package openconfig import ( "context" "encoding/json" + "errors" "fmt" "github.com/ironcore-dev/network-operator/api/core/v1alpha1" @@ -664,3 +665,27 @@ type SubinterfaceVlanDoubleTaggedConfig struct { InnerVlanID uint16 `json:"inner-vlan-id,omitempty"` OuterVlanID uint16 `json:"outer-vlan-id,omitempty"` } + +type interfaceAddrs struct { + ifName string + Address gnmiext.List[string, *IPv4Address] `json:"address"` +} + +func (a *interfaceAddrs) XPath() string { + return fmt.Sprintf("openconfig-interfaces:interfaces/interface[name=%s]/subinterfaces/subinterface[index=0]/openconfig-if-ip:ipv4/addresses", a.ifName) +} + +// interfaceIPAddr retrieves the first IPv4 address from the state of the named interface. +func (p *Provider) interfaceIPAddr(ctx context.Context, name string) (string, error) { + addrs := &interfaceAddrs{ifName: name} + if err := p.client.GetState(ctx, addrs); err != nil { + if errors.Is(err, gnmiext.ErrNil) { + return "", apistatus.NewFailedPreconditionError(fmt.Sprintf("interface %q has no IPv4 address A", name)) + } + return "", fmt.Errorf("failed to get IPv4 address for interface %q: %w", name, err) + } + for _, a := range addrs.Address { + return a.IP, nil + } + return "", apistatus.NewFailedPreconditionError(fmt.Sprintf("interface %q has no IPv4 address B", name)) +} diff --git a/internal/provider/openconfig/ntp.go b/internal/provider/openconfig/ntp.go new file mode 100644 index 000000000..8a31c063e --- /dev/null +++ b/internal/provider/openconfig/ntp.go @@ -0,0 +1,91 @@ +// SPDX-FileCopyrightText: 2026 SAP SE or an SAP affiliate company and IronCore contributors +// SPDX-License-Identifier: Apache-2.0 + +package openconfig + +import ( + "context" + + "github.com/ironcore-dev/network-operator/api/core/v1alpha1" + "github.com/ironcore-dev/network-operator/internal/provider" + "github.com/ironcore-dev/network-operator/internal/transport/gnmiext" +) + +var _ provider.NTPProvider = (*Provider)(nil) + +func (p *Provider) EnsureNTP(ctx context.Context, req *provider.EnsureNTPRequest) error { + spec := req.NTP.Spec + + n := &NTP{ + Config: &NTPConfig{ + Enabled: spec.AdminState == v1alpha1.AdminStateUp, + }, + } + + var sourceAddress string + if spec.SourceInterfaceName != "" { + var err error + sourceAddress, err = p.interfaceIPAddr(ctx, spec.SourceInterfaceName) + if err != nil { + return err + } + } + + if len(spec.Servers) > 0 { + n.Servers = &NTPServers{} + for _, s := range spec.Servers { + n.Servers.Server.Set(&NTPServer{ + Address: s.Address, + Config: &NTPServerConfig{ + Address: s.Address, + Prefer: s.Prefer, + NetworkInstance: s.VrfName, + SourceAddress: sourceAddress, + }, + }) + } + } + + return p.client.Update(ctx, n) +} + +func (p *Provider) DeleteNTP(ctx context.Context) error { + return p.client.Delete(ctx, &NTP{}) +} + +// Compile-time assertions. +var _ gnmiext.DataElement = (*NTP)(nil) + +// DNS represents the OpenConfig /system/ntp container. +type NTP struct { + Config *NTPConfig `json:"config"` + Servers *NTPServers `json:"servers"` +} + +func (*NTP) XPath() string { return "openconfig-system:system/ntp" } + +// NTPConfig holds the config container for NTP. +type NTPConfig struct { + Enabled bool `json:"enabled"` +} + +// NTPServers holds the servers container for NTP. +type NTPServers struct { + Server gnmiext.List[string, *NTPServer] `json:"server"` +} + +// NTPServer represents a single NTP server entry. +type NTPServer struct { + Address string `json:"address"` + Config *NTPServerConfig `json:"config"` +} + +func (s *NTPServer) Key() string { return s.Address } + +// NTPServerConfig holds the config container for a NTP server. +type NTPServerConfig struct { + Address string `json:"address"` + Prefer bool `json:"prefer,omitempty"` + NetworkInstance string `json:"network-instance,omitempty"` // Maps to VrfName + SourceAddress string `json:"source-address,omitempty"` +} diff --git a/test/gnmi/testdata/openconfig/ntp.txtar b/test/gnmi/testdata/openconfig/ntp.txtar new file mode 100644 index 000000000..875c64a64 --- /dev/null +++ b/test/gnmi/testdata/openconfig/ntp.txtar @@ -0,0 +1,191 @@ +# NTP +-- ntp/ntp -- +apiVersion: networking.metal.ironcore.dev/v1alpha1 +kind: NTP +metadata: + name: ntp +spec: + deviceRef: + name: leaf1 + sourceInterfaceName: mgmt0 + servers: + - address: de.pool.ntp.org + prefer: true + vrfName: mgmt + - address: pool.ntp.org + prefer: false + vrfName: mgmt + +-- state/preload -- +{ + "openconfig-system:system": { + "state": { + "boot-time": "1784731445707000000" + } + }, + "openconfig-interfaces:interfaces": { + "interface": [ + { + "name": "mgmt0", + "config": { + "enabled": true, + "name": "mgmt0", + "type": "iana-if-type:ethernetCsmacd" + }, + "subinterfaces": { + "subinterface": [ + { + "index": 0, + "config": { + "enabled": true, + "index": 0 + }, + "openconfig-if-ip:ipv4": { + "addresses": { + "address": [ + { + "ip": "172.20.20.2", + "state": { + "ip": "172.20.20.2", + "origin": "DHCP", + "prefix-length": 24 + } + } + ] + }, + "config": { + "enabled": true + } + } + } + ] + } + } + ] + } +} + +-- state/expect -- +{ + "openconfig-system:system": { + "state": { + "boot-time": "1784731445707000000" + }, + "ntp": { + "config": { + "enabled": true + }, + "servers": { + "server": [ + { + "address": "de.pool.ntp.org", + "config": { + "address": "de.pool.ntp.org", + "prefer": true, + "network-instance": "mgmt", + "source-address": "172.20.20.2" + } + }, + { + "address": "pool.ntp.org", + "config": { + "address": "pool.ntp.org", + "network-instance": "mgmt", + "source-address": "172.20.20.2" + } + } + ] + } + } + }, + "openconfig-interfaces:interfaces": { + "interface": [ + { + "name": "mgmt0", + "config": { + "enabled": true, + "name": "mgmt0", + "type": "iana-if-type:ethernetCsmacd" + }, + "subinterfaces": { + "subinterface": [ + { + "index": 0, + "config": { + "enabled": true, + "index": 0 + }, + "openconfig-if-ip:ipv4": { + "addresses": { + "address": [ + { + "ip": "172.20.20.2", + "state": { + "ip": "172.20.20.2", + "origin": "DHCP", + "prefix-length": 24 + } + } + ] + }, + "config": { + "enabled": true + } + } + } + ] + } + } + ] + } +} + +-- state/delete -- +{ + "openconfig-system:system": { + "state": { + "boot-time": "1784731445707000000" + } + }, + "openconfig-interfaces:interfaces": { + "interface": [ + { + "name": "mgmt0", + "config": { + "enabled": true, + "name": "mgmt0", + "type": "iana-if-type:ethernetCsmacd" + }, + "subinterfaces": { + "subinterface": [ + { + "index": 0, + "config": { + "enabled": true, + "index": 0 + }, + "openconfig-if-ip:ipv4": { + "addresses": { + "address": [ + { + "ip": "172.20.20.2", + "state": { + "ip": "172.20.20.2", + "origin": "DHCP", + "prefix-length": 24 + } + } + ] + }, + "config": { + "enabled": true + } + } + } + ] + } + } + ] + } +} + From fd9475d0ad963140019ba44574402c4becfb18af Mon Sep 17 00:00:00 2001 From: Adam Trizuljak Date: Thu, 10 Sep 2026 13:22:28 +0200 Subject: [PATCH 2/4] Review, cleanup Signed-off-by: Adam Trizuljak --- api/core/v1alpha1/ntp_types.go | 1 - .../templates/crd/ntp.networking.metal.ironcore.dev.yaml | 5 ++--- config/crd/bases/networking.metal.ironcore.dev_ntp.yaml | 5 ++--- docs/api-reference/index.md | 2 +- .../kubernetes/01-devices/v1alpha1-leaf1-clab-ntp.yaml | 2 +- internal/provider/openconfig/interface.go | 4 ++-- internal/provider/openconfig/ntp.go | 2 +- 7 files changed, 9 insertions(+), 12 deletions(-) diff --git a/api/core/v1alpha1/ntp_types.go b/api/core/v1alpha1/ntp_types.go index 74a0b5287..f6ffaddc9 100644 --- a/api/core/v1alpha1/ntp_types.go +++ b/api/core/v1alpha1/ntp_types.go @@ -56,7 +56,6 @@ type NTPServer struct { Prefer bool `json:"prefer,omitempty"` // The name of the vrf used to communicate with the NTP server. - // Maps to network-instance in Openconfig // +optional // +kubebuilder:validation:MinLength=1 // +kubebuilder:validation:MaxLength=63 diff --git a/charts/network-operator/templates/crd/ntp.networking.metal.ironcore.dev.yaml b/charts/network-operator/templates/crd/ntp.networking.metal.ironcore.dev.yaml index c862c4c56..caf783013 100644 --- a/charts/network-operator/templates/crd/ntp.networking.metal.ironcore.dev.yaml +++ b/charts/network-operator/templates/crd/ntp.networking.metal.ironcore.dev.yaml @@ -140,9 +140,8 @@ spec: or not. type: boolean vrfName: - description: |- - The name of the vrf used to communicate with the NTP server. - Maps to network-instance in Openconfig + description: The name of the vrf used to communicate with the + NTP server. maxLength: 63 minLength: 1 type: string diff --git a/config/crd/bases/networking.metal.ironcore.dev_ntp.yaml b/config/crd/bases/networking.metal.ironcore.dev_ntp.yaml index 5b932c59a..184698a73 100644 --- a/config/crd/bases/networking.metal.ironcore.dev_ntp.yaml +++ b/config/crd/bases/networking.metal.ironcore.dev_ntp.yaml @@ -137,9 +137,8 @@ spec: or not. type: boolean vrfName: - description: |- - The name of the vrf used to communicate with the NTP server. - Maps to network-instance in Openconfig + description: The name of the vrf used to communicate with the + NTP server. maxLength: 63 minLength: 1 type: string diff --git a/docs/api-reference/index.md b/docs/api-reference/index.md index 3ee77c5cf..ed271ca0e 100644 --- a/docs/api-reference/index.md +++ b/docs/api-reference/index.md @@ -2890,7 +2890,7 @@ _Appears in:_ | --- | --- | --- | --- | | `address` _string_ | Hostname/IP address of the NTP server. | | MaxLength: 253
MinLength: 1
Required: \{\}
| | `prefer` _boolean_ | Indicates whether this server should be preferred or not. | false | Optional: \{\}
| -| `vrfName` _string_ | The name of the vrf used to communicate with the NTP server.
Maps to network-instance in Openconfig | | MaxLength: 63
MinLength: 1
Optional: \{\}
| +| `vrfName` _string_ | The name of the vrf used to communicate with the NTP server. | | MaxLength: 63
MinLength: 1
Optional: \{\}
| #### NTPSpec diff --git a/examples/openconfig-containerlab/kubernetes/01-devices/v1alpha1-leaf1-clab-ntp.yaml b/examples/openconfig-containerlab/kubernetes/01-devices/v1alpha1-leaf1-clab-ntp.yaml index 5bb465ca7..137f048a1 100644 --- a/examples/openconfig-containerlab/kubernetes/01-devices/v1alpha1-leaf1-clab-ntp.yaml +++ b/examples/openconfig-containerlab/kubernetes/01-devices/v1alpha1-leaf1-clab-ntp.yaml @@ -4,7 +4,7 @@ metadata: labels: app.kubernetes.io/name: network-operator app.kubernetes.io/managed-by: kustomize - networking.metal.ironcore.dev/device-name: leaf1-clab + networking.metal.ironcore.dev/device-name: leaf1 name: ntp-clab spec: deviceRef: diff --git a/internal/provider/openconfig/interface.go b/internal/provider/openconfig/interface.go index 59226fd20..ed634676d 100644 --- a/internal/provider/openconfig/interface.go +++ b/internal/provider/openconfig/interface.go @@ -680,12 +680,12 @@ func (p *Provider) interfaceIPAddr(ctx context.Context, name string) (string, er addrs := &interfaceAddrs{ifName: name} if err := p.client.GetState(ctx, addrs); err != nil { if errors.Is(err, gnmiext.ErrNil) { - return "", apistatus.NewFailedPreconditionError(fmt.Sprintf("interface %q has no IPv4 address A", name)) + return "", apistatus.NewFailedPreconditionError(fmt.Sprintf("interface %q has no IPv4 address", name)) } return "", fmt.Errorf("failed to get IPv4 address for interface %q: %w", name, err) } for _, a := range addrs.Address { return a.IP, nil } - return "", apistatus.NewFailedPreconditionError(fmt.Sprintf("interface %q has no IPv4 address B", name)) + return "", apistatus.NewFailedPreconditionError(fmt.Sprintf("interface %q has no IPv4 address", name)) } diff --git a/internal/provider/openconfig/ntp.go b/internal/provider/openconfig/ntp.go index 8a31c063e..534163ffc 100644 --- a/internal/provider/openconfig/ntp.go +++ b/internal/provider/openconfig/ntp.go @@ -85,7 +85,7 @@ func (s *NTPServer) Key() string { return s.Address } // NTPServerConfig holds the config container for a NTP server. type NTPServerConfig struct { Address string `json:"address"` - Prefer bool `json:"prefer,omitempty"` + Prefer bool `json:"prefer"` NetworkInstance string `json:"network-instance,omitempty"` // Maps to VrfName SourceAddress string `json:"source-address,omitempty"` } From c85ecfb95dcf104a9512500109ef87ff8e1891d6 Mon Sep 17 00:00:00 2001 From: Adam Trizuljak Date: Fri, 11 Sep 2026 16:45:53 +0200 Subject: [PATCH 3/4] Move NTP sample into config/samples/nokia/srlinux Signed-off-by: Adam Trizuljak --- Tiltfile | 4 ++-- .../samples/nokia/srlinux/v1alpha1_ntp.yaml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) rename examples/openconfig-containerlab/kubernetes/01-devices/v1alpha1-leaf1-clab-ntp.yaml => config/samples/nokia/srlinux/v1alpha1_ntp.yaml (95%) diff --git a/Tiltfile b/Tiltfile index 4b0140ab7..b9820553f 100644 --- a/Tiltfile +++ b/Tiltfile @@ -207,8 +207,8 @@ k8s_resource(new_name='mac-entry', objects=['mac-entry:probe'], trigger_mode=TRI k8s_resource(new_name='route-prefix', objects=['route-prefix:probe'], trigger_mode=TRIGGER_MODE_MANUAL, auto_init=False, labels=['samples']) k8s_resource(new_name='vtep-peers', objects=['vtep-peers:probe'], trigger_mode=TRIGGER_MODE_MANUAL, auto_init=False, labels=['samples']) -k8s_yaml('./examples/openconfig-containerlab/kubernetes/01-devices/v1alpha1-leaf1-clab-ntp.yaml') -k8s_resource(new_name='ntp-clab', objects=['ntp-clab:ntp'], trigger_mode=TRIGGER_MODE_MANUAL, auto_init=False, labels=['containerlab']) +k8s_yaml('./config/samples/nokia/srlinux/v1alpha1_ntp.yaml') +k8s_resource(new_name='ntp-srlinux', objects=['ntp-srlinux:ntp'], trigger_mode=TRIGGER_MODE_MANUAL, auto_init=False, labels=['srlinux']) print('🚀 network-operator development environment') print('👉 Edit the code inside the api/, cmd/, or internal/ directories') diff --git a/examples/openconfig-containerlab/kubernetes/01-devices/v1alpha1-leaf1-clab-ntp.yaml b/config/samples/nokia/srlinux/v1alpha1_ntp.yaml similarity index 95% rename from examples/openconfig-containerlab/kubernetes/01-devices/v1alpha1-leaf1-clab-ntp.yaml rename to config/samples/nokia/srlinux/v1alpha1_ntp.yaml index 137f048a1..b839d0d26 100644 --- a/examples/openconfig-containerlab/kubernetes/01-devices/v1alpha1-leaf1-clab-ntp.yaml +++ b/config/samples/nokia/srlinux/v1alpha1_ntp.yaml @@ -5,7 +5,7 @@ metadata: app.kubernetes.io/name: network-operator app.kubernetes.io/managed-by: kustomize networking.metal.ironcore.dev/device-name: leaf1 - name: ntp-clab + name: ntp-srlinux spec: deviceRef: name: leaf1 From 6d7ef8f328780dcc6af97e9fffc16c232eb5e003 Mon Sep 17 00:00:00 2001 From: Adam Trizuljak Date: Fri, 11 Sep 2026 17:28:14 +0200 Subject: [PATCH 4/4] Fix GNMI test data Signed-off-by: Adam Trizuljak --- test/gnmi/testdata/openconfig/ntp.txtar | 1 + 1 file changed, 1 insertion(+) diff --git a/test/gnmi/testdata/openconfig/ntp.txtar b/test/gnmi/testdata/openconfig/ntp.txtar index 875c64a64..1c4c627c2 100644 --- a/test/gnmi/testdata/openconfig/ntp.txtar +++ b/test/gnmi/testdata/openconfig/ntp.txtar @@ -90,6 +90,7 @@ spec: "address": "pool.ntp.org", "config": { "address": "pool.ntp.org", + "prefer": false, "network-instance": "mgmt", "source-address": "172.20.20.2" }