@@ -185,6 +185,21 @@ Output formats:
185185* user-friendly tables with headers, etc
186186* machine-parsable delimited
187187
188+ .. note ::
189+
190+ A note on terminology. An **argument ** is a positional parameter to the
191+ command. As discussed later, these should be used sparingly in
192+ OpenStackClient. An **option ** - also known as a **flag ** - is a named
193+ parameter denoted with either a hyphen and a single-letter name (``-r ``) or
194+ a double hyphen and a multiple-letter name (``--recursive ``). They may or
195+ may not also include a user-specified value (``--file foo.txt `` or
196+ ``--file=foo.txt ``).
197+
198+ For more information on this topic and CLIs in general, refer to the
199+ excellent `Command Line Interface Guidelines website `__.
200+
201+ .. __ : https://clig.dev/#arguments-and-flags
202+
188203Global Options
189204~~~~~~~~~~~~~~
190205
@@ -225,46 +240,107 @@ form help option (``-h``) is also available.
225240The standard ``--version `` option displays the name and version on standard
226241output. All other options and commands are ignored when this is present.
227242
228- Command Object(s) and Action
229- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
243+ Objects and Actions
244+ ~~~~~~~~~~~~~~~~~~~
230245
231- Commands consist of an object described by one or more words followed by an
232- action. Commands that require two objects have the primary object ahead of the
233- action and the secondary object after the action. Any positional arguments
234- identifying the objects shall appear in the same order as the objects. In
235- badly formed English it is expressed as "(Take) object-1 (and perform) action
236- (using) object-2 (to it)."::
246+ Commands consist of an object, described by one or more words, followed by an
247+ action. ::
237248
238- <object-1 > <action> [<object-2 >]
249+ <object> <action> [<name-or-id >]
239250
240- Examples :
251+ For example :
241252
242- * ``group add user <group> <user> ``
243- * ``volume type list `` (note that ``volume type `` is a two-word single object)
253+ * ``group create ``
254+ * ``server set ``
255+ * ``volume type list ``
244256
245- The ``help `` command is unique as it appears in front of a normal command
246- and displays the help text for that command rather than execute it.
257+ (note that ``volume type `` is a two-word single object)
258+
259+ Some commands require two objects. These commands have the primary object ahead of the
260+ action and the secondary object after the action. In badly formed English it is
261+ expressed as "(Take) object-1 (and perform) action (using) object-2 (to it)." ::
262+
263+ <object-1> <action> <object-2>
264+
265+ For example:
266+
267+ * ``group add user ``
268+ * ``aggregate add host ``
269+ * ``image remove project ``
247270
248271Object names are always specified in command in their singular form. This is
249272contrary to natural language use.
250273
251- Command Arguments and Options
252- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
274+ ``help ``
275+ ++++++++
276+
277+ The ``help `` command is unique as it appears in front of a normal command
278+ and displays the help text for that command rather than execute it.
279+
280+ Arguments
281+ ~~~~~~~~~
282+
283+ Commands that interact with a specific instance of an object should accept a
284+ single argument. This argument should be a name or identifier for the object.
285+ ::
286+
287+ <object> <action> [<name-or-id>]
288+
289+ For example:
290+
291+ * ``group create <group> ``
292+ * ``server set <server> ``
293+
294+ (note that ``volume type `` is a two-word single object)
295+
296+ For commands that require two objects, the commands should accept two
297+ arguments when interacting with specific instances of the two objects. These
298+ arguments should appear in the same order as the objects. ::
299+
300+ <object-1> <action> <object-2> [<object-1-name-or-id> <object-2-name-or-id>]
301+
302+ For example:
303+
304+ * ``group add user <group> <user> ``
305+ * ``aggregate add host <aggregate> <host> ``
306+ * ``image remove project <image> <project> ``
307+
308+ Options
309+ ~~~~~~~
253310
254311Each command may have its own set of options distinct from the global options.
255312They follow the same style as the global options and always appear between
256- the command and any positional arguments the command requires.
313+ the command and any arguments the command requires.
257314
258- Command options shall only have long names. The small range of available
259- short names makes it hard for a single short option name to have a consistent
260- meaning across multiple commands.
315+ Command options should only have long names. The small range of available short
316+ names makes it hard for a single short option name to have a consistent meaning
317+ across multiple commands.
261318
262319Option Forms
263320++++++++++++
264321
265- * **boolean **: boolean options shall use a form of ``--<true>|--<false> ``
266- (preferred) or ``--<option>|--no-<option> ``. For example, the
267- ``enabled `` state of a project is set with ``--enable|--disable ``.
322+ * **datetime **: Datetime options shall accept a value in `ISO-8061 `__ format.
323+ For example, you can list servers last modified before a given date using
324+ ``--changes-before ``. ::
325+
326+ server list --changes-before 2020-01-01T12:30:00+00:00
327+
328+ * **list **: List options shall be passed via multiple options rather than as
329+ a single delimited option. For example, you can set multiple properties on a
330+ compute flavor using multiple ``--property `` options. ::
331+
332+ flavor set --property quota:read_bytes_sec=10240000 \
333+ --property quota:write_bytes_sec=10240000 \
334+ <flavor>
335+
336+ * **boolean **: Boolean options shall use a form of ``--<true>|--<false> ``
337+ (preferred) or ``--<option>|--no-<option> ``. These must be mutually
338+ exclusive and should be adjective rather than verbs. For example, the
339+ ``enabled `` state of a project is set with ``--enable|--disable ``. ::
340+
341+ project set --enable <project>
342+
343+ .. __ : https://en.wikipedia.org/wiki/ISO_8601
268344
269345Command Output
270346--------------
@@ -293,6 +369,147 @@ list of the supported commands. Note that the commands shown depend on the API
293369versions that are in effect; i.e. if ``--os-identity-api-version=3 `` is
294370present Identity API v3 commands are shown.
295371
372+
373+ Common Actions
374+ ==============
375+
376+ There are a number of common actions or patterns in use across OpenStackClient.
377+ When adding new commands, they should aim to match one of these action formats.
378+
379+ ``create ``
380+ ----------
381+
382+ ``create `` will create a new instance of ``<object> ``. Only a name should be
383+ accepted as an argument. All other required and optional information
384+ should be provided as options. If a name is not required, it can be marked as
385+ optional. If it is not possible to specify a name when creating a new instance,
386+ no arguments should be accepted. ::
387+
388+ <object> create <name>
389+
390+ For example:
391+
392+ * ``flavor create <name> `` (compute flavors require a name)
393+ * ``volume create [<name>] ... `` (block storage volumes don't *need * names)
394+ * ``consumer create ... `` (identity consumers don't have names)
395+ * ``container create --public <name> `` (additional information should be
396+ provided as options)
397+
398+ ``show ``
399+ --------
400+
401+ ``show `` will fetch a single instance of ``object ``. Only a name or identifier
402+ should be accepted as a argument. Any filters or additional information should
403+ be provided as options. Where names are not unique or an instance is not found,
404+ an error must be shown so the user can try again using a unique or valid ID,
405+ respectively. ::
406+
407+ <object> show <name-or-id>
408+
409+ For example:
410+
411+ * ``server show <name-or-id> `` (compute servers have names or IDs and can be
412+ referenced by both)
413+ * ``consumer show <id> `` (identity consumers only have IDs, not names)
414+ * ``server show --toplogy <name-or-id> `` (additional information should be
415+ provided as options)
416+
417+ ``list ``
418+ --------
419+
420+ ``list `` will list multiple instances of ``object ``. No arguments should be
421+ accepted. Any filters or pagination requests should be requested via option
422+ arguments. ::
423+
424+ <object> list
425+
426+ For example:
427+
428+ * ``image list `` (no arguments should be accepted)
429+ * ``server list --status ACTIVE `` (filters should be provided as option
430+ arguments)
431+
432+ ``delete ``
433+ ----------
434+
435+ ``delete `` will delete one or more instances of ``object ``. Where possible,
436+ this command should handle deleting instances of ``object `` by either name or
437+ ID. Where names are not unique or an instance is not found, the command should
438+ continue deleting any other instances requested before returning an error
439+ indicating the instances that failed to delete. ::
440+
441+ <object> delete <name-or-id> [<name-or-id> ...]
442+
443+ For example:
444+
445+ * ``network delete <name-or-id> ``
446+ * ``region delete <name-or-id> ``
447+
448+ ``set ``, ``unset ``
449+ ------------------
450+
451+ ``set `` and ``unset `` will add or remove one or more attributes of an instance
452+ of ``object ``, respectively. Only a name or identifier should be accepted as a
453+ argument. All other information should be provided as option
454+ arguments. Where names are not unique or an instance is not found, an error
455+ must be shown so the user can try again using a unique or valid ID,
456+ respectively. This command may result in multiple API calls but it must not
457+ result in the creation or modification of child object. ::
458+
459+ <object> set <name-or-id>
460+
461+ For example:
462+
463+ * ``network set <name-or-id> ``
464+ * ``floating ip unset --port <port> <name-or-id> `` (additional information
465+ should be provided as options)
466+
467+ ``add ``, ``remove ``
468+ -------------------
469+
470+ ``add `` and ``remove `` will associate or disassociate a child object with a
471+ parent object. Only a name or identifier for both parent and child objects
472+ should be accepted as arguments. All other information should be provided as
473+ options. Where names are not unique or an instance is not found, an error must
474+ be shown so the user can try again using a unique or valid ID, respectively. ::
475+
476+ <parent-object> add <child-object> <parent-name-or-id> <child-name-or-id>
477+ <parent-object> remove <child-object> <parent-name-or-id> <child-name-or-id>
478+
479+ For example:
480+
481+ * ``aggregate add host <aggregate-name-or-id> <host> ``
482+ * ``consistency group add volume <consistency-group-name-or-id> <volume-name-or-id> ``
483+
484+ Other actions
485+ -------------
486+
487+ There are other actions that do not fit neatly into any of the above actions.
488+ Typically, these are used where an action would create a child object but that
489+ child object is only exposed as part of the parent object. They are also used
490+ where fitting the action into one of the above actions, particularly ``set ``,
491+ would be deemed to be confusing or otherwise inappropriate. These are permitted
492+ once this has been discussed among reviewers and context provided in either the
493+ commit message or via comments in the code.
494+
495+ For example:
496+
497+ * ``server ssh `` (this would not naturally fit into any of the other actions)
498+ * ``server migrate `` (this results in the creation of a server migration record
499+ and could be implemented as ``server migration create `` but this feels
500+ unnatural)
501+ * ``server migration confirm `` (this could be implemented as ``server migration
502+ set --confirm `` but this feels unnatural)
503+ * ``volume backup record export `` (this could be implemented as ``volume backup
504+ record show --exportable `` but this feels unnatural)
505+
506+ .. note ::
507+
508+ The guidelines below are best practices but exceptions do exist in
509+ OpenStackClient and in various plugins. Where possible, these exceptions
510+ should be addressed over time.
511+
512+
296513Examples
297514========
298515
0 commit comments