blob: 0a474f0602e16f7f5d00126171281f6bf6682b01 [file] [log] [blame]
Václav Kubernát24df80e2018-06-06 15:18:03 +02001/*
2 * Copyright (C) 2018 CESNET, https://photonics.cesnet.cz/
3 * Copyright (C) 2018 FIT CVUT, https://fit.cvut.cz/
4 *
5 * Written by Václav Kubernát <kubervac@fit.cvut.cz>
6 *
7*/
8#pragma once
9
Václav Kubernát57272422019-02-08 12:48:24 +010010#include <boost/mpl/vector.hpp>
Václav Kubernát509ce652019-05-29 19:46:44 +020011#include <boost/spirit/home/x3/support/ast/position_tagged.hpp>
Václav Kubernát24df80e2018-06-06 15:18:03 +020012#include "ast_path.hpp"
Václav Kubernát627f6152018-08-29 13:23:56 +020013#include "ast_values.hpp"
Václav Kubernát162165e2021-02-22 09:46:53 +010014#include "datastore_access.hpp"
Václav Kubernát6a7dd4d2020-06-23 22:44:13 +020015#include "yang_operations.hpp"
Václav Kubernát24df80e2018-06-06 15:18:03 +020016
17namespace x3 = boost::spirit::x3;
Václav Kubernát24df80e2018-06-06 15:18:03 +020018
Václav Kubernát7707cae2020-01-16 12:04:53 +010019using keyValue_ = std::pair<std::string, leaf_data_>;
Václav Kubernát24df80e2018-06-06 15:18:03 +020020
Václav Kubernáte7d4aea2018-09-11 18:15:48 +020021enum class LsOption {
22 Recursive
23};
24
Václav Kubernát6d791432018-10-25 16:00:35 +020025struct discard_ : x3::position_tagged {
Václav Kubernát57272422019-02-08 12:48:24 +010026 static constexpr auto name = "discard";
Václav Kubernát054cc992019-02-21 14:23:52 +010027 static constexpr auto shortHelp = "discard - Discard current changes.";
28 static constexpr auto longHelp = R"(
29 discard
30
31 Discards current changes. Accepts no arguments.
32
33 Usage:
34 /> discard)";
Václav Kubernát6d791432018-10-25 16:00:35 +020035 bool operator==(const discard_& b) const;
36};
37
Václav Kubernát11afac72018-07-18 14:59:53 +020038struct ls_ : x3::position_tagged {
Václav Kubernát57272422019-02-08 12:48:24 +010039 static constexpr auto name = "ls";
Václav Kubernát054cc992019-02-21 14:23:52 +010040 static constexpr auto shortHelp = "ls - List available nodes.";
41 static constexpr auto longHelp = R"(
42 ls [--recursive] [path]
43
Václav Kubernát419d9172020-11-30 01:20:28 +010044 Lists available child nodes in the current context node. Optionally accepts
45 a path argument. Accepts both schema paths and data paths. Path starting
46 with a forward slash means an absolute path.
47
48 Options:
49 --recursive makes `ls` work recursively
Václav Kubernát054cc992019-02-21 14:23:52 +010050
51 Usage:
52 /> ls
53 /> ls --recursive module:node
54 /> ls /module:node)";
Václav Kubernát11afac72018-07-18 14:59:53 +020055 bool operator==(const ls_& b) const;
Václav Kubernáte7d4aea2018-09-11 18:15:48 +020056 std::vector<LsOption> m_options;
Václav Kubernátbeaa8aa2020-04-29 22:39:34 +020057 boost::optional<boost::variant<dataPath_, schemaPath_, module_>> m_path;
Václav Kubernát11afac72018-07-18 14:59:53 +020058};
59
Václav Kubernát24df80e2018-06-06 15:18:03 +020060struct cd_ : x3::position_tagged {
Václav Kubernát57272422019-02-08 12:48:24 +010061 static constexpr auto name = "cd";
Václav Kubernát054cc992019-02-21 14:23:52 +010062 static constexpr auto shortHelp = "cd - Enter a different node.";
63 static constexpr auto longHelp = R"(
Václav Kubernát419d9172020-11-30 01:20:28 +010064 cd <path>
Václav Kubernát054cc992019-02-21 14:23:52 +010065
Václav Kubernát419d9172020-11-30 01:20:28 +010066 Changes context to a node specified by <path>. Only accepts data paths
67 (paths with all list keys supplied).
Václav Kubernát054cc992019-02-21 14:23:52 +010068
69 Usage:
70 /> cd /module:node/node2
71 /> cd ..)";
Václav Kubernát24df80e2018-06-06 15:18:03 +020072 bool operator==(const cd_& b) const;
Václav Kubernát2eaceb82018-10-08 19:56:30 +020073 dataPath_ m_path;
Václav Kubernát24df80e2018-06-06 15:18:03 +020074};
75
76struct create_ : x3::position_tagged {
Václav Kubernát57272422019-02-08 12:48:24 +010077 static constexpr auto name = "create";
Václav Kubernát419d9172020-11-30 01:20:28 +010078 static constexpr auto shortHelp = "create - Create a node.";
Václav Kubernát054cc992019-02-21 14:23:52 +010079 static constexpr auto longHelp = R"(
Václav Kubernát419d9172020-11-30 01:20:28 +010080 create <path>
Václav Kubernát054cc992019-02-21 14:23:52 +010081
Václav Kubernát419d9172020-11-30 01:20:28 +010082 Creates a node specified by <path>.
83 Supported node types are list items, leaflist instance and presence
84 containers.
Václav Kubernát054cc992019-02-21 14:23:52 +010085
86 Usage:
Václav Kubernátf5f64f02019-03-19 17:15:47 +010087 /> create /module:pContainer
Václav Kubernát419d9172020-11-30 01:20:28 +010088 /> create /module:leafList['value']
Václav Kubernátf5f64f02019-03-19 17:15:47 +010089 /> create /module:list[key=value][anotherKey=value])";
Václav Kubernát24df80e2018-06-06 15:18:03 +020090 bool operator==(const create_& b) const;
Václav Kubernát2eaceb82018-10-08 19:56:30 +020091 dataPath_ m_path;
Václav Kubernát24df80e2018-06-06 15:18:03 +020092};
93
94struct delete_ : x3::position_tagged {
Václav Kubernát57272422019-02-08 12:48:24 +010095 static constexpr auto name = "delete";
Václav Kubernát419d9172020-11-30 01:20:28 +010096 static constexpr auto shortHelp = "delete - Delete a node.";
Václav Kubernát054cc992019-02-21 14:23:52 +010097 static constexpr auto longHelp = R"(
Václav Kubernát419d9172020-11-30 01:20:28 +010098 delete <path>
Václav Kubernát054cc992019-02-21 14:23:52 +010099
Václav Kubernát419d9172020-11-30 01:20:28 +0100100 Deletes a node specified by <path>.
101 Supported node types are leafs, list items, leaflist instance and presence
102 containers.
Václav Kubernát054cc992019-02-21 14:23:52 +0100103
104 Usage:
Václav Kubernátf5f64f02019-03-19 17:15:47 +0100105 /> delete /module:pContainer
Václav Kubernát419d9172020-11-30 01:20:28 +0100106 /> delete /module:leafList['value']
Václav Kubernátf5f64f02019-03-19 17:15:47 +0100107 /> delete /module:list[key=value][anotherKey=value])";
Václav Kubernát24df80e2018-06-06 15:18:03 +0200108 bool operator==(const delete_& b) const;
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200109 dataPath_ m_path;
Václav Kubernát24df80e2018-06-06 15:18:03 +0200110};
111
112struct set_ : x3::position_tagged {
Václav Kubernát57272422019-02-08 12:48:24 +0100113 static constexpr auto name = "set";
Václav Kubernát419d9172020-11-30 01:20:28 +0100114 static constexpr auto shortHelp = "set - Set value of a leaf.";
Václav Kubernát054cc992019-02-21 14:23:52 +0100115 static constexpr auto longHelp = R"(
Václav Kubernát419d9172020-11-30 01:20:28 +0100116 set <path_to_leaf> <value>
Václav Kubernát054cc992019-02-21 14:23:52 +0100117
Václav Kubernát419d9172020-11-30 01:20:28 +0100118 Sets the leaf specified by <path_to_leaf> to <value>.
Václav Kubernáta63a3fa2022-03-30 21:49:07 +0200119 Values of type string must be enclosed in quotation marks (" or ').
Václav Kubernát054cc992019-02-21 14:23:52 +0100120
121 Usage:
Václav Kubernáta63a3fa2022-03-30 21:49:07 +0200122 /> set /module:someNumber 123
123 /> set /module:someString 'abc'
124 /> set /module:someString "abc")";
Václav Kubernát24df80e2018-06-06 15:18:03 +0200125 bool operator==(const set_& b) const;
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200126 dataPath_ m_path;
Václav Kubernátebca2552018-06-08 19:06:02 +0200127 leaf_data_ m_data;
Václav Kubernát24df80e2018-06-06 15:18:03 +0200128};
129
Václav Kubernát812ee282018-08-30 17:10:03 +0200130struct commit_ : x3::position_tagged {
Václav Kubernát57272422019-02-08 12:48:24 +0100131 static constexpr auto name = "commit";
Václav Kubernát054cc992019-02-21 14:23:52 +0100132 static constexpr auto shortHelp = "commit - Commit current changes.";
133 static constexpr auto longHelp = R"(
134 commit
135
136 Commits the current changes. Accepts no arguments.
137
138 Usage:
139 /> commit)";
Václav Kubernát812ee282018-08-30 17:10:03 +0200140};
141
Václav Kubernátb6ff0b62018-08-30 16:14:53 +0200142struct get_ : x3::position_tagged {
Václav Kubernát57272422019-02-08 12:48:24 +0100143 static constexpr auto name = "get";
Václav Kubernát054cc992019-02-21 14:23:52 +0100144 static constexpr auto shortHelp = "get - Retrieve configuration from the server.";
145 static constexpr auto longHelp = R"(
146 get [path]
147
Václav Kubernát419d9172020-11-30 01:20:28 +0100148 Prints out content of the current datastore at a specified [path], or below
149 the current context tree.
Václav Kubernát054cc992019-02-21 14:23:52 +0100150
151 Usage:
152 /> get
153 /> get /module:path)";
Václav Kubernátb6ff0b62018-08-30 16:14:53 +0200154 bool operator==(const get_& b) const;
Václav Kubernáte066fe22022-04-06 00:32:26 +0200155 boost::optional<DatastoreTarget> m_dsTarget;
Václav Kubernát8f6bff32020-06-10 14:51:10 +0200156 boost::optional<boost::variant<dataPath_, module_>> m_path;
Václav Kubernátb6ff0b62018-08-30 16:14:53 +0200157};
Václav Kubernát812ee282018-08-30 17:10:03 +0200158
Václav Kubernát9cfcd872020-02-18 12:34:02 +0100159struct describe_ : x3::position_tagged {
160 static constexpr auto name = "describe";
161 static constexpr auto shortHelp = "describe - Print information about YANG tree path.";
162 static constexpr auto longHelp = R"(
163 describe <path>
164
Václav Kubernát419d9172020-11-30 01:20:28 +0100165 Shows documentation of YANG tree paths. In the YANG model, each item may
Václav Kubernát9cfcd872020-02-18 12:34:02 +0100166 have an optional `description` which often explains the function of that
Václav Kubernát419d9172020-11-30 01:20:28 +0100167 node to the end user. This command takes the description from the YANG model
168 and shows it to the user along with additional data, such as the type of the
169 node, units of leaf values, etc.
Václav Kubernát9cfcd872020-02-18 12:34:02 +0100170
171 Usage:
172 /> describe /module:node)";
173 bool operator==(const describe_& b) const;
174
175 boost::variant<schemaPath_, dataPath_> m_path;
176};
177
Václav Kubernát7160a132020-04-03 02:11:01 +0200178struct copy_ : x3::position_tagged {
179 static constexpr auto name = "copy";
Václav Kubernát419d9172020-11-30 01:20:28 +0100180 static constexpr auto shortHelp = "copy - Copy configuration.";
Václav Kubernát7160a132020-04-03 02:11:01 +0200181 static constexpr auto longHelp = R"(
182 copy <source> <destination>
183
Václav Kubernát419d9172020-11-30 01:20:28 +0100184 Copies configuration from <source> to <destination>.
185
Václav Kubernát7160a132020-04-03 02:11:01 +0200186 Usage:
187 /> copy running startup
188 /> copy startup running)";
189 bool operator==(const copy_& b) const;
190
191 Datastore m_source;
192 Datastore m_destination;
193};
194
Václav Kubernátbf65dd72020-05-28 02:32:31 +0200195enum class MoveMode {
196 Begin,
197 End,
198 Before,
199 After
200};
201
202struct move_ : x3::position_tagged {
203 static constexpr auto name = "move";
Václav Kubernát419d9172020-11-30 01:20:28 +0100204 static constexpr auto shortHelp = "move - Move (leaf)list instances.";
Václav Kubernátbf65dd72020-05-28 02:32:31 +0200205 static constexpr auto longHelp = R"(
Václav Kubernát419d9172020-11-30 01:20:28 +0100206 move <path> begin
207 move <path> end
208 move <path> before <key>
209 move <path> after <key>
210
211 Moves the instance specified by <path> to the position specified by the
212 specified by the second and third argument.
Václav Kubernátbf65dd72020-05-28 02:32:31 +0200213
214 Usage:
215 /> move mod:leaflist['abc'] begin
216 /> move mod:leaflist['def'] after 'abc'
Václav Kubernát419d9172020-11-30 01:20:28 +0100217 /> move mod:interfaces[name='eth0'] after [name='eth1'])";
Václav Kubernátbf65dd72020-05-28 02:32:31 +0200218 bool operator==(const move_& b) const;
219
220 dataPath_ m_source;
221
222 std::variant<yang::move::Absolute, yang::move::Relative> m_destination;
223};
224
Václav Kubernát70d7f7a2020-06-23 14:40:40 +0200225struct dump_ : x3::position_tagged {
226 static constexpr auto name = "dump";
Václav Kubernát419d9172020-11-30 01:20:28 +0100227 static constexpr auto shortHelp = "dump - Print out datastore content as JSON or XML.";
Václav Kubernát70d7f7a2020-06-23 14:40:40 +0200228 static constexpr auto longHelp = R"(
229 dump xml|json
230
Václav Kubernát419d9172020-11-30 01:20:28 +0100231 Prints out the content of the datastore. Supports JSON and XML.
232
Václav Kubernát70d7f7a2020-06-23 14:40:40 +0200233 Usage:
234 /> dump xml
235 /> dump json)";
236 bool operator==(const dump_& other) const;
237
238 DataFormat m_format;
239};
240
Václav Kubernátaa4250a2020-07-22 00:02:23 +0200241struct prepare_ : x3::position_tagged {
242 static constexpr auto name = "prepare";
Václav Kubernát419d9172020-11-30 01:20:28 +0100243 static constexpr auto shortHelp = "prepare - Initiate RPC/action.";
Václav Kubernáte7248b22020-06-26 15:38:59 +0200244 static constexpr auto longHelp = R"(
Václav Kubernátaa4250a2020-07-22 00:02:23 +0200245 prepare <path-to-rpc-or-action>
Václav Kubernáte7248b22020-06-26 15:38:59 +0200246
Václav Kubernát419d9172020-11-30 01:20:28 +0100247 This command enters a mode for entering input parameters for the RPC/action.
248 In this mode, you can use commands like `set` on nodes inside the RPC/action
249 to set the input. After setting the input, use `exec` to execute the
250 RPC/action.
Václav Kubernáte7248b22020-06-26 15:38:59 +0200251
252 Usage:
Václav Kubernát419d9172020-11-30 01:20:28 +0100253 /> prepare /mod:launch-nukes
254 /> set kilotons 1000
255 /> exec)";
Václav Kubernátaa4250a2020-07-22 00:02:23 +0200256 bool operator==(const prepare_& other) const;
Václav Kubernáte7248b22020-06-26 15:38:59 +0200257
258 dataPath_ m_path;
259};
260
261struct exec_ : x3::position_tagged {
262 static constexpr auto name = "exec";
Václav Kubernát419d9172020-11-30 01:20:28 +0100263 static constexpr auto shortHelp = "exec - Execute RPC/action.";
Václav Kubernáte7248b22020-06-26 15:38:59 +0200264 static constexpr auto longHelp = R"(
Václav Kubernátd8408e02020-12-02 05:13:27 +0100265 exec [path]
Václav Kubernáte7248b22020-06-26 15:38:59 +0200266
Václav Kubernát419d9172020-11-30 01:20:28 +0100267 This command executes the RPC/action you have previously initiated via the
268 `prepare` command.
Václav Kubernáte7248b22020-06-26 15:38:59 +0200269
Václav Kubernátd8408e02020-12-02 05:13:27 +0100270 If the RPC/action has no input parameters, it can be directly execute via
271 `exec` without usgin `prepare`.
272
Václav Kubernáte7248b22020-06-26 15:38:59 +0200273 Usage:
Václav Kubernátd8408e02020-12-02 05:13:27 +0100274 /> exec
275 /> exec /mod:myRpc)";
Václav Kubernáte7248b22020-06-26 15:38:59 +0200276 bool operator==(const exec_& other) const;
Václav Kubernátd8408e02020-12-02 05:13:27 +0100277
278 boost::optional<dataPath_> m_path;
Václav Kubernáte7248b22020-06-26 15:38:59 +0200279};
280
281struct cancel_ : x3::position_tagged {
282 static constexpr auto name = "cancel";
Václav Kubernát419d9172020-11-30 01:20:28 +0100283 static constexpr auto shortHelp = "cancel - Cancel an ongoing RPC/action input.";
Václav Kubernáte7248b22020-06-26 15:38:59 +0200284 static constexpr auto longHelp = R"(
285 cancel
286
Václav Kubernát419d9172020-11-30 01:20:28 +0100287 This command cancels a previously entered RPC/action context.
Václav Kubernáte7248b22020-06-26 15:38:59 +0200288
289 Usage:
290 /> cancel)";
291 bool operator==(const cancel_& other) const;
292};
293
Václav Kubernát162165e2021-02-22 09:46:53 +0100294struct switch_ : x3::position_tagged {
295 static constexpr auto name = "switch";
296 static constexpr auto shortHelp = "switch - Switch datastore target.";
297 static constexpr auto longHelp = R"(
298 switch <target>
299
300 This command switches the datastore target. Available targets are:
301
302 operational:
303 - reads from operational, writes to running
304 startup:
305 - reads from startup, writes to startup
306 running:
307 - reads from running, writes to running
308
309
310 Usage:
311 /> switch running
312 /> switch startup
313 /> switch operational)";
314 bool operator==(const switch_& other) const;
315 DatastoreTarget m_target;
316};
317
Václav Kubernát054cc992019-02-21 14:23:52 +0100318struct help_;
Václav Kubernát162165e2021-02-22 09:46:53 +0100319using CommandTypes = boost::mpl::vector<cancel_, cd_, commit_, copy_, create_, delete_, describe_, discard_, dump_, exec_, get_, help_, ls_, move_, prepare_, set_, switch_>;
Václav Kubernát054cc992019-02-21 14:23:52 +0100320struct help_ : x3::position_tagged {
321 static constexpr auto name = "help";
322 static constexpr auto shortHelp = "help - Print help for commands.";
323 static constexpr auto longHelp = R"(
324 help [command_name]
325
326 Print help for command_name. If used without an argument,
327 print short help for all commands.
328
329 Usage:
330 /> help
331 /> help cd
332 /> help help)";
333 bool operator==(const help_& b) const;
334
335 // The help command has got one optional argument – a command name (type).
336 // All commands are saved in CommandTypes, so we could just use that, but
337 // that way, Spirit would be default constructing the command structs,
338 // which is undesirable, so firstly we use mpl::transform to wrap
339 // CommandTypes with boost::type:
340 using WrappedCommandTypes = boost::mpl::transform<CommandTypes, boost::type<boost::mpl::_>>::type;
341 // Next, we create a variant over the wrapped types:
342 using CommandTypesVariant = boost::make_variant_over<WrappedCommandTypes>::type;
343 // Finally, we wrap the variant with boost::optional:
344 boost::optional<CommandTypesVariant> m_cmd;
345};
346
Václav Kubernát57272422019-02-08 12:48:24 +0100347// TODO: The usage of MPL won't be necessary after std::variant support is added to Spirit
348// https://github.com/boostorg/spirit/issues/270
Václav Kubernát57272422019-02-08 12:48:24 +0100349using command_ = boost::make_variant_over<CommandTypes>::type;
Václav Kubernát24df80e2018-06-06 15:18:03 +0200350
Václav Kubernáte7d4aea2018-09-11 18:15:48 +0200351BOOST_FUSION_ADAPT_STRUCT(ls_, m_options, m_path)
Václav Kubernát24df80e2018-06-06 15:18:03 +0200352BOOST_FUSION_ADAPT_STRUCT(cd_, m_path)
353BOOST_FUSION_ADAPT_STRUCT(create_, m_path)
354BOOST_FUSION_ADAPT_STRUCT(delete_, m_path)
Václav Kubernát24df80e2018-06-06 15:18:03 +0200355BOOST_FUSION_ADAPT_STRUCT(set_, m_path, m_data)
Václav Kubernátab538992019-03-06 15:30:50 +0100356BOOST_FUSION_ADAPT_STRUCT(enum_, m_value)
Václav Kubernátdab73ca2020-10-26 23:44:43 +0100357BOOST_FUSION_ADAPT_STRUCT(bits_, m_bits)
Václav Kubernátab538992019-03-06 15:30:50 +0100358BOOST_FUSION_ADAPT_STRUCT(binary_, m_value)
Václav Kubernáteeb38842019-03-20 19:46:05 +0100359BOOST_FUSION_ADAPT_STRUCT(identityRef_, m_prefix, m_value)
Václav Kubernát812ee282018-08-30 17:10:03 +0200360BOOST_FUSION_ADAPT_STRUCT(commit_)
Václav Kubernát9cfcd872020-02-18 12:34:02 +0100361BOOST_FUSION_ADAPT_STRUCT(describe_, m_path)
Václav Kubernát054cc992019-02-21 14:23:52 +0100362BOOST_FUSION_ADAPT_STRUCT(help_, m_cmd)
Václav Kubernát6d791432018-10-25 16:00:35 +0200363BOOST_FUSION_ADAPT_STRUCT(discard_)
Václav Kubernáte066fe22022-04-06 00:32:26 +0200364BOOST_FUSION_ADAPT_STRUCT(get_, m_dsTarget, m_path)
Václav Kubernát7160a132020-04-03 02:11:01 +0200365BOOST_FUSION_ADAPT_STRUCT(copy_, m_source, m_destination)
Václav Kubernátbf65dd72020-05-28 02:32:31 +0200366BOOST_FUSION_ADAPT_STRUCT(move_, m_source, m_destination)
Václav Kubernát70d7f7a2020-06-23 14:40:40 +0200367BOOST_FUSION_ADAPT_STRUCT(dump_, m_format)
Václav Kubernátaa4250a2020-07-22 00:02:23 +0200368BOOST_FUSION_ADAPT_STRUCT(prepare_, m_path)
Václav Kubernátd8408e02020-12-02 05:13:27 +0100369BOOST_FUSION_ADAPT_STRUCT(exec_, m_path)
Václav Kubernát162165e2021-02-22 09:46:53 +0100370BOOST_FUSION_ADAPT_STRUCT(switch_, m_target)