MINOR: stktable: support optional index for array types in {set, clear, show} table commands
As discussed in GH #2286, {set, clear, show} table commands were unable to deal with array types such as gpt, because they handled such types as a non-array types, thus only the first entry (ie: gpt[0]) was considered. In this patch we add an extra logic around array-types handling so that it is possible to specify an array index right after the type, like this: set table peer/table key mykey data.gpt[2] value # where 2 is the entry index that we want to access If no index is specified, then it implicitly defaults to 0 to mimic previous behavior.
This commit is contained in:
parent
c0dc7769d4
commit
e8b7337d86
@ -1869,6 +1869,9 @@ clear table <table> [ data.<type> <operator> <value> ] | [ key <key> ] |
|
|||||||
the entry cannot be matched using the key due to empty key or incompatible
|
the entry cannot be matched using the key due to empty key or incompatible
|
||||||
characters on the cli.
|
characters on the cli.
|
||||||
|
|
||||||
|
If data.<type> is an array type, "[]" may be used to access a specific
|
||||||
|
index in the array, like so: data.gpt[1]
|
||||||
|
|
||||||
Example :
|
Example :
|
||||||
$ echo "show table http_proxy" | socat stdio /tmp/sock1
|
$ echo "show table http_proxy" | socat stdio /tmp/sock1
|
||||||
>>> # table: http_proxy, type: ip, size:204800, used:2
|
>>> # table: http_proxy, type: ip, size:204800, used:2
|
||||||
@ -2625,6 +2628,9 @@ set table <table> ptr <ptr> [data.<data_type> <value>]*
|
|||||||
pointer may be relevant if the entry cannot be matched using the key due to
|
pointer may be relevant if the entry cannot be matched using the key due to
|
||||||
empty key or incompatible characters on the cli.
|
empty key or incompatible characters on the cli.
|
||||||
|
|
||||||
|
If data.<data_type> is an array type, "[]" may be used to access a specific
|
||||||
|
index in the array, like so: data.gpt[1]
|
||||||
|
|
||||||
set timeout cli <delay>
|
set timeout cli <delay>
|
||||||
Change the CLI interface timeout for current connection. This can be useful
|
Change the CLI interface timeout for current connection. This can be useful
|
||||||
during long debugging sessions where the user needs to constantly inspect
|
during long debugging sessions where the user needs to constantly inspect
|
||||||
@ -3862,6 +3868,9 @@ show table <name> [ data.<type> <operator> <value> [data.<type> ...]] |
|
|||||||
the entry cannot be matched using the key due empty key or incompatible
|
the entry cannot be matched using the key due empty key or incompatible
|
||||||
characters on the cli.
|
characters on the cli.
|
||||||
|
|
||||||
|
If data.<type> is an array type, "[]" may be used to access a specific
|
||||||
|
index in the array, like so: data.gpt[1]
|
||||||
|
|
||||||
Example :
|
Example :
|
||||||
$ echo "show table http_proxy" | socat stdio /tmp/sock1
|
$ echo "show table http_proxy" | socat stdio /tmp/sock1
|
||||||
>>> # table: http_proxy, type: ip, size:204800, used:2
|
>>> # table: http_proxy, type: ip, size:204800, used:2
|
||||||
|
@ -5281,6 +5281,7 @@ struct show_table_ctx {
|
|||||||
long long value[STKTABLE_FILTER_LEN]; /* value to compare against */
|
long long value[STKTABLE_FILTER_LEN]; /* value to compare against */
|
||||||
signed char data_type[STKTABLE_FILTER_LEN]; /* type of data to compare, or -1 if none */
|
signed char data_type[STKTABLE_FILTER_LEN]; /* type of data to compare, or -1 if none */
|
||||||
signed char data_op[STKTABLE_FILTER_LEN]; /* operator (STD_OP_*) when data_type set */
|
signed char data_op[STKTABLE_FILTER_LEN]; /* operator (STD_OP_*) when data_type set */
|
||||||
|
unsigned int data_idx[STKTABLE_FILTER_LEN]; /* index of data to consider for array types */
|
||||||
enum {
|
enum {
|
||||||
STATE_NEXT = 0, /* px points to next table, entry=NULL */
|
STATE_NEXT = 0, /* px points to next table, entry=NULL */
|
||||||
STATE_DUMP, /* px points to curr table, entry is valid, refcount held */
|
STATE_DUMP, /* px points to curr table, entry is valid, refcount held */
|
||||||
@ -5355,6 +5356,8 @@ static int table_process_entry(struct appctx *appctx, struct stksess *ts, char *
|
|||||||
case STK_CLI_ACT_SET:
|
case STK_CLI_ACT_SET:
|
||||||
HA_RWLOCK_WRLOCK(STK_SESS_LOCK, &ts->lock);
|
HA_RWLOCK_WRLOCK(STK_SESS_LOCK, &ts->lock);
|
||||||
for (cur_arg = 5; *args[cur_arg]; cur_arg += 2) {
|
for (cur_arg = 5; *args[cur_arg]; cur_arg += 2) {
|
||||||
|
unsigned int idx;
|
||||||
|
|
||||||
if (strncmp(args[cur_arg], "data.", 5) != 0) {
|
if (strncmp(args[cur_arg], "data.", 5) != 0) {
|
||||||
cli_err(appctx, "\"data.<type>\" followed by a value expected\n");
|
cli_err(appctx, "\"data.<type>\" followed by a value expected\n");
|
||||||
HA_RWLOCK_WRUNLOCK(STK_SESS_LOCK, &ts->lock);
|
HA_RWLOCK_WRUNLOCK(STK_SESS_LOCK, &ts->lock);
|
||||||
@ -5362,7 +5365,7 @@ static int table_process_entry(struct appctx *appctx, struct stksess *ts, char *
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
data_type = stktable_get_data_type(args[cur_arg] + 5);
|
data_type = stktable_get_data_type_idx(args[cur_arg] + 5, &idx);
|
||||||
if (data_type < 0) {
|
if (data_type < 0) {
|
||||||
cli_err(appctx, "Unknown data type\n");
|
cli_err(appctx, "Unknown data type\n");
|
||||||
HA_RWLOCK_WRUNLOCK(STK_SESS_LOCK, &ts->lock);
|
HA_RWLOCK_WRUNLOCK(STK_SESS_LOCK, &ts->lock);
|
||||||
@ -5384,6 +5387,16 @@ static int table_process_entry(struct appctx *appctx, struct stksess *ts, char *
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (stktable_data_types[data_type].is_array) {
|
||||||
|
ptr = stktable_data_ptr_idx(t, ts, data_type, idx);
|
||||||
|
if (!ptr) {
|
||||||
|
cli_err(appctx, "index out of range in this data array\n");
|
||||||
|
HA_RWLOCK_WRUNLOCK(STK_SESS_LOCK, &ts->lock);
|
||||||
|
stktable_touch_local(t, ts, 1);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
ptr = __stktable_data_ptr(t, ts, data_type);
|
ptr = __stktable_data_ptr(t, ts, data_type);
|
||||||
|
|
||||||
switch (stktable_data_types[data_type].std_type) {
|
switch (stktable_data_types[data_type].std_type) {
|
||||||
@ -5515,7 +5528,7 @@ static int table_prepare_data_request(struct appctx *appctx, char **args)
|
|||||||
if (i > 0 && !*args[3+3*i]) // number of filter entries can be less than STKTABLE_FILTER_LEN
|
if (i > 0 && !*args[3+3*i]) // number of filter entries can be less than STKTABLE_FILTER_LEN
|
||||||
break;
|
break;
|
||||||
/* condition on stored data value */
|
/* condition on stored data value */
|
||||||
ctx->data_type[i] = stktable_get_data_type(args[3+3*i] + 5);
|
ctx->data_type[i] = stktable_get_data_type_idx(args[3+3*i] + 5, &ctx->data_idx[i]);
|
||||||
if (ctx->data_type[i] < 0)
|
if (ctx->data_type[i] < 0)
|
||||||
return cli_dynerr(appctx, memprintf(&err, "Filter entry #%i: Unknown data type\n", i + 1));
|
return cli_dynerr(appctx, memprintf(&err, "Filter entry #%i: Unknown data type\n", i + 1));
|
||||||
|
|
||||||
@ -5670,6 +5683,17 @@ static int cli_io_handler_table(struct appctx *appctx)
|
|||||||
if (ctx->data_type[i] == -1)
|
if (ctx->data_type[i] == -1)
|
||||||
break;
|
break;
|
||||||
dt = ctx->data_type[i];
|
dt = ctx->data_type[i];
|
||||||
|
if (stktable_data_types[dt].is_array) {
|
||||||
|
ptr = stktable_data_ptr_idx(ctx->t,
|
||||||
|
ctx->entry,
|
||||||
|
dt, ctx->data_idx[i]);
|
||||||
|
if (!ptr) {
|
||||||
|
/* index out of range */
|
||||||
|
skip_entry = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
ptr = stktable_data_ptr(ctx->t,
|
ptr = stktable_data_ptr(ctx->t,
|
||||||
ctx->entry,
|
ctx->entry,
|
||||||
dt);
|
dt);
|
||||||
@ -5677,6 +5701,7 @@ static int cli_io_handler_table(struct appctx *appctx)
|
|||||||
* type is both valid and stored
|
* type is both valid and stored
|
||||||
*/
|
*/
|
||||||
BUG_ON(!ptr);
|
BUG_ON(!ptr);
|
||||||
|
}
|
||||||
|
|
||||||
data = 0;
|
data = 0;
|
||||||
switch (stktable_data_types[dt].std_type) {
|
switch (stktable_data_types[dt].std_type) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user