blob: 9ec2740496fd51b53c6beeffb06af58c50e94eef [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át6a7dd4d2020-06-23 22:44:13 +020014#include "yang_operations.hpp"
Václav Kubernát24df80e2018-06-06 15:18:03 +020015
16namespace x3 = boost::spirit::x3;
Václav Kubernát24df80e2018-06-06 15:18:03 +020017
Václav Kubernát7707cae2020-01-16 12:04:53 +010018using keyValue_ = std::pair<std::string, leaf_data_>;
Václav Kubernát24df80e2018-06-06 15:18:03 +020019
Václav Kubernáte7d4aea2018-09-11 18:15:48 +020020enum class LsOption {
21 Recursive
22};
23
Václav Kubernát6d791432018-10-25 16:00:35 +020024struct discard_ : x3::position_tagged {
Václav Kubernát57272422019-02-08 12:48:24 +010025 static constexpr auto name = "discard";
Václav Kubernát054cc992019-02-21 14:23:52 +010026 static constexpr auto shortHelp = "discard - Discard current changes.";
27 static constexpr auto longHelp = R"(
28 discard
29
30 Discards current changes. Accepts no arguments.
31
32 Usage:
33 /> discard)";
Václav Kubernát6d791432018-10-25 16:00:35 +020034 bool operator==(const discard_& b) const;
35};
36
Václav Kubernát11afac72018-07-18 14:59:53 +020037struct ls_ : x3::position_tagged {
Václav Kubernát57272422019-02-08 12:48:24 +010038 static constexpr auto name = "ls";
Václav Kubernát054cc992019-02-21 14:23:52 +010039 static constexpr auto shortHelp = "ls - List available nodes.";
40 static constexpr auto longHelp = R"(
41 ls [--recursive] [path]
42
Václav Kubernát419d9172020-11-30 01:20:28 +010043 Lists available child nodes in the current context node. Optionally accepts
44 a path argument. Accepts both schema paths and data paths. Path starting
45 with a forward slash means an absolute path.
46
47 Options:
48 --recursive makes `ls` work recursively
Václav Kubernát054cc992019-02-21 14:23:52 +010049
50 Usage:
51 /> ls
52 /> ls --recursive module:node
53 /> ls /module:node)";
Václav Kubernát11afac72018-07-18 14:59:53 +020054 bool operator==(const ls_& b) const;
Václav Kubernáte7d4aea2018-09-11 18:15:48 +020055 std::vector<LsOption> m_options;
Václav Kubernátbeaa8aa2020-04-29 22:39:34 +020056 boost::optional<boost::variant<dataPath_, schemaPath_, module_>> m_path;
Václav Kubernát11afac72018-07-18 14:59:53 +020057};
58
Václav Kubernát24df80e2018-06-06 15:18:03 +020059struct cd_ : x3::position_tagged {
Václav Kubernát57272422019-02-08 12:48:24 +010060 static constexpr auto name = "cd";
Václav Kubernát054cc992019-02-21 14:23:52 +010061 static constexpr auto shortHelp = "cd - Enter a different node.";
62 static constexpr auto longHelp = R"(
Václav Kubernát419d9172020-11-30 01:20:28 +010063 cd <path>
Václav Kubernát054cc992019-02-21 14:23:52 +010064
Václav Kubernát419d9172020-11-30 01:20:28 +010065 Changes context to a node specified by <path>. Only accepts data paths
66 (paths with all list keys supplied).
Václav Kubernát054cc992019-02-21 14:23:52 +010067
68 Usage:
69 /> cd /module:node/node2
70 /> cd ..)";
Václav Kubernát24df80e2018-06-06 15:18:03 +020071 bool operator==(const cd_& b) const;
Václav Kubernát2eaceb82018-10-08 19:56:30 +020072 dataPath_ m_path;
Václav Kubernát24df80e2018-06-06 15:18:03 +020073};
74
75struct create_ : x3::position_tagged {
Václav Kubernát57272422019-02-08 12:48:24 +010076 static constexpr auto name = "create";
Václav Kubernát419d9172020-11-30 01:20:28 +010077 static constexpr auto shortHelp = "create - Create a node.";
Václav Kubernát054cc992019-02-21 14:23:52 +010078 static constexpr auto longHelp = R"(
Václav Kubernát419d9172020-11-30 01:20:28 +010079 create <path>
Václav Kubernát054cc992019-02-21 14:23:52 +010080
Václav Kubernát419d9172020-11-30 01:20:28 +010081 Creates a node specified by <path>.
82 Supported node types are list items, leaflist instance and presence
83 containers.
Václav Kubernát054cc992019-02-21 14:23:52 +010084
85 Usage:
Václav Kubernátf5f64f02019-03-19 17:15:47 +010086 /> create /module:pContainer
Václav Kubernát419d9172020-11-30 01:20:28 +010087 /> create /module:leafList['value']
Václav Kubernátf5f64f02019-03-19 17:15:47 +010088 /> create /module:list[key=value][anotherKey=value])";
Václav Kubernát24df80e2018-06-06 15:18:03 +020089 bool operator==(const create_& b) const;
Václav Kubernát2eaceb82018-10-08 19:56:30 +020090 dataPath_ m_path;
Václav Kubernát24df80e2018-06-06 15:18:03 +020091};
92
93struct delete_ : x3::position_tagged {
Václav Kubernát57272422019-02-08 12:48:24 +010094 static constexpr auto name = "delete";
Václav Kubernát419d9172020-11-30 01:20:28 +010095 static constexpr auto shortHelp = "delete - Delete a node.";
Václav Kubernát054cc992019-02-21 14:23:52 +010096 static constexpr auto longHelp = R"(
Václav Kubernát419d9172020-11-30 01:20:28 +010097 delete <path>
Václav Kubernát054cc992019-02-21 14:23:52 +010098
Václav Kubernát419d9172020-11-30 01:20:28 +010099 Deletes a node specified by <path>.
100 Supported node types are leafs, list items, leaflist instance and presence
101 containers.
Václav Kubernát054cc992019-02-21 14:23:52 +0100102
103 Usage:
Václav Kubernátf5f64f02019-03-19 17:15:47 +0100104 /> delete /module:pContainer
Václav Kubernát419d9172020-11-30 01:20:28 +0100105 /> delete /module:leafList['value']
Václav Kubernátf5f64f02019-03-19 17:15:47 +0100106 /> delete /module:list[key=value][anotherKey=value])";
Václav Kubernát24df80e2018-06-06 15:18:03 +0200107 bool operator==(const delete_& b) const;
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200108 dataPath_ m_path;
Václav Kubernát24df80e2018-06-06 15:18:03 +0200109};
110
111struct set_ : x3::position_tagged {
Václav Kubernát57272422019-02-08 12:48:24 +0100112 static constexpr auto name = "set";
Václav Kubernát419d9172020-11-30 01:20:28 +0100113 static constexpr auto shortHelp = "set - Set value of a leaf.";
Václav Kubernát054cc992019-02-21 14:23:52 +0100114 static constexpr auto longHelp = R"(
Václav Kubernát419d9172020-11-30 01:20:28 +0100115 set <path_to_leaf> <value>
Václav Kubernát054cc992019-02-21 14:23:52 +0100116
Václav Kubernát419d9172020-11-30 01:20:28 +0100117 Sets the leaf specified by <path_to_leaf> to <value>.
Václav Kubernát054cc992019-02-21 14:23:52 +0100118
119 Usage:
120 /> set /module:leaf 123
121 /> set /module:leaf abc)";
Václav Kubernát24df80e2018-06-06 15:18:03 +0200122 bool operator==(const set_& b) const;
Václav Kubernát2eaceb82018-10-08 19:56:30 +0200123 dataPath_ m_path;
Václav Kubernátebca2552018-06-08 19:06:02 +0200124 leaf_data_ m_data;
Václav Kubernát24df80e2018-06-06 15:18:03 +0200125};
126
Václav Kubernát812ee282018-08-30 17:10:03 +0200127struct commit_ : x3::position_tagged {
Václav Kubernát57272422019-02-08 12:48:24 +0100128 static constexpr auto name = "commit";
Václav Kubernát054cc992019-02-21 14:23:52 +0100129 static constexpr auto shortHelp = "commit - Commit current changes.";
130 static constexpr auto longHelp = R"(
131 commit
132
133 Commits the current changes. Accepts no arguments.
134
135 Usage:
136 /> commit)";
Václav Kubernát812ee282018-08-30 17:10:03 +0200137};
138
Václav Kubernátb6ff0b62018-08-30 16:14:53 +0200139struct get_ : x3::position_tagged {
Václav Kubernát57272422019-02-08 12:48:24 +0100140 static constexpr auto name = "get";
Václav Kubernát054cc992019-02-21 14:23:52 +0100141 static constexpr auto shortHelp = "get - Retrieve configuration from the server.";
142 static constexpr auto longHelp = R"(
143 get [path]
144
Václav Kubernát419d9172020-11-30 01:20:28 +0100145 Prints out content of the current datastore at a specified [path], or below
146 the current context tree.
Václav Kubernát054cc992019-02-21 14:23:52 +0100147
148 Usage:
149 /> get
150 /> get /module:path)";
Václav Kubernátb6ff0b62018-08-30 16:14:53 +0200151 bool operator==(const get_& b) const;
Václav Kubernát8f6bff32020-06-10 14:51:10 +0200152 boost::optional<boost::variant<dataPath_, module_>> m_path;
Václav Kubernátb6ff0b62018-08-30 16:14:53 +0200153};
Václav Kubernát812ee282018-08-30 17:10:03 +0200154
Václav Kubernát9cfcd872020-02-18 12:34:02 +0100155struct describe_ : x3::position_tagged {
156 static constexpr auto name = "describe";
157 static constexpr auto shortHelp = "describe - Print information about YANG tree path.";
158 static constexpr auto longHelp = R"(
159 describe <path>
160
Václav Kubernát419d9172020-11-30 01:20:28 +0100161 Shows documentation of YANG tree paths. In the YANG model, each item may
Václav Kubernát9cfcd872020-02-18 12:34:02 +0100162 have an optional `description` which often explains the function of that
Václav Kubernát419d9172020-11-30 01:20:28 +0100163 node to the end user. This command takes the description from the YANG model
164 and shows it to the user along with additional data, such as the type of the
165 node, units of leaf values, etc.
Václav Kubernát9cfcd872020-02-18 12:34:02 +0100166
167 Usage:
168 /> describe /module:node)";
169 bool operator==(const describe_& b) const;
170
171 boost::variant<schemaPath_, dataPath_> m_path;
172};
173
Václav Kubernát7160a132020-04-03 02:11:01 +0200174struct copy_ : x3::position_tagged {
175 static constexpr auto name = "copy";
Václav Kubernát419d9172020-11-30 01:20:28 +0100176 static constexpr auto shortHelp = "copy - Copy configuration.";
Václav Kubernát7160a132020-04-03 02:11:01 +0200177 static constexpr auto longHelp = R"(
178 copy <source> <destination>
179
Václav Kubernát419d9172020-11-30 01:20:28 +0100180 Copies configuration from <source> to <destination>.
181
Václav Kubernát7160a132020-04-03 02:11:01 +0200182 Usage:
183 /> copy running startup
184 /> copy startup running)";
185 bool operator==(const copy_& b) const;
186
187 Datastore m_source;
188 Datastore m_destination;
189};
190
Václav Kubernátbf65dd72020-05-28 02:32:31 +0200191enum class MoveMode {
192 Begin,
193 End,
194 Before,
195 After
196};
197
198struct move_ : x3::position_tagged {
199 static constexpr auto name = "move";
Václav Kubernát419d9172020-11-30 01:20:28 +0100200 static constexpr auto shortHelp = "move - Move (leaf)list instances.";
Václav Kubernátbf65dd72020-05-28 02:32:31 +0200201 static constexpr auto longHelp = R"(
Václav Kubernát419d9172020-11-30 01:20:28 +0100202 move <path> begin
203 move <path> end
204 move <path> before <key>
205 move <path> after <key>
206
207 Moves the instance specified by <path> to the position specified by the
208 specified by the second and third argument.
Václav Kubernátbf65dd72020-05-28 02:32:31 +0200209
210 Usage:
211 /> move mod:leaflist['abc'] begin
212 /> move mod:leaflist['def'] after 'abc'
Václav Kubernát419d9172020-11-30 01:20:28 +0100213 /> move mod:interfaces[name='eth0'] after [name='eth1'])";
Václav Kubernátbf65dd72020-05-28 02:32:31 +0200214 bool operator==(const move_& b) const;
215
216 dataPath_ m_source;
217
218 std::variant<yang::move::Absolute, yang::move::Relative> m_destination;
219};
220
Václav Kubernát70d7f7a2020-06-23 14:40:40 +0200221struct dump_ : x3::position_tagged {
222 static constexpr auto name = "dump";
Václav Kubernát419d9172020-11-30 01:20:28 +0100223 static constexpr auto shortHelp = "dump - Print out datastore content as JSON or XML.";
Václav Kubernát70d7f7a2020-06-23 14:40:40 +0200224 static constexpr auto longHelp = R"(
225 dump xml|json
226
Václav Kubernát419d9172020-11-30 01:20:28 +0100227 Prints out the content of the datastore. Supports JSON and XML.
228
Václav Kubernát70d7f7a2020-06-23 14:40:40 +0200229 Usage:
230 /> dump xml
231 /> dump json)";
232 bool operator==(const dump_& other) const;
233
234 DataFormat m_format;
235};
236
Václav Kubernátaa4250a2020-07-22 00:02:23 +0200237struct prepare_ : x3::position_tagged {
238 static constexpr auto name = "prepare";
Václav Kubernát419d9172020-11-30 01:20:28 +0100239 static constexpr auto shortHelp = "prepare - Initiate RPC/action.";
Václav Kubernáte7248b22020-06-26 15:38:59 +0200240 static constexpr auto longHelp = R"(
Václav Kubernátaa4250a2020-07-22 00:02:23 +0200241 prepare <path-to-rpc-or-action>
Václav Kubernáte7248b22020-06-26 15:38:59 +0200242
Václav Kubernát419d9172020-11-30 01:20:28 +0100243 This command enters a mode for entering input parameters for the RPC/action.
244 In this mode, you can use commands like `set` on nodes inside the RPC/action
245 to set the input. After setting the input, use `exec` to execute the
246 RPC/action.
Václav Kubernáte7248b22020-06-26 15:38:59 +0200247
248 Usage:
Václav Kubernát419d9172020-11-30 01:20:28 +0100249 /> prepare /mod:launch-nukes
250 /> set kilotons 1000
251 /> exec)";
Václav Kubernátaa4250a2020-07-22 00:02:23 +0200252 bool operator==(const prepare_& other) const;
Václav Kubernáte7248b22020-06-26 15:38:59 +0200253
254 dataPath_ m_path;
255};
256
257struct exec_ : x3::position_tagged {
258 static constexpr auto name = "exec";
Václav Kubernát419d9172020-11-30 01:20:28 +0100259 static constexpr auto shortHelp = "exec - Execute RPC/action.";
Václav Kubernáte7248b22020-06-26 15:38:59 +0200260 static constexpr auto longHelp = R"(
Václav Kubernátd8408e02020-12-02 05:13:27 +0100261 exec [path]
Václav Kubernáte7248b22020-06-26 15:38:59 +0200262
Václav Kubernát419d9172020-11-30 01:20:28 +0100263 This command executes the RPC/action you have previously initiated via the
264 `prepare` command.
Václav Kubernáte7248b22020-06-26 15:38:59 +0200265
Václav Kubernátd8408e02020-12-02 05:13:27 +0100266 If the RPC/action has no input parameters, it can be directly execute via
267 `exec` without usgin `prepare`.
268
Václav Kubernáte7248b22020-06-26 15:38:59 +0200269 Usage:
Václav Kubernátd8408e02020-12-02 05:13:27 +0100270 /> exec
271 /> exec /mod:myRpc)";
Václav Kubernáte7248b22020-06-26 15:38:59 +0200272 bool operator==(const exec_& other) const;
Václav Kubernátd8408e02020-12-02 05:13:27 +0100273
274 boost::optional<dataPath_> m_path;
Václav Kubernáte7248b22020-06-26 15:38:59 +0200275};
276
277struct cancel_ : x3::position_tagged {
278 static constexpr auto name = "cancel";
Václav Kubernát419d9172020-11-30 01:20:28 +0100279 static constexpr auto shortHelp = "cancel - Cancel an ongoing RPC/action input.";
Václav Kubernáte7248b22020-06-26 15:38:59 +0200280 static constexpr auto longHelp = R"(
281 cancel
282
Václav Kubernát419d9172020-11-30 01:20:28 +0100283 This command cancels a previously entered RPC/action context.
Václav Kubernáte7248b22020-06-26 15:38:59 +0200284
285 Usage:
286 /> cancel)";
287 bool operator==(const cancel_& other) const;
288};
289
Václav Kubernát054cc992019-02-21 14:23:52 +0100290struct help_;
Václav Kubernátaa4250a2020-07-22 00:02:23 +0200291using CommandTypes = boost::mpl::vector<cancel_, cd_, commit_, copy_, create_, delete_, describe_, discard_, dump_, exec_, get_, help_, ls_, move_, prepare_, set_>;
Václav Kubernát054cc992019-02-21 14:23:52 +0100292struct help_ : x3::position_tagged {
293 static constexpr auto name = "help";
294 static constexpr auto shortHelp = "help - Print help for commands.";
295 static constexpr auto longHelp = R"(
296 help [command_name]
297
298 Print help for command_name. If used without an argument,
299 print short help for all commands.
300
301 Usage:
302 /> help
303 /> help cd
304 /> help help)";
305 bool operator==(const help_& b) const;
306
307 // The help command has got one optional argument – a command name (type).
308 // All commands are saved in CommandTypes, so we could just use that, but
309 // that way, Spirit would be default constructing the command structs,
310 // which is undesirable, so firstly we use mpl::transform to wrap
311 // CommandTypes with boost::type:
312 using WrappedCommandTypes = boost::mpl::transform<CommandTypes, boost::type<boost::mpl::_>>::type;
313 // Next, we create a variant over the wrapped types:
314 using CommandTypesVariant = boost::make_variant_over<WrappedCommandTypes>::type;
315 // Finally, we wrap the variant with boost::optional:
316 boost::optional<CommandTypesVariant> m_cmd;
317};
318
Václav Kubernát57272422019-02-08 12:48:24 +0100319// TODO: The usage of MPL won't be necessary after std::variant support is added to Spirit
320// https://github.com/boostorg/spirit/issues/270
Václav Kubernát57272422019-02-08 12:48:24 +0100321using command_ = boost::make_variant_over<CommandTypes>::type;
Václav Kubernát24df80e2018-06-06 15:18:03 +0200322
Václav Kubernáte7d4aea2018-09-11 18:15:48 +0200323BOOST_FUSION_ADAPT_STRUCT(ls_, m_options, m_path)
Václav Kubernát24df80e2018-06-06 15:18:03 +0200324BOOST_FUSION_ADAPT_STRUCT(cd_, m_path)
325BOOST_FUSION_ADAPT_STRUCT(create_, m_path)
326BOOST_FUSION_ADAPT_STRUCT(delete_, m_path)
Václav Kubernát24df80e2018-06-06 15:18:03 +0200327BOOST_FUSION_ADAPT_STRUCT(set_, m_path, m_data)
Václav Kubernátab538992019-03-06 15:30:50 +0100328BOOST_FUSION_ADAPT_STRUCT(enum_, m_value)
Václav Kubernátdab73ca2020-10-26 23:44:43 +0100329BOOST_FUSION_ADAPT_STRUCT(bits_, m_bits)
Václav Kubernátab538992019-03-06 15:30:50 +0100330BOOST_FUSION_ADAPT_STRUCT(binary_, m_value)
Václav Kubernáteeb38842019-03-20 19:46:05 +0100331BOOST_FUSION_ADAPT_STRUCT(identityRef_, m_prefix, m_value)
Václav Kubernát812ee282018-08-30 17:10:03 +0200332BOOST_FUSION_ADAPT_STRUCT(commit_)
Václav Kubernát9cfcd872020-02-18 12:34:02 +0100333BOOST_FUSION_ADAPT_STRUCT(describe_, m_path)
Václav Kubernát054cc992019-02-21 14:23:52 +0100334BOOST_FUSION_ADAPT_STRUCT(help_, m_cmd)
Václav Kubernát6d791432018-10-25 16:00:35 +0200335BOOST_FUSION_ADAPT_STRUCT(discard_)
Václav Kubernátb6ff0b62018-08-30 16:14:53 +0200336BOOST_FUSION_ADAPT_STRUCT(get_, m_path)
Václav Kubernát7160a132020-04-03 02:11:01 +0200337BOOST_FUSION_ADAPT_STRUCT(copy_, m_source, m_destination)
Václav Kubernátbf65dd72020-05-28 02:32:31 +0200338BOOST_FUSION_ADAPT_STRUCT(move_, m_source, m_destination)
Václav Kubernát70d7f7a2020-06-23 14:40:40 +0200339BOOST_FUSION_ADAPT_STRUCT(dump_, m_format)
Václav Kubernátaa4250a2020-07-22 00:02:23 +0200340BOOST_FUSION_ADAPT_STRUCT(prepare_, m_path)
Václav Kubernátd8408e02020-12-02 05:13:27 +0100341BOOST_FUSION_ADAPT_STRUCT(exec_, m_path)