summaryrefslogtreecommitdiff
path: root/docs/contributing/vyos_cli.rst
blob: 322b0be6a0817e51f6ede4dde693ead3f8a2180a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
.. _vyos_cli:

The VyOS CLI
============

The bash (or better vbash) completion in VyOS is defined in *templates*.
Templates are text files (called ``node.def``) stored in a directory tree. The
directory names define the command names, and template files define the command
behaviour. Before VyOS 1.2 (crux) this files were created by hand. After a
complex redesign process_ the new style template are automatically generated
from a XML input file.

XML interface definitions for VyOS come with a RelaxNG schema and are located
in the vyos-1x_ module. This schema is a slightly modified schema from VyConf_
alias VyOS 2.0 So VyOS 1.2.x interface definitions will be reusable in Nextgen
VyOS Versions with very minimal changes.

The great thing about schemas is not only that people can know the complete
grammar for certain, but also that it can be automatically verified. The
`scripts/build-command-templates` script that converts the XML definitions to
old style templates also verifies them against the schema, so a bad definition
will cause the package build to fail. I do agree that the format is verbose, but
there is no other format now that would allow this. Besides, a specialized XML
editor can alleviate the issue with verbosity.

Example XML File
----------------

.. code-block:: xml

  <?xml version="1.0"?>
  <!-- Cron configuration -->
  <interfaceDefinition>
    <node name="system">
      <children>
        <node name="task-scheduler">
          <properties>
            <help>Task scheduler settings</help>
          </properties>
          <children>
            <tagNode name="task" owner="${vyos_conf_scripts_dir}/task_scheduler.py">
              <properties>
                <help>Scheduled task</help>
                <valueHelp>
                  <format>&lt;string&gt;</format>
                  <description>Task name</description>
                </valueHelp>
                <priority>999</priority>
              </properties>
              <children>
                <leafNode name="crontab-spec">
                  <properties>
                    <help>UNIX crontab time specification string</help>
                  </properties>
                </leafNode>
                <leafNode name="interval">
                  <properties>
                    <help>Execution interval</help>
                    <valueHelp>
                      <format>&lt;minutes&gt;</format>
                      <description>Execution interval in minutes</description>
                    </valueHelp>
                    <valueHelp>
                      <format>&lt;minutes&gt;m</format>
                      <description>Execution interval in minutes</description>
                    </valueHelp>
                    <valueHelp>
                      <format>&lt;hours&gt;h</format>
                      <description>Execution interval in hours</description>
                    </valueHelp>
                    <valueHelp>
                      <format>&lt;days&gt;d</format>
                      <description>Execution interval in days</description>
                    </valueHelp>
                    <constraint>
                      <regex>[1-9]([0-9]*)([mhd]{0,1})</regex>
                    </constraint>
                  </properties>
                </leafNode>
                <node name="executable">
                  <properties>
                    <help>Executable path and arguments</help>
                  </properties>
                  <children>
                    <leafNode name="path">
                      <properties>
                        <help>Path to executable</help>
                      </properties>
                    </leafNode>
                    <leafNode name="arguments">
                      <properties>
                        <help>Arguments passed to the executable</help>
                      </properties>
                    </leafNode>
                  </children>
                </node>
              </children>
            </tagNode>
          </children>
        </node>
      </children>
    </node>
  </interfaceDefinition>

Configuration mode command definitions
--------------------------------------

Command definitions are purely declarative, and cannot contain any logic. All
logic for generating config files for target applications, restarting services
and so on is implemented in configuration scripts instead.

Command syntax guidelines
*************************

Use of numbers
^^^^^^^^^^^^^^

Use of numbers in command names **should** be avoided unless a number is a
part of a protocol name or similar. Thus, ``protocols ospfv3`` is perfectly
fine, but something like ``server-1`` is questionable at best.

Help string guidelines
**********************

To ensure uniform look and feel, and improve readability, we should follow a
set of guidelines consistently.

Capitalization and punctuation
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The first word of every help string **must** be capitalized. There **must not**
be a period at the end of help strings.

