Community discussions

MikroTik App
 
xunil76
newbie
Topic Author
Posts: 46
Joined: Fri May 20, 2011 12:48 am

automatically name the system identity

Mon Feb 02, 2015 6:10 pm

hey guys,

pretty new to scripting here....i'm looking for a way to add to an existing script the ability to automatically set the system identity, based on the MAC address of the WAN interface.

what i want it to do is get the MAC address of the interface of choice (which will be specified by the variable) and set the system identity to that value.

so basically:

:global IDENTITY xxx (where xxx is the name of the interface, i.e., ether1, ether2, etc).

i know that /system identity set name=xx:xx:xx:xx:xx:xx is how to set the system identity, but i just don't know how to get the name set to the value that is pulled when setting the variable.

i'd appreciate any help you guys could provide
 
User avatar
Kickoleg
Member Candidate
Member Candidate
Posts: 129
Joined: Tue Mar 11, 2014 3:13 pm
Location: Yverdon-les-Bains, Suisse

Re: automatically name the system identity

Mon Feb 02, 2015 6:21 pm

ros code

:global IDENTITY [interface ethernet get ether1 mac-address ]
:system identity set name=$identity
 
xunil76
newbie
Topic Author
Posts: 46
Joined: Fri May 20, 2011 12:48 am

Re: automatically name the system identity

Fri Feb 06, 2015 6:19 pm

OK, the "$identity" part was what i was missing, thanks for that
and would it not be "/system identity set name=$identity" instead of ":system identity set name=$identity"? or does it have to have the ":" there?

also, using the scripts that we have already to perform other things as a sort of template, i came up with (what i hope is) a way to make setting the variable more intuitive. if the following works the way i'm hoping, it will allow you to initially just set the IDENTITY variable to the name of the interface for which you want to pull the MAC address, then based on that, the rest of the script should pull the MAC address of that interface and assign it to the "/system identity" field. Please let me know if i'm missing something.:

ros code

{:delay 00:00:01
:global IDENTITY <variable>
### "<variable>" would be "ether1", "ether2", "sfp1", "sfp2", etc.

:if ([:typeof $IDENTITY] = "nothing") do={:log info "Please enter a global IDENTITY Variable using :global IDENTITY #####"; :log info "TERMINATING SCRIPT FIX THE ERROR AND RE-RUN THE SCRIPT" ; :put "\r\n" ; :put "Please enter a global IDENTITY Variable using :global IDENTITY ########"; :put "\r\n" ; :put "TERMINATING SCRIPT FIX THE ERROR AND RE-RUN THE SCRIPT" ; :put "\r\n" ; :end}

:if ($IDENTITY=sfp1) do={:global IDENTITY [interface ethernet get sfp1 mac-address] {/system identity set name=$identity}}
:if ($IDENTITY=sfp2) do={:global IDENTITY [interface ethernet get sfp2 mac-address] {/system identity set name=$identity}}
:if ($IDENTITY=sfp3) do={:global IDENTITY [interface ethernet get sfp3 mac-address] {/system identity set name=$identity}}
:if ($IDENTITY=sfp4) do={:global IDENTITY [interface ethernet get sfp4 mac-address] {/system identity set name=$identity}}
:if ($IDENTITY=ether1) do={:global IDENTITY [interface ethernet get ether1 mac-address] {/system identity set name=$identity}}
:if ($IDENTITY=ether2) do={:global IDENTITY [interface ethernet get ether2 mac-address] {/system identity set name=$identity}}
:if ($IDENTITY=ether3) do={:global IDENTITY [interface ethernet get ether3 mac-address] {/system identity set name=$identity}}
:if ($IDENTITY=ether4) do={:global IDENTITY [interface ethernet get ether4 mac-address] {/system identity set name=$identity}}
:if ($IDENTITY=ether5) do={:global IDENTITY [interface ethernet get ether5 mac-address] {/system identity set name=$identity}}
:if ($IDENTITY=ether6) do={:global IDENTITY [interface ethernet get ether6 mac-address] {/system identity set name=$identity}}
:if ($IDENTITY=ether7) do={:global IDENTITY [interface ethernet get ether7 mac-address] {/system identity set name=$identity}}
:if ($IDENTITY=ether8) do={:global IDENTITY [interface ethernet get ether8 mac-address] {/system identity set name=$identity}}
:if ($IDENTITY=ether9) do={:global IDENTITY [interface ethernet get ether9 mac-address] {/system identity set name=$identity}}
:if ($IDENTITY=ether10) do={:global IDENTITY [interface ethernet get ether10 mac-address] {/system identity set name=$identity}}
:if ($IDENTITY=ether11) do={:global IDENTITY [interface ethernet get ether11 mac-address] {/system identity set name=$identity}}
:if ($IDENTITY=ether12) do={:global IDENTITY [interface ethernet get ether12 mac-address] {/system identity set name=$identity}}
:if ($IDENTITY=ether13) do={:global IDENTITY [interface ethernet get ether13 mac-address] {/system identity set name=$identity}}

}
 
