blob: 0d7a47615de45b73b031c0c5be5e0101d813b7f8 [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át8f6bff32020-06-10 14:51:10 +0200155 boost::optional<boost::variant<dataPath_, module_>> m_path;
Václav Kubernátb6ff0b62018-08-30 16:14:53 +0200156};
Václav Kubernát812ee282018-08-30 17:10:03 +0200157
Václav Kubernát9cfcd872020-02-18 12:34:02 +0100158struct describe_ : x3::position_tagged {
159 static constexpr auto name = "describe";
160 static constexpr auto shortHelp = "describe - Print information about YANG tree path.";
161 static constexpr auto longHelp = R"(
162 describe <path>
163
Václav Kubernát419d9172020-11-30 01:20:28 +0100164 Shows documentation of YANG tree paths. In the YANG model, each item may
Václav Kubernát9cfcd872020-02-18 12:34:02 +0100165 have an optional `description` which often explains the function of that
Václav Kubernát419d9172020-11-30 01:20:28 +0100166 node to the end user. This command takes the description from the YANG model
167 and shows it to the user along with additional data, such as the type of the
168 node, units of leaf values, etc.
Václav Kubernát9cfcd872020-02-18 12:34:02 +0100169
170 Usage:
171 /> describe /module:node)";
172 bool operator==(const describe_& b) const;
173
174 boost::variant<schemaPath_, dataPath_> m_path;
175};
176
Václav Kubernát7160a132020-04-03 02:11:01 +0200177struct copy_ : x3::position_tagged {
178 static constexpr auto name = "copy";
Václav Kubernát419d9172020-11-30 01:20:28 +0100179 static constexpr auto shortHelp = "copy - Copy configuration.";
Václav Kubernát7160a132020-04-03 02:11:01 +0200180 static constexpr auto longHelp = R"(
181 copy <source> <destination>
182
Václav Kubernát419d9172020-11-30 01:20:28 +0100183 Copies configuration from <source> to <destination>.
184
Václav Kubernát7160a132020-04-03 02:11:01 +0200185 Usage:
186 /> copy running startup
187 /> copy startup running)";
188 bool operator==(const copy_& b) const;
189
190 Datastore m_source;
191 Datastore m_destination;
192};
193
Václav Kubernátbf65dd72020-05-28 02:32:31 +0200194enum class MoveMode {
195 Begin,
196 End,
197 Before,
198 After
199};
200
201struct move_ : x3::position_tagged {
202 static constexpr auto name = "move";
Václav Kubernát419d9172020-11-30 01:20:28 +0100203 static constexpr auto shortHelp = "move - Move (leaf)list instances.";
Václav Kubernátbf65dd72020-05-28 02:32:31 +0200204 static constexpr auto longHelp = R"(
Václav Kubernát419d9172020-11-30 01:20:28 +0100205 move <path> begin
206 move <path> end
207 move <path> before <key>
208 move <path> after <key>
209
210 Moves the instance specified by <path> to the position specified by the
211 specified by the second and third argument.
Václav Kubernátbf65dd72020-05-28 02:32:31 +0200212
213 Usage:
214 /> move mod:leaflist['abc'] begin
215 /> move mod:leaflist['def'] after 'abc'
Václav Kubernát419d9172020-11-30 01:20:28 +0100216 /> move mod:interfaces[name='eth0'] after [name='eth1'])";
Václav Kubernátbf65dd72020-05-28 02:32:31 +0200217 bool operator==(const move_& b) const;
218
219 dataPath_ m_source;
220
221 std::variant<yang::move::Absolute, yang::move::Relative> m_destination;
222};
223
Václav Kubernát70d7f7a2020-06-23 14:40:40 +0200224struct dump_ : x3::position_tagged {
225 static constexpr auto name = "dump";
Václav Kubernát419d9172020-11-30 01:20:28 +0100226 static constexpr auto shortHelp = "dump - Print out datastore content as JSON or XML.";
Václav Kubernát70d7f7a2020-06-23 14:40:40 +0200227 static constexpr auto longHelp = R"(
228 dump xml|json
229
Václav Kubernát419d9172020-11-30 01:20:28 +0100230 Prints out the content of the datastore. Supports JSON and XML.
231
Václav Kubernát70d7f7a2020-06-23 14:40:40 +0200232 Usage:
233 /> dump xml
234 /> dump json)";
235 bool operator==(const dump_& other) const;
236
237 DataFormat m_format;
238};
239
Václav Kubernátaa4250a2020-07-22 00:02:23 +0200240struct prepare_ : x3::position_tagged {
241 static constexpr auto name = "prepare";
Václav Kubernát419d9172020-11-30 01:20:28 +0100242 static constexpr auto shortHelp = "prepare - Initiate RPC/action.";
Václav Kubernáte7248b22020-06-26 15:38:59 +0200243 static constexpr auto longHelp = R"(
Václav Kubernátaa4250a2020-07-22 00:02:23 +0200244 prepare <path-to-rpc-or-action>
Václav Kubernáte7248b22020-06-26 15:38:59 +0200245
Václav Kubernát419d9172020-11-30 01:20:28 +0100246 This command enters a mode for entering input parameters for the RPC/action.
247 In this mode, you can use commands like `set` on nodes inside the RPC/action
248 to set the input. After setting the input, use `exec` to execute the
249 RPC/action.
Václav Kubernáte7248b22020-06-26 15:38:59 +0200250
251 Usage:
Václav Kubernát419d9172020-11-30 01:20:28 +0100252 /> prepare /mod:launch-nukes
253 /> set kilotons 1000
254 /> exec)";
Václav Kubernátaa4250a2020-07-22 00:02:23 +0200255 bool operator==(const prepare_& other) const;
Václav Kubernáte7248b22020-06-26 15:38:59 +0200256
257 dataPath_ m_path;
258};
259
260struct exec_ : x3::position_tagged {
261 static constexpr auto name = "exec";
Václav Kubernát419d9172020-11-30 01:20:28 +0100262 static constexpr auto shortHelp = "exec - Execute RPC/action.";
Václav Kubernáte7248b22020-06-26 15:38:59 +0200263 static constexpr auto longHelp = R"(
Václav Kubernátd8408e02020-12-02 05:13:27 +0100264 exec [path]
Václav Kubernáte7248b22020-06-26 15:38:59 +0200265
Václav Kubernát419d9172020-11-30 01:20:28 +0100266 This command executes the RPC/action you have previously initiated via the
267 `prepare` command.
Václav Kubernáte7248b22020-06-26 15:38:59 +0200268
Václav Kubernátd8408e02020-12-02 05:13:27 +0100269 If the RPC/action has no input parameters, it can be directly execute via
270 `exec` without usgin `prepare`.
271
Václav Kubernáte7248b22020-06-26 15:38:59 +0200272 Usage:
Václav Kubernátd8408e02020-12-02 05:13:27 +0100273 /> exec
274 /> exec /mod:myRpc)";
Václav Kubernáte7248b22020-06-26 15:38:59 +0200275 bool operator==(const exec_& other) const;
Václav Kubernátd8408e02020-12-02 05:13:27 +0100276
277 boost::optional<dataPath_> m_path;
Václav Kubernáte7248b22020-06-26 15:38:59 +0200278};
279
280struct cancel_ : x3::position_tagged {
281 static constexpr auto name = "cancel";
Václav Kubernát419d9172020-11-30 01:20:28 +0100282 static constexpr auto shortHelp = "cancel - Cancel an ongoing RPC/action input.";
Václav Kubernáte7248b22020-06-26 15:38:59 +0200283 static constexpr auto longHelp = R"(
284 cancel
285
Václav Kubernát419d9172020-11-30 01:20:28 +0100286 This command cancels a previously entered RPC/action context.
Václav Kubernáte7248b22020-06-26 15:38:59 +0200287
288 Usage:
289 /> cancel)";
290 bool operator==(const cancel_& other) const;
291};
292
Václav Kubernát162165e2021-02-22 09:46:53 +0100293struct switch_ : x3::position_tagged {
294 static constexpr auto name = "switch";
295 static constexpr auto shortHelp = "switch - Switch datastore target.";
296 static constexpr auto longHelp = R"(
297 switch <target>
298
299 This command switches the datastore target. Available targets are:
300
301 operational:
302 - reads from operational, writes to running
303 startup:
304 - reads from startup, writes to startup
305 running:
306 - reads from running, writes to running
307
308
309 Usage:
310 /> switch running
311 /> switch startup
312 /> switch operational)";
313 bool operator==(const switch_& other) const;
314 DatastoreTarget m_target;
315};
316
Václav Kubernát054cc992019-02-21 14:23:52 +0100317struct help_;
Václav Kubernát162165e2021-02-22 09:46:53 +0100318using 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 +0100319struct help_ : x3::position_tagged {
320 static constexpr auto name = "help";
321 static constexpr auto shortHelp = "help - Print help for commands.";
322 static constexpr auto longHelp = R"(
323 help [command_name]
324
325 Print help for command_name. If used without an argument,
326 print short help for all commands.
327
328 Usage:
329 /> help
330 /> help cd
331 /> help help)";
332 bool operator==(const help_& b) const;
333
334 // The help command has got one optional argument – a command name (type).
335 // All commands are saved in CommandTypes, so we could just use that, but
336 // that way, Spirit would be default constructing the command structs,
337 // which is undesirable, so firstly we use mpl::transform to wrap
338 // CommandTypes with boost::type:
339 using WrappedCommandTypes = boost::mpl::transform<CommandTypes, boost::type<boost::mpl::_>>::type;
340 // Next, we create a variant over the wrapped types:
341 using CommandTypesVariant = boost::make_variant_over<WrappedCommandTypes>::type;
342 // Finally, we wrap the variant with boost::optional:
343 boost::optional<CommandTypesVariant> m_cmd;
344};
345
Václav Kubernát57272422019-02-08 12:48:24 +0100346// TODO: The usage of MPL won't be necessary after std::variant support is added to Spirit
347// https://github.com/boostorg/spirit/issues/270
Václav Kubernát57272422019-02-08 12:48:24 +0100348using command_ = boost::make_variant_over<CommandTypes>::type;
Václav Kubernát24df80e2018-06-06 15:18:03 +0200349
Václav Kubernáte7d4aea2018-09-11 18:15:48 +0200350BOOST_FUSION_ADAPT_STRUCT(ls_, m_options, m_path)
Václav Kubernát24df80e2018-06-06 15:18:03 +0200351BOOST_FUSION_ADAPT_STRUCT(cd_, m_path)
352BOOST_FUSION_ADAPT_STRUCT(create_, m_path)
353BOOST_FUSION_ADAPT_STRUCT(delete_, m_path)
Václav Kubernát24df80e2018-06-06 15:18:03 +0200354BOOST_FUSION_ADAPT_STRUCT(set_, m_path, m_data)
Václav Kubernátab538992019-03-06 15:30:50 +0100355BOOST_FUSION_ADAPT_STRUCT(enum_, m_value)
Václav Kubernátdab73ca2020-10-26 23:44:43 +0100356BOOST_FUSION_ADAPT_STRUCT(bits_, m_bits)
Václav Kubernátab538992019-03-06 15:30:50 +0100357BOOST_FUSION_ADAPT_STRUCT(binary_, m_value)
Václav Kubernáteeb38842019-03-20 19:46:05 +0100358BOOST_FUSION_ADAPT_STRUCT(identityRef_, m_prefix, m_value)
Václav Kubernát812ee282018-08-30 17:10:03 +0200359BOOST_FUSION_ADAPT_STRUCT(commit_)
Václav Kubernát9cfcd872020-02-18 12:34:02 +0100360BOOST_FUSION_ADAPT_STRUCT(describe_, m_path)
Václav Kubernát054cc992019-02-21 14:23:52 +0100361BOOST_FUSION_ADAPT_STRUCT(help_, m_cmd)
Václav Kubernát6d791432018-10-25 16:00:35 +0200362BOOST_FUSION_ADAPT_STRUCT(discard_)
Václav Kubernátb6ff0b62018-08-30 16:14:53 +0200363BOOST_FUSION_ADAPT_STRUCT(get_, m_path)
Václav Kubernát7160a132020-04-03 02:11:01 +0200364BOOST_FUSION_ADAPT_STRUCT(copy_, m_source, m_destination)
Václav Kubernátbf65dd72020-05-28 02:32:31 +0200365BOOST_FUSION_ADAPT_STRUCT(move_, m_source, m_destination)
Václav Kubernát70d7f7a2020-06-23 14:40:40 +0200366BOOST_FUSION_ADAPT_STRUCT(dump_, m_format)
Václav Kubernátaa4250a2020-07-22 00:02:23 +0200367BOOST_FUSION_ADAPT_STRUCT(prepare_, m_path)
Václav Kubernátd8408e02020-12-02 05:13:27 +0100368BOOST_FUSION_ADAPT_STRUCT(exec_, m_path)
Václav Kubernát162165e2021-02-22 09:46:53 +0100369BOOST_FUSION_ADAPT_STRUCT(switch_, m_target)