blob: d0a3f3eb9a5cca3cee857086cb4620c6152d0dbb [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át054cc992019-02-21 14:23:52 +0100119
120 Usage:
121 /> set /module:leaf 123
122 /> set /module:leaf abc)";
Václav Kubernát24df80e2018-06-06 15:18:03 +0200123 bool operator==(const set_& b) const;
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200124 dataPath_ m_path;
Václav Kubernátebca2552018-06-08 19:06:02 +0200125 leaf_data_ m_data;
Václav Kubernát24df80e2018-06-06 15:18:03 +0200126};
127
Václav Kubernát812ee282018-08-30 17:10:03 +0200128struct commit_ : x3::position_tagged {
Václav Kubernát57272422019-02-08 12:48:24 +0100129 static constexpr auto name = "commit";
Václav Kubernát054cc992019-02-21 14:23:52 +0100130 static constexpr auto shortHelp = "commit - Commit current changes.";
131 static constexpr auto longHelp = R"(
132 commit
133
134 Commits the current changes. Accepts no arguments.
135
136 Usage:
137 /> commit)";
Václav Kubernát812ee282018-08-30 17:10:03 +0200138};
139
Václav Kubernátb6ff0b62018-08-30 16:14:53 +0200140struct get_ : x3::position_tagged {
Václav Kubernát57272422019-02-08 12:48:24 +0100141 static constexpr auto name = "get";
Václav Kubernát054cc992019-02-21 14:23:52 +0100142 static constexpr auto shortHelp = "get - Retrieve configuration from the server.";
143 static constexpr auto longHelp = R"(
144 get [path]
145
Václav Kubernát419d9172020-11-30 01:20:28 +0100146 Prints out content of the current datastore at a specified [path], or below
147 the current context tree.
Václav Kubernát054cc992019-02-21 14:23:52 +0100148
149 Usage:
150 /> get
151 /> get /module:path)";
Václav Kubernátb6ff0b62018-08-30 16:14:53 +0200152 bool operator==(const get_& b) const;
Václav Kubernát8f6bff32020-06-10 14:51:10 +0200153 boost::optional<boost::variant<dataPath_, module_>> m_path;
Václav Kubernátb6ff0b62018-08-30 16:14:53 +0200154};
Václav Kubernát812ee282018-08-30 17:10:03 +0200155
Václav Kubernát9cfcd872020-02-18 12:34:02 +0100156struct describe_ : x3::position_tagged {
157 static constexpr auto name = "describe";
158 static constexpr auto shortHelp = "describe - Print information about YANG tree path.";
159 static constexpr auto longHelp = R"(
160 describe <path>
161
Václav Kubernát419d9172020-11-30 01:20:28 +0100162 Shows documentation of YANG tree paths. In the YANG model, each item may
Václav Kubernát9cfcd872020-02-18 12:34:02 +0100163 have an optional `description` which often explains the function of that
Václav Kubernát419d9172020-11-30 01:20:28 +0100164 node to the end user. This command takes the description from the YANG model
165 and shows it to the user along with additional data, such as the type of the
166 node, units of leaf values, etc.
Václav Kubernát9cfcd872020-02-18 12:34:02 +0100167
168 Usage:
169 /> describe /module:node)";
170 bool operator==(const describe_& b) const;
171
172 boost::variant<schemaPath_, dataPath_> m_path;
173};
174
Václav Kubernát7160a132020-04-03 02:11:01 +0200175struct copy_ : x3::position_tagged {
176 static constexpr auto name = "copy";
Václav Kubernát419d9172020-11-30 01:20:28 +0100177 static constexpr auto shortHelp = "copy - Copy configuration.";
Václav Kubernát7160a132020-04-03 02:11:01 +0200178 static constexpr auto longHelp = R"(
179 copy <source> <destination>
180
Václav Kubernát419d9172020-11-30 01:20:28 +0100181 Copies configuration from <source> to <destination>.
182
Václav Kubernát7160a132020-04-03 02:11:01 +0200183 Usage:
184 /> copy running startup
185 /> copy startup running)";
186 bool operator==(const copy_& b) const;
187
188 Datastore m_source;
189 Datastore m_destination;
190};
191
Václav Kubernátbf65dd72020-05-28 02:32:31 +0200192enum class MoveMode {
193 Begin,
194 End,
195 Before,
196 After
197};
198
199struct move_ : x3::position_tagged {
200 static constexpr auto name = "move";
Václav Kubernát419d9172020-11-30 01:20:28 +0100201 static constexpr auto shortHelp = "move - Move (leaf)list instances.";
Václav Kubernátbf65dd72020-05-28 02:32:31 +0200202 static constexpr auto longHelp = R"(
Václav Kubernát419d9172020-11-30 01:20:28 +0100203 move <path> begin
204 move <path> end
205 move <path> before <key>
206 move <path> after <key>
207
208 Moves the instance specified by <path> to the position specified by the
209 specified by the second and third argument.
Václav Kubernátbf65dd72020-05-28 02:32:31 +0200210
211 Usage:
212 /> move mod:leaflist['abc'] begin
213 /> move mod:leaflist['def'] after 'abc'
Václav Kubernát419d9172020-11-30 01:20:28 +0100214 /> move mod:interfaces[name='eth0'] after [name='eth1'])";
Václav Kubernátbf65dd72020-05-28 02:32:31 +0200215 bool operator==(const move_& b) const;
216
217 dataPath_ m_source;
218
219 std::variant<yang::move::Absolute, yang::move::Relative> m_destination;
220};
221
Václav Kubernát70d7f7a2020-06-23 14:40:40 +0200222struct dump_ : x3::position_tagged {
223 static constexpr auto name = "dump";
Václav Kubernát419d9172020-11-30 01:20:28 +0100224 static constexpr auto shortHelp = "dump - Print out datastore content as JSON or XML.";
Václav Kubernát70d7f7a2020-06-23 14:40:40 +0200225 static constexpr auto longHelp = R"(
226 dump xml|json
227
Václav Kubernát419d9172020-11-30 01:20:28 +0100228 Prints out the content of the datastore. Supports JSON and XML.
229
Václav Kubernát70d7f7a2020-06-23 14:40:40 +0200230 Usage:
231 /> dump xml
232 /> dump json)";
233 bool operator==(const dump_& other) const;
234
235 DataFormat m_format;
236};
237
Václav Kubernátaa4250a2020-07-22 00:02:23 +0200238struct prepare_ : x3::position_tagged {
239 static constexpr auto name = "prepare";
Václav Kubernát419d9172020-11-30 01:20:28 +0100240 static constexpr auto shortHelp = "prepare - Initiate RPC/action.";
Václav Kubernáte7248b22020-06-26 15:38:59 +0200241 static constexpr auto longHelp = R"(
Václav Kubernátaa4250a2020-07-22 00:02:23 +0200242 prepare <path-to-rpc-or-action>
Václav Kubernáte7248b22020-06-26 15:38:59 +0200243
Václav Kubernát419d9172020-11-30 01:20:28 +0100244 This command enters a mode for entering input parameters for the RPC/action.
245 In this mode, you can use commands like `set` on nodes inside the RPC/action
246 to set the input. After setting the input, use `exec` to execute the
247 RPC/action.
Václav Kubernáte7248b22020-06-26 15:38:59 +0200248
249 Usage:
Václav Kubernát419d9172020-11-30 01:20:28 +0100250 /> prepare /mod:launch-nukes
251 /> set kilotons 1000
252 /> exec)";
Václav Kubernátaa4250a2020-07-22 00:02:23 +0200253 bool operator==(const prepare_& other) const;
Václav Kubernáte7248b22020-06-26 15:38:59 +0200254
255 dataPath_ m_path;
256};
257
258struct exec_ : x3::position_tagged {
259 static constexpr auto name = "exec";
Václav Kubernát419d9172020-11-30 01:20:28 +0100260 static constexpr auto shortHelp = "exec - Execute RPC/action.";
Václav Kubernáte7248b22020-06-26 15:38:59 +0200261 static constexpr auto longHelp = R"(
Václav Kubernátd8408e02020-12-02 05:13:27 +0100262 exec [path]
Václav Kubernáte7248b22020-06-26 15:38:59 +0200263
Václav Kubernát419d9172020-11-30 01:20:28 +0100264 This command executes the RPC/action you have previously initiated via the
265 `prepare` command.
Václav Kubernáte7248b22020-06-26 15:38:59 +0200266
Václav Kubernátd8408e02020-12-02 05:13:27 +0100267 If the RPC/action has no input parameters, it can be directly execute via
268 `exec` without usgin `prepare`.
269
Václav Kubernáte7248b22020-06-26 15:38:59 +0200270 Usage:
Václav Kubernátd8408e02020-12-02 05:13:27 +0100271 /> exec
272 /> exec /mod:myRpc)";
Václav Kubernáte7248b22020-06-26 15:38:59 +0200273 bool operator==(const exec_& other) const;
Václav Kubernátd8408e02020-12-02 05:13:27 +0100274
275 boost::optional<dataPath_> m_path;
Václav Kubernáte7248b22020-06-26 15:38:59 +0200276};
277
278struct cancel_ : x3::position_tagged {
279 static constexpr auto name = "cancel";
Václav Kubernát419d9172020-11-30 01:20:28 +0100280 static constexpr auto shortHelp = "cancel - Cancel an ongoing RPC/action input.";
Václav Kubernáte7248b22020-06-26 15:38:59 +0200281 static constexpr auto longHelp = R"(
282 cancel
283
Václav Kubernát419d9172020-11-30 01:20:28 +0100284 This command cancels a previously entered RPC/action context.
Václav Kubernáte7248b22020-06-26 15:38:59 +0200285
286 Usage:
287 /> cancel)";
288 bool operator==(const cancel_& other) const;
289};
290
Václav Kubernát162165e2021-02-22 09:46:53 +0100291struct switch_ : x3::position_tagged {
292 static constexpr auto name = "switch";
293 static constexpr auto shortHelp = "switch - Switch datastore target.";
294 static constexpr auto longHelp = R"(
295 switch <target>
296
297 This command switches the datastore target. Available targets are:
298
299 operational:
300 - reads from operational, writes to running
301 startup:
302 - reads from startup, writes to startup
303 running:
304 - reads from running, writes to running
305
306
307 Usage:
308 /> switch running
309 /> switch startup
310 /> switch operational)";
311 bool operator==(const switch_& other) const;
312 DatastoreTarget m_target;
313};
314
Václav Kubernát054cc992019-02-21 14:23:52 +0100315struct help_;
Václav Kubernát162165e2021-02-22 09:46:53 +0100316using 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 +0100317struct help_ : x3::position_tagged {
318 static constexpr auto name = "help";
319 static constexpr auto shortHelp = "help - Print help for commands.";
320 static constexpr auto longHelp = R"(
321 help [command_name]
322
323 Print help for command_name. If used without an argument,
324 print short help for all commands.
325
326 Usage:
327 /> help
328 /> help cd
329 /> help help)";
330 bool operator==(const help_& b) const;
331
332 // The help command has got one optional argument – a command name (type).
333 // All commands are saved in CommandTypes, so we could just use that, but
334 // that way, Spirit would be default constructing the command structs,
335 // which is undesirable, so firstly we use mpl::transform to wrap
336 // CommandTypes with boost::type:
337 using WrappedCommandTypes = boost::mpl::transform<CommandTypes, boost::type<boost::mpl::_>>::type;
338 // Next, we create a variant over the wrapped types:
339 using CommandTypesVariant = boost::make_variant_over<WrappedCommandTypes>::type;
340 // Finally, we wrap the variant with boost::optional:
341 boost::optional<CommandTypesVariant> m_cmd;
342};
343
Václav Kubernát57272422019-02-08 12:48:24 +0100344// TODO: The usage of MPL won't be necessary after std::variant support is added to Spirit
345// https://github.com/boostorg/spirit/issues/270
Václav Kubernát57272422019-02-08 12:48:24 +0100346using command_ = boost::make_variant_over<CommandTypes>::type;
Václav Kubernát24df80e2018-06-06 15:18:03 +0200347
Václav Kubernáte7d4aea2018-09-11 18:15:48 +0200348BOOST_FUSION_ADAPT_STRUCT(ls_, m_options, m_path)
Václav Kubernát24df80e2018-06-06 15:18:03 +0200349BOOST_FUSION_ADAPT_STRUCT(cd_, m_path)
350BOOST_FUSION_ADAPT_STRUCT(create_, m_path)
351BOOST_FUSION_ADAPT_STRUCT(delete_, m_path)
Václav Kubernát24df80e2018-06-06 15:18:03 +0200352BOOST_FUSION_ADAPT_STRUCT(set_, m_path, m_data)
Václav Kubernátab538992019-03-06 15:30:50 +0100353BOOST_FUSION_ADAPT_STRUCT(enum_, m_value)
Václav Kubernátdab73ca2020-10-26 23:44:43 +0100354BOOST_FUSION_ADAPT_STRUCT(bits_, m_bits)
Václav Kubernátab538992019-03-06 15:30:50 +0100355BOOST_FUSION_ADAPT_STRUCT(binary_, m_value)
Václav Kubernáteeb38842019-03-20 19:46:05 +0100356BOOST_FUSION_ADAPT_STRUCT(identityRef_, m_prefix, m_value)
Václav Kubernát812ee282018-08-30 17:10:03 +0200357BOOST_FUSION_ADAPT_STRUCT(commit_)
Václav Kubernát9cfcd872020-02-18 12:34:02 +0100358BOOST_FUSION_ADAPT_STRUCT(describe_, m_path)
Václav Kubernát054cc992019-02-21 14:23:52 +0100359BOOST_FUSION_ADAPT_STRUCT(help_, m_cmd)
Václav Kubernát6d791432018-10-25 16:00:35 +0200360BOOST_FUSION_ADAPT_STRUCT(discard_)
Václav Kubernátb6ff0b62018-08-30 16:14:53 +0200361BOOST_FUSION_ADAPT_STRUCT(get_, m_path)
Václav Kubernát7160a132020-04-03 02:11:01 +0200362BOOST_FUSION_ADAPT_STRUCT(copy_, m_source, m_destination)
Václav Kubernátbf65dd72020-05-28 02:32:31 +0200363BOOST_FUSION_ADAPT_STRUCT(move_, m_source, m_destination)
Václav Kubernát70d7f7a2020-06-23 14:40:40 +0200364BOOST_FUSION_ADAPT_STRUCT(dump_, m_format)
Václav Kubernátaa4250a2020-07-22 00:02:23 +0200365BOOST_FUSION_ADAPT_STRUCT(prepare_, m_path)
Václav Kubernátd8408e02020-12-02 05:13:27 +0100366BOOST_FUSION_ADAPT_STRUCT(exec_, m_path)
Václav Kubernát162165e2021-02-22 09:46:53 +0100367BOOST_FUSION_ADAPT_STRUCT(switch_, m_target)