MINOR: map/acl: add the possibility to specify the version in "show map/acl"

The maps and ACLs internally all have two versions, the "current" one,
which is the one being matched against, and the "next" one, the one being
filled during an atomic replacement. Till now the "show" commands only used
to show the current one but it can be convenient to be able to show other
ones as well, so let's add the ability to do this with "show map" and
"show acl". The method used here consists in passing the version number
as "@<ver>" before the map/acl name or ID. It would have been better after
it but that could create confusion with keys already using such a format.
This commit is contained in:
Willy Tarreau 2021-04-30 12:09:54 +02:00
parent e3a42a6c2d
commit 95f753e403
2 changed files with 40 additions and 12 deletions

View File

@ -2028,13 +2028,17 @@ set weight <backend>/<server> <weight>[%]
"admin". Both the backend and the server may be specified either by their
name or by their numeric ID, prefixed with a sharp ('#').
show acl [<acl>]
show acl [[@<ver>] <acl>]
Dump info about acl converters. Without argument, the list of all available
acls is returned. If a <acl> is specified, its contents are dumped. <acl> if
the #<id> or <file>. The dump format is the same than the map even for the
sample value. The data returned are not a list of available ACL, but are the
list of all patterns composing any ACL. Many of these patterns can be shared
with maps.
acls is returned. If a <acl> is specified, its contents are dumped. <acl> is
the #<id> or <file>. By default the current version of the ACL is shown (the
version currently being matched against and reported as 'curr_ver' in the ACL
list). It is possible to instead dump other versions by prepending '@<ver>'
before the ACL's identifier. The version works as a filter and non-existing
versions will simply report no result. The dump format is the same as for the
maps even for the sample values. The data returned are not a list of
available ACL, but are the list of all patterns composing any ACL. Many of
these patterns can be shared with maps.
show backend
Dump the list of backends available in the running process
@ -2326,11 +2330,17 @@ show info [typed|json] [desc]
$ echo "show info json" | socat /var/run/haproxy.sock stdio | \
python -m json.tool
show map [<map>]
show map [[@<ver>] <map>]
Dump info about map converters. Without argument, the list of all available
maps is returned. If a <map> is specified, its contents are dumped. <map> is
the #<id> or <file>. The first column is a unique identifier. It can be used
as reference for the operation "del map" and "set map". The second column is
the #<id> or <file>. By default the current version of the map is shown (the
version currently being matched against and reported as 'curr_ver' in the map
list). It is possible to instead dump other versions by prepending '@<ver>'
before the map's identifier. The version works as a filter and non-existing
versions will simply report no result.
In the output, the first column is a unique entry identifier, which is usable
as a reference for operations "del map" and "set map". The second column is
the pattern and the third column is the sample if available. The data returned
are not directly a list of available maps, but are the list of all patterns
composing any map. Many of these patterns can be shared with ACL.

View File

@ -319,6 +319,7 @@ struct pattern_expr *pat_expr_get_next(struct pattern_expr *getnext, struct list
return expr;
}
/* expects the current generation ID in appctx->cli.cli.i0 */
static int cli_io_handler_pat_list(struct appctx *appctx)
{
struct stream_interface *si = appctx->owner;
@ -368,7 +369,7 @@ static int cli_io_handler_pat_list(struct appctx *appctx)
elt = LIST_ELEM(appctx->ctx.map.bref.ref, struct pat_ref_elt *, list);
if (elt->gen_id != appctx->ctx.map.ref->curr_gen)
if (elt->gen_id != appctx->ctx.cli.i0)
goto skip;
/* build messages */
@ -644,6 +645,7 @@ static int cli_parse_show_map(char **args, char *payload, struct appctx *appctx,
{
if (strcmp(args[1], "map") == 0 ||
strcmp(args[1], "acl") == 0) {
const char *gen = NULL;
/* Set ACL or MAP flags. */
if (args[1][0] == 'm')
@ -657,6 +659,15 @@ static int cli_parse_show_map(char **args, char *payload, struct appctx *appctx,
return 0;
}
/* For both "map" and "acl" we may have an optional generation
* number specified using a "@" character before the pattern
* file name.
*/
if (*args[2] == '@') {
gen = args[2] + 1;
args++;
}
/* lookup into the refs and check the map flag */
appctx->ctx.map.ref = pat_ref_lookup_ref(args[2]);
if (!appctx->ctx.map.ref ||
@ -666,6 +677,13 @@ static int cli_parse_show_map(char **args, char *payload, struct appctx *appctx,
else
return cli_err(appctx, "Unknown ACL identifier. Please use #<id> or <file>.\n");
}
/* set the desired generation id in cli.i0 */
if (gen)
appctx->ctx.cli.i0 = str2uic(gen);
else
appctx->ctx.cli.i0 = appctx->ctx.map.ref->curr_gen;
appctx->io_handler = cli_io_handler_pat_list;
appctx->io_release = cli_release_show_map;
return 0;
@ -976,13 +994,13 @@ static struct cli_kw_list cli_kws = {{ },{
{ { "clear", "acl", NULL }, "clear acl <id> : clear the content of this acl", cli_parse_clear_map, cli_io_handler_clear_map, NULL },
{ { "del", "acl", NULL }, "del acl : delete acl entry", cli_parse_del_map, NULL },
{ { "get", "acl", NULL }, "get acl : report the patterns matching a sample for an ACL", cli_parse_get_map, cli_io_handler_map_lookup, cli_release_mlook },
{ { "show", "acl", NULL }, "show acl [id] : report available acls or dump an acl's contents", cli_parse_show_map, NULL },
{ { "show", "acl", NULL }, "show acl [@ver] [id] : report available acls or dump an acl's contents", cli_parse_show_map, NULL },
{ { "add", "map", NULL }, "add map : add map entry", cli_parse_add_map, NULL },
{ { "clear", "map", NULL }, "clear map <id> : clear the content of this map", cli_parse_clear_map, cli_io_handler_clear_map, NULL },
{ { "del", "map", NULL }, "del map : delete map entry", cli_parse_del_map, NULL },
{ { "get", "map", NULL }, "get map : report the keys and values matching a sample for a map", cli_parse_get_map, cli_io_handler_map_lookup, cli_release_mlook },
{ { "set", "map", NULL }, "set map : modify map entry", cli_parse_set_map, NULL },
{ { "show", "map", NULL }, "show map [id] : report available maps or dump a map's contents", cli_parse_show_map, NULL },
{ { "show", "map", NULL }, "show map [@ver] [id] : report available maps or dump a map's contents", cli_parse_show_map, NULL },
{ { NULL }, NULL, NULL, NULL }
}};