Implement Openconfig NTP provider - #517
adamtrizuljak-sap wants to merge 4 commits into
Conversation
a355b07 to
e1c927a
Compare
6974f26 to
edf5a26
Compare
- 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 <adam.trizuljak@sap.com>
edf5a26 to
2ab090d
Compare
nikatza
left a comment
There was a problem hiding this comment.
I have some minor comments, happy to discuss them if needed :) 🚀
| @@ -0,0 +1,19 @@ | |||
| apiVersion: networking.metal.ironcore.dev/v1alpha1 | |||
There was a problem hiding this comment.
I fear these new files included in this folder as they don't really fit well here in this PR. I think the examples folder is reserved to more complex scenarios. If that is OK for you we could remove them and clarify in our weekly. What do you think?
There was a problem hiding this comment.
I created this file because Openconfig requires different settings from config/samples/v1alpha1_ntp.yaml.
As I wrote here #517 (comment), my idea is to have ready-to-go samples for all providers which can be used during development for testing against a Containerlab setup or similar. If I only have config/samples/v1alpha1_ntp.yaml in the repo, I would need to overwrite it each time, discard the changes afterwards (and pay attention to not commit it) and do this for every resource that differs -> not a very streamlined and uniform development workflow.
Do you have an idea for better placement of such samples? Maybe move config/samples/ into something like config/samples/common and place this file into config/samples/openconfig?
| } | ||
|
|
||
| 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) |
There was a problem hiding this comment.
We have two hard-coded elements here: the index (0) and the AFI (IPv4). I think we should be able to fetch IPv6 or indicate the address family we want. Same goes for the index. What we could do is add these fields in interfaceAddrs (with tag json:"-") and build our xpath using those values.
If so the provider should be changed accordingly, e.g., use index 0 when the interface name matches some constraints (or just document why 0 is hard-coded). For the IPv4 and IPv6 AFI: you could make that dependent on the AFI of the NTPServers in the spec.
There was a problem hiding this comment.
It's a simple lookup to get the first IP address of the interface given by NTPSpec.SourceInterfaceName, which we did to avoid adding the NTPSpec.SourceAddress field. I am not sure how to include the information (especially the interface index) without again modifying NTPSpec...
| } | ||
|
|
||
| // interfaceIPAddr retrieves the first IPv4 address from the state of the named interface. | ||
| func (p *Provider) interfaceIPAddr(ctx context.Context, name string) (string, error) { |
There was a problem hiding this comment.
We should be able to get IPv6 addresses too :)
There was a problem hiding this comment.
I could do it, but in general we don't support IPv6 in network-operator?
| 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']) |
There was a problem hiding this comment.
I would propose to leave the existing resource from samples and keep the tilt file compact.
Signed-off-by: Adam Trizuljak <adam.trizuljak@sap.com>
Signed-off-by: Adam Trizuljak <adam.trizuljak@sap.com>
Signed-off-by: Adam Trizuljak <adam.trizuljak@sap.com>
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. |
Work in progress
internal/provider/openconfig/ntp.go) and a gnmi testdata file (test/gnmi/testdata/openconfig/ntp.txtar).Add optional fieldNTPSpec.SourceAddressand validation logic (see below)NTPSpec.SourceInterfacefrom the device using the GRPC client and use it to populate thesource-addressfield in OpenconfigDeviceandNTPresourcesApplying examples/openconfig-containerlab/kubernetes/01-devices/v1alpha1-leaf1-clab-ntp.yaml produces the following config in SRLinux:
Cisco vs Openconfig compatibility issue (solved)
NTPSpecdefines theSourceInterfaceNamefield https://github.com/ironcore-dev/network-operator/blob/main/api/core/v1alpha1/ntp_types.go#L36. Openconfig has something similarsource-addresshttps://openconfig.net/projects/models/schemadocs/yangdoc/openconfig-system.html#system-ntp-servers-server-config-source-addressA way to handle it would be to look up the interface given by SourceInterfaceName , get its IPv4 address and put it into
source-address. Does it make sense? Do you usually do such operations, or do you keep the provider code clean from reading any additional k8s resources?Other way would be to just ignore
SourceInterfaceNameand not pass it into the Openconfig struct, or even throw aapistatus.FieldViolationsaying that it's unsupportedSolution
After discussion we decided to do the original proposal and obtain the IP address from the interface. However, if the management interface is used for NTP we can't obtain the address from an
Interfaceresource, 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 thesource-addressfield.This solution does not change the NTPSpec and should work with any
SourceInterfaceNamethat has an IP address (either manually configured, or obtained from DHCP).Previous solution - abandoned
Discussed with @nikatza and @rgildeinNTPSpec.SourceInterfaceNameas optionalNTPSpec.SourceAddressSourceInterfaceNameis definedSince both fields are optional, the change will be backwards-compatible with the previous NTPSpec and the generated custom resources.