From 527477b04252790e03968de88aefbbd32e7d4977 Mon Sep 17 00:00:00 2001 From: "Bryan T. Richardson" Date: Wed, 17 Jan 2024 16:40:25 -0700 Subject: [PATCH] fix(vrouter): support NTP configuration via ntp app This commit updates the vrouter app to look for the ntp app in the scenario config and configure ntp (client only) in the Vyos/Vyatta config files that are generated by the vrouter app. Note that the latest version of this app does not yet support NTP client configuration for minirouter-based routers, nor does it support configuring routers to act as NTP servers. --- src/go/app/vrouter.go | 49 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/src/go/app/vrouter.go b/src/go/app/vrouter.go index 469eaa4d..6c421def 100644 --- a/src/go/app/vrouter.go +++ b/src/go/app/vrouter.go @@ -192,6 +192,14 @@ func (this *Vrouter) PreStart(ctx context.Context, exp *types.Experiment) error "", "", ) + if ntpAddr == "" { + var err error + + if ntpAddr, err = configureNTP(exp, node.General().Hostname()); err != nil { + return fmt.Errorf("configuring NTP for host %s: %w", node.General().Hostname(), err) + } + } + data := map[string]interface{}{ "node": node, "ntp-addr": ntpAddr, @@ -747,6 +755,47 @@ func (this *Vrouter) processNAT(md map[string]interface{}, nets []ifaces.NodeNet return sources, destinations, nil } +func configureNTP(exp *types.Experiment, hostname string) (string, error) { + // Check to see if a scenario exists for this experiment and if it contains + // a "ntp" app. If so, use it to configure NTP for the experiment. + for _, app := range exp.Apps() { + if app.Name() == "ntp" { + var amd NTPAppMetadata + mapstructure.Decode(app.Metadata(), &amd) + + // Might be an empty string, but that's okay... for now. + defaultSource := amd.DefaultSource.IPAddress(exp) + + for _, host := range app.Hosts() { + if host.Hostname() != hostname { + continue + } + + var hmd NTPAppHostMetadata + mapstructure.Decode(host.Metadata(), &hmd) + + source := hmd.Source.IPAddress(exp) + + if hmd.Client == "ntp" { + if source == "" { + if defaultSource == "" { + return "", fmt.Errorf("no NTP source configured for host %s (and no default source configured)", host.Hostname()) + } + + source = defaultSource + } + + return source, nil + } else { + return "", fmt.Errorf("the only valid NTP client for vrouters is 'ntp' (%s was provided)", hmd.Client) + } + } + } + } + + return "", nil +} + func addChainRules(cmd *mmcli.Command, node string, ruleset ifaces.NodeNetworkRuleset) error { for _, rule := range ruleset.Rules() { dst := rule.Destination().Address()