Rationale: this seems to be the unwritten standard in network device CLIs, and
a good aesthetic compromise.

Examples:

* Good: "Frobnication algorithm"
* Bad: "frobnication algorithm"
* Bad: "Frobnication algorithm."
* Horrible: "frobnication algorithm."

Use of abbreviations and acronyms
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Abbreviations and acronyms **must** be capitalized.

Examples:

* Good: "TCP connection timeout"
* Bad: "tcp connection timeout"
* Horrible: "Tcp connectin timeout"

Acronyms also **must** be capitalized to visually distinguish them from normal
words:

Examples:

* Good: RADIUS (as in remote authentication for dial-in user services)
* Bad: radius (unless it's about the distance between a center of a circle and
  any of its points)

Some abbreviations are traditionally written in mixed case. Generally, if it
contains words "over" or "version", the letter **should** be lowercase. If
there's an accepted spelling (especially if defined by an RFC or another
standard), it **must** be followed.

Examples:

* Good: PPPoE, IPsec
* Bad: PPPOE, IPSEC
* Bad: pppoe, ipsec

Use of verbs
^^^^^^^^^^^^

Verbs **should** be avoided. If a verb can be omitted, omit it.

Examples:

* Good: "TCP connection timeout"
* Bad: "Set TCP connection timeout"

If a verb is essential, keep it. For example, in the help text of ``set system
ipv6 disable-forwarding`, "Disable IPv6 forwarding on all interfaces" is a
perfectly justified wording.

Prefer infinitives
^^^^^^^^^^^^^^^^^^

Verbs, when they are necessary, **should** be in their infinitive form.

Examples:

* Good: "Disable IPv6 forwarding"
* Bad: "Disables IPv6 forwarding"

Mapping old node.def style to new XML definitions
-------------------------------------------------

.. list-table::
   :widths: 25 25 50
   :header-rows: 1

   * - Old concept/syntax
     - New syntax
     - Notes
   * - mynode/node.def
     - <node name="mynode"> </node>
     - Leaf nodes (nodes with values) use <leafNode> tag instead
   * - mynode/node.tag , tag:
     - <tagNode name="mynode> </node>
     -
   * - help: My node
     - <properties> <help>My node</help>
     -
   * - val_help: <format>; some string
     - <properties> <valueHelp> <format> format </format> <description> some
       string </description>
     - Do not add angle brackets around the format, they will be inserted
       automatically
   * - syntax:expression: pattern
     - <properties> <constraint> <regex> ...
     - <constraintErrorMessage> will be displayed on failure
   * - syntax:expression: $VAR(@) in "foo", "bar", "baz"
     - None
     - Use regex
   * - syntax:expression: exec ...
     - <properties> <constraint> <validator> <name ="foo" argument="bar">
     - "${vyos_libexecdir}/validators/foo bar $VAR(@)" will be executed,
       <constraintErrorMessage> will be displayed on failure
   * - syntax:expression: (arithmetic expression)
     - None
     - External arithmetic validator may be added if there's demand, complex
       validation is better left to commit-time scripts
   * - priority: 999
     - <properties> <priority>999</priority>
     - Please leave a comment explaining why the priority was chosen (e.g. "after
       interfaces are configured")
   * - multi:
     - <properties> <multi/>
     - Only applicable to leaf nodes
   * - allowed: echo foo bar
     - <properties> <completionHelp> <list> foo bar </list>
     -
   * - allowed: cli-shell-api listNodes vpn ipsec esp-group
     - <properties> <completionHelp> <path> vpn ipsec esp-group </path> ...
     -
   * - allowed: /path/to/script
     - <properties> <completionHelp> <script> /path/to/script </script> ...
     -
   * - default:
     - None
     - Move default values to scripts
   * - commit:expression:
     - None
     - All commit time checks should be in the verify() function of the script
   * - begin:/create:/delete:
     - None
     - All logic should be in the scripts

.. _process: https://blog.vyos.io/vyos-development-digest-10
.. _vyos-1x: https://github.com/vyos/vyos-1x/blob/current/schema/
.. _VyConf: https://github.com/vyos/vyconf/blob/master/data/schemata