Proposal API help
Contents
Introduction
Abstract
The API protocol, unlike the command line (and by extension - the Telnet and SSH protocols), does not offfer a way for RouterOS to report to the client the available commands, menus, attributes or attribute values. This proposal suggests a new API protocol specific command called "/help" that behaves similarly to a "?" in the command line, in that it will fill this gap, and it should hopefully be relatively easy to implement by MikroTik due to its similarity with the "?" help.
Terminology
- API protocol - The syntax defined in the corresponding manual page.
- API client - A general purpose implementation of the API protocol for use in a programming language. All "Examples" at the end of the above manual page are essentially API clients.
- (API) application - A program or script written in a programming language that uses an API client as part of its functionality.
- Users - People using API clients inside their applications or otherwise interact directly with the API protocol.
- End users - People for which the "Users" write the API applications.
Use cases
"Why would such a feature even be needed in a protocol intended for machine consumption?" you may ask. There are several notable use cases:
- Utility methods in API clients may sometimes need to behave differently based on the presence or absence of a command at a particular menu. Case in point: The "move" command, based on which API clients respectively may support or should avoid supporting "numbers" emulation at the given menu.
- API clients will be able to (if the user wants to) pre-validate commands (or at least some of the more trivial aspects of command calls), lessening the load on the router at the expense of the API application.
- Applications could be written that generate classes (or the equivalent in whatever language the API protocol is used from) representing each menu/command, allowing IDEs to seamlessly assist users when creating API applications.
- Because most commands are shared between scripting and API, one could also make an application that uses this command to generate auto-complete suggestions for ".rsc" files.
- It lets applications potentially detect upgrades to RouterOS, and in turn verify automatically that there are no breaking changes as a result. Case in point: v5's "target-address"/"interface" combo in "/queue simple" vs. v6's "target".
Syntax
No arguments
When the "/help" command is called with no arguments, only a single "!done" reply should be given, with a "ret" attribute that has a hash value in it. The hash should be computed based on the names and build times of all installed and enabled RouterOS packages.
The actual hash algorithm may be changed, without any prior notice, from one RouterOS build to the next. The only thing that applications should be able to safely assume about it is that it would be different whenever RouterOS is upgraded/downgraded, or if a RouterOS package is installed/uninstalled/upgraded/downgraded/enabled/disabled.
Note: MD5 or SHA1 are good choices here, since collisions are not easy enough to create when the whole data is a small series of names and times, and there's no security concern here.
Note: Version numbers are intentionally avoided, as to allow seamless uses of improperly labeled RC versions of RouterOS or its packages.
Warning: Applications MUST NOT assume ANY particular hashing algorithm or alphabet of the hash. When storing the hash, applications should take care to escape the value for whatever context they are storing it in.
Example:
| /help |
| !done |
| =ret=ebddd18303a54111e2dea05a92ab46b4 |
The purpose of this hash is to allow applications to "cache" the other results from "/help", particularly in cases where an application is examining the whole of RouterOS. For example, an object generator may generate different sets of objects for different RouterOS hostnames, but not bother regenerating them when there's no need to.
Enabling/Disabling a package affects the given hash, because enabling/disabling a package will more often than not affect the presence of menus, commands, attributes and attribute values, which is the primary use case for making an overall examination of RouterOS to begin with.
When the "/help" command is called with ONLY the "menu" argument, the "/help" command should return all menus and commands available immediatly from the specified menu.
The value of the "menu" argument is an absolute path to the menu, using the API protocol syntax, with the leading slash, and without a trailing slash. Applications can safely assume there's always going to be a root menu, i.e. "/", but should not assume the existence of any submenu.
The "!done" reply may optionally contain the following attributes:
- description - A long description of the menu, as seen above the list of commands and menus when using "?" after a menu.
For each menu or command, a "!re" reply should be generated, with the following attributes:
- name - The name of the menu or command.
- summary - A short description of the menu/command, as seen in the help from "?" after each listed menu.
- type - Indicates whether this is a menu or a command. Possible values are only "command" and "menu".
- env - Optional. A comma separated list of protocols/environments from which the command/menu is available. When not present, applications may assume that this menu/command is available from all protocols/environments supported by that RouterOS version. Each value may also be preceeded by "!" to exclude it from a previously included protocol/environment. Possible values:
- api - The API protocol.
- cli - The command line, both local and from protocols like Telnet and SSH. Also includes scripting.
- script - Scripting. Both in ".rsc" files and in "/system script" scripts and the like. Does not include the command line, Telnet and SSH.
Note: The "env" attribute is defined in this way, so as to allow forwards compatibility in case new protocols are added with their own restrictions or if commands are shifted in seemingly counter intuitive ways, e.g. not being available from scripting but being available from the command line or vice-versa. New values can be added on an "as needed" basis to exclude previously included values.
Note: Some commands' availablility over a protocol/environment is dependent on the presence/absence/value of certain arguments. RouterOS must consider the command as available to a protocol/environment if there's ANY set of arguments for which that command could work over that protocol. In other words, a command that only works under "cli" - except when a certain argument is provided and/or has a certain value - is NOT considered "cli" specific, because of that specific case. Case in point: The export command, which is really only useful when a "file" argument is provided.
Warning: Command line specific navigation features, notably ".." and ":", are excluded from the list of available menus, due to it being impossible to reliably detect them as "not-exactly-menus-on-their-own" without special casing the application code. If an application wants to support them, it would end up doing that anyway, due to these features' behaviour being special. There's no need force other applications to also special case these, so they're excluded for their benefit.
Example:
| /help |
| =menu=/ |
| !re |
| =name=beep |
| =summary= |
| =type=command |
| !re |
| =name=cancel |
| =summary=Cancel a running command |
| =type=command |
| =env=api |
| !re |
| =name=certificate |
| =summary=Certificate management |
| =type=menu |
| !re |
| =name=console |
| =summary= |
| =type=menu |
| !re |
| =name=delay |
| =summary=does nothing for a while |
| =type=command |
| =env=cli |
| !re |
| =name=do |
| =summary=executes command |
| =type=command |
| =env=cli |
| ... more !re sentences ... |
| !re |
| =name=export |
| =summary=Print or save an export script that can be used to restore configuration |
| =type=command |
| !done |
| /help |
| =menu=/system/resource |
| !re |
| =name=cpu |
| =summary= |
| =type=menu |
| !re |
| =name=export |
| =summary=Print or save an export script that can be used to restore configuration |
| =type=command |
| !re |
| =name=get |
| =summary=Gets value of item's property |
| =type=command |
| ... more !re sentences ... |
| !done |
| /help |
| =menu=/interface |
| !re |
| =name=6to4 |
| =summary= |
| =type=menu |
| !re |
| =name=blink |
| =summary= |
| =type=command |
| ... more !re sentences ... |
| !done |
| =description=An Interface is physical or virtual device which provides a connection to an external network. |
The "command" argument
If specified, the "command" argument MUST be specified together with a "menu" argument.
The value of the "command" argument is the name of a command, without any menu information attached to it. It is an error if "command" includes "/" or whitespace characters, given that neither of these constitute a valid command name.
When ONLY the "menu" and "command" arguments are both present, the "/help" command should return the available arguments for the specified command, at the specified menu, along with detailed information about the command itself.
The "!done" reply may optionally contain the following attributes:
- description - A long description of the command, as seen above the argument list, when using "?" after a command.
- policy - A comma separated list of permissions that this command always requires when its unconditionally required arguments are present. In the absence of this attribute, it is assumed that the command is always available.
- flags - A comma separated list of flags for the command. In its absence, a finite command that doesn't support queries is assumed. Possible values:
- continious - Indicates that the command will - upon having ONLY its unconditionally required arguments and without being explicitly canceled - run continiously until explicitly canceled or disconnected.
- queryable - Indicates that the command supports queries. On the command line, this would be the equivalent of a "where" argument being supported in its standard form.
For each argument that the command accepts, a "!re" reply is generated with the following attributes:
- name - The name of the argument.
- summary - A short description of the argument, as seen in the help from "?" after a command.
- flags - Optional. A comma separated list of flags for the argument. If absent, applications should assume an optional named argument with a value. Possible values:
- unnamed - Indicates that the argument's name may be omitted when using the command from the command line.
- empty - Indicates that the argument does not have a value, but should instead always be empty.
- required - Indicates that the argument is required in all calls to the command from any protocol/environment, regardless of the presence or value of any other argument.
- finite-invert - Indicates that a finite command would become continious in the presence of this argument, or if the command is continious (according to the "!done" reply), it would become finite instead.
- env - Optional. Works the same as the "env" on a command, but applies only to the particular argument.
- policy - Optional. A comma separated of additional permissions that are required when this argument is present. Each policy value may also be prefixed with "!" to indicate that an otherwise required permission would not be required when this argument is present.