User avatar
boen_robot
Forum Guru
Forum Guru
Posts: 2400
Joined: Thu Aug 31, 2006 4:43 pm
Location: europe://Bulgaria/Plovdiv

Re: automatically name the system identity

Fri Feb 06, 2015 6:42 pm

Why do those checks? You can unconditionally just take the name, and use it, like:
:delay 00:00:01
:global IDENTITY <variable>
### "<variable>" would be "ether1", "ether2", "sfp1", "sfp2", etc.

:if ([:typeof $IDENTITY] = "nothing") do={
    :log info "Please enter a global IDENTITY Variable using :global IDENTITY #####";
    :log info "TERMINATING SCRIPT FIX THE ERROR AND RE-RUN THE SCRIPT";
    :put "\r\n" ; :put "Please enter a global IDENTITY Variable using :global IDENTITY ########";
    :put "\r\n" ; :put "TERMINATING SCRIPT FIX THE ERROR AND RE-RUN THE SCRIPT";
    :put "\r\n" ;
} else={
    :set IDENTITY [interface ethernet get $IDENTITY mac-address];
    /system identity set name=$IDENTITY;
}
BTW, it might be wise to keep the $IDENTITY variable consistently contain the interface name, for the purposes of that script being able to run a second time without unfortunate side effects, so f.e.
:delay 00:00:01
:global IDENTITY <variable>
### "<variable>" would be "ether1", "ether2", "sfp1", "sfp2", etc.

:if ([:typeof $IDENTITY] = "nothing") do={
    :log info "Please enter a global IDENTITY Variable using :global IDENTITY #####";
    :log info "TERMINATING SCRIPT FIX THE ERROR AND RE-RUN THE SCRIPT";
    :put "\r\n" ; :put "Please enter a global IDENTITY Variable using :global IDENTITY ########";
    :put "\r\n" ; :put "TERMINATING SCRIPT FIX THE ERROR AND RE-RUN THE SCRIPT";
    :put "\r\n" ;
} else={
    /system identity set name=[interface ethernet get $IDENTITY mac-address];
}
or if you need to reuse the MAC address for a different purpose, use a differently named (local?) variable, e.g.
Why do those checks? You can unconditionally just take the name, and use it, like:
:delay 00:00:01
:global IDENTITY <variable>
### "<variable>" would be "ether1", "ether2", "sfp1", "sfp2", etc.

:if ([:typeof $IDENTITY] = "nothing") do={
    :log info "Please enter a global IDENTITY Variable using :global IDENTITY #####";
    :log info "TERMINATING SCRIPT FIX THE ERROR AND RE-RUN THE SCRIPT";
    :put "\r\n" ; :put "Please enter a global IDENTITY Variable using :global IDENTITY ########";
    :put "\r\n" ; :put "TERMINATING SCRIPT FIX THE ERROR AND RE-RUN THE SCRIPT";
    :put "\r\n" ;
} else={
    :local IDENTITY_MAC [interface ethernet get $IDENTITY mac-address];
    /system identity set name=$IDENTITY_MAC;
    ### Rest of the script here uses $IDENTITY to refer to interface, and $IDENTITY_MAC to refer to that interface's MAC address
}
 
xunil76
newbie
Topic Author
Posts: 46
Joined: Fri May 20, 2011 12:48 am

Re: automatically name the system identity

Fri Feb 06, 2015 9:27 pm

