Reading the current value of import.route-targets

I am trying to build a script that adds route targets to an import list (BGP VPN). However, I can't read the current value of the list, which I need before I can add to it.

When I print the current BGP VPN configuration, I see output similar to:
/routing/bgp/vpn> print

3 name="bgp-mpls-vpn-4" instance=default route-distinguisher="xxxx" vrf=xxxx label-allocation-policy=per-vrf
import.route-targets=64912:1
export.route-targets=64912:4 .redistribute=connected

However, when I try to get the value of import.route-targets with the GET command, I get the following:

/routing/bgp/vpn> :put [get value-name=import.route-targets number=3]

386w2d16:01:00

That value does not make much sense to me. I would have expected the output to be 64912:1. Does anyone know what I am doing wrong here?

UPDATE: For reference, this is on RouterOS v7.23.2

Yep. It's decoded as time i.e. 64912 hours and 1 minute.

As to how to get it to be of the form you want, consult the :typeof, :tostr, etc. parts of the scripting docs.

Or wait for one of the scripting gurus to show up :slight_smile:

You can use @rextended's script that converts such duration to seconds: Convert uptime to date and time - #37 by rextended. That you can adjust to calculate the Hour & Minute values and rebuild the original as Hour:Minute.

Instead of this:

use $itMin as Minute directly, and ($itHou + (24 * $itDay) + (168 * $itWee)) as Hour.

Thank you very much for your input. I now understand a little better what is happening, although I am not sure how to solve it.

The test value of the import route target here is 64912:1 and the following command
:put [get value-name=import.route-targets number=3] returns 386w2d16:01:00

I get the same for the following:

:put [[:totime "64912:1"]] (386w2d16:01:00)

So it seems that RouterOS is doing some sort of implicit type conversion when I try to get it directly from the import.route-target variable, treating it as 64912 hours and 1 minute, as you both mentioned. However, I need a way to stop that type conversion before it happens. Converting back afterward will lose information (i.e., if the "minutes" are 60 or larger).

With the funky time decoding approach, I will not be able to decode 64912:61 (it would decode to 64913:1, which is not correct). There is absolutely no correlation between time and time targets in the real world :slight_smile:

UPDATE:

The following prints the same strange time converted value, which to me indicates that the conversion happens somewhere in the GET command. Is there another way for me to read the value of import.route-targets?

:foreach rt in=[get value-name=import.route-targets number=3] do={
:put [:tostr $rt]
}

386w2d16:01:00

Ah, that's true.

I can't test, but print normally has a as-value parameter, for example:

:local myItems [/routing bgp vpn print as-value];

Should populate $myItems with an array (one element for each items of the table) of keyed arrays (each parameter name as key). Maybe the conversion is not done with that output? You can use :foreach to iterate over $myItems and retrieve the value with ($currentItem->"import.route-targets"), with $currentItem being the iteration variable.

EDIT: Tested and this doesn't work. ($currentItem->"import.route-targets") is an array of time elements :frowning:. You'll need to fill a bug report then.

I asked the Mikrotik AI for suggestions and it suggested serializing it into JSON as a safe string first and then using it:

:local row [/routing/bgp/vpn/print as-value];
:put [:serialize to=json value=($row->0->"import.route-targets")];

It wouldn't hurt to try