OK, with a minor modification, the 2nd script you posted works (it was missing a "/" on the 2nd to last line: " /system identity set name=[interface ethernet get $IDENTITY mac-address]" needs to be " /system identity set name=[/interface ethernet get $IDENTITY mac-address]"

so the script would be:

ros code

:delay 00:00:01
:global IDENTITY <variable>
### "<variable>" would be "ether1", "ether2", "sfp1", "sfp2", etc.

:if ([:typeof $IDENTITY] = "nothing") do={
    :log info "Please enter a global IDENTITY Variable using :global IDENTITY #####";
    :log info "TERMINATING SCRIPT FIX THE ERROR AND RE-RUN THE SCRIPT";
    :put "\r\n" ; :put "Please enter a global IDENTITY Variable using :global IDENTITY ########";
    :put "\r\n" ; :put "TERMINATING SCRIPT FIX THE ERROR AND RE-RUN THE SCRIPT";
    :put "\r\n" ;
} else={
    /system identity set name=[/interface ethernet get $IDENTITY mac-address];
}
however, there is one small snag.....
if the WAN interface is wlan1, it doesn't work, because the wlan interface is an interface of type=wireless instead of type=ethernet.
i need the script to check if $IDENTITY=wlan1, and if so, run: " /system identity set name=[/interface wireless get $IDENTITY mac-address]"....otherwise, if the $IDENTITY=etherx/sfpx (ether1, ether2, sfp1, etc), then it would run: " /system identity set name=[/interface ethernet get $IDENTITY mac-address]"
 
xunil76
newbie
Topic Author
Posts: 46
Joined: Fri May 20, 2011 12:48 am

Re: automatically name the system identity

Sat Feb 07, 2015 12:50 am

OK, so i figured out the problem between the wlan1 & etherx/sfpx:

ros code

:global IDENTITY <variable>
### "<variable>" would be "ether1", "ether2", "sfp1", "sfp2", etc.

:if ($IDENTITY = "wlan1") do= { /system identity set name=[/interface wireless get $IDENTITY mac-address] } else={ /system identity set name=[/interface ethernet get $IDENTITY mac-address] }
however, in our main configuration script, we have about 10 - 12 variables at the start of the script, then a section just below that which does error checking to make sure that all the variables have been specified. if anything has been left blank or is specified with an invalid value, it gives an error stating to enter a correct variable and re-run the script. we check all the variables first, and have the command ":end" at the end of each variable checking line so that the script will stop running if an error is encountered, so that it does not continue trying to configure the unit without valid variables.

i copied one of the existing lines and simply changed the name of the variable to be "IDENTITY" instead of its previous value, but it keeps telling me that the ":end" command is invalid, after giving me the prompt about making sure the variable is set correctly. this is the script pared down to only the section i am working on:

ros code

{:delay 00:00:01
:global IDENTITY

:if ([:typeof $IDENTITY] = "nothing") do={
:log info "Please enter a global IDENTITY Variable using :global IDENTITY #####"; 
:log info "TERMINATING SCRIPT FIX THE ERROR AND RE-RUN THE SCRIPT" ; 
:put "\r\n" ; :put "Please enter a global IDENTITY Variable using :global IDENTITY ########"; 
:put "\r\n" ; :put "TERMINATING SCRIPT FIX THE ERROR AND RE-RUN THE SCRIPT" ; 
:put "\r\n" ; :end
}

:if ($IDENTITY = "wlan1") do= { /system identity set name=[/interface wireless get $IDENTITY mac-address] } else={ /system identity set name=[/interface ethernet get $IDENTITY mac-address] }
}
 
User avatar
boen_robot
Forum Guru
Forum Guru
Posts: 2400
Joined: Thu Aug 31, 2006 4:43 pm
Location: europe://Bulgaria/Plovdiv

Re: automatically name the system identity

Sun Feb 08, 2015 12:32 am

Well, yes, there's no :end command. If you want to stop a script from running, use :return instead, or branch out, as I did in my previous example.

As for the Wireless/Ethernet check... You can simply check whether the output of one is an empty string, and try the other if it is.

You keep wanting to do a sequence of :if commands that check for a specific name... Stop doing that! I mean, what if you want to run the script on a router where the interface names were already specified as something else - something more meaningful? You want to let the user adjust it, so... Let them use whatever they've specified.
{
:delay 1s
:global IDENTITY

:if ([:typeof $IDENTITY] = "nothing") do={
:log info "Please enter a global IDENTITY Variable using :global IDENTITY #####"; 
:log info "TERMINATING SCRIPT FIX THE ERROR AND RE-RUN THE SCRIPT" ; 
:put "\r\n" ;
:put "Please enter a global IDENTITY Variable using :global IDENTITY ########"; 
:put "\r\n" ;
:put "TERMINATING SCRIPT FIX THE ERROR AND RE-RUN THE SCRIPT" ; 
:put "\r\n" ;

#Fine, if you insist on not branching
:return;
}

:global IDENTITY_MAC
:set IDENTITY_MAC [/interface get $IDENTITY mac-address];
:if ([:typeof $IDENTITY] = "nothing") do={
    :set IDENTITY_MAC [/interface wireless get $IDENTITY mac-address];
}
/system identity set name=$IDENTITY_MAC;
}
 
xunil76
newbie
Topic Author
Posts: 46
Joined: Fri May 20, 2011 12:48 am

Re: automatically name the system identity

Mon Feb 09, 2015 5:09 pm

Well, yes, there's no :end command. If you want to stop a script from running, use :return instead, or branch out, as I did in my previous example.

As for the Wireless/Ethernet check... You can simply check whether the output of one is an empty string, and try the other if it is.

You keep wanting to do a sequence of :if commands that check for a specific name... Stop doing that! I mean, what if you want to run the script on a router where the interface names were already specified as something else - something more meaningful? You want to let the user adjust it, so... Let them use whatever they've specified.
ok, so i found out that the person who originally wrote our scripts intentionally used the (invalid) :end command so that the script would error out and stop running if that line was run (which only happens if a variable is not set)...not elegant, but it does work, and unfortunately i'll probably not be able to change his mind on that part. whatever, as long as it does the job it was intended to do.

as for running it on an existing config, that won't happen. these scripts are exclusively being used on devices which have been defaulted with no backups and no default configuration, so they are a completely clean slate. we are the only ones who have access to the devices and the scripts, so other users specifying different interface names is not going to happen. if we were needing to set the identity on a device with an existing configuration on it, we would just do so manually. the devices we are configuring will only be using the default names, so specifying "wlan1" in the :if statement is fine for our purposes; we will not be using any devices with more than one wireless interface.

i appreciate the assistance though, it was very helpful in figuring out where i was going wrong. :D