mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-09-22 14:21:25 +02:00
MINOR: cli: make it possible to enter multiple values at once with "set table"
The "set table" statement allows to create new entries with their respective values. Till now it was limited to a single data type per line, requiring as many "set table" statements as the desired data types to be set. Since this is only a parser limitation, this patch gets rid of it. It also allows the creation of a key with no data types (all reset to their default values).
This commit is contained in:
parent
ce54d1b9f2
commit
47060b6ae0
@ -12047,12 +12047,13 @@ set rate-limit http-compression global <value>
|
|||||||
passed in number of kilobytes per second. The value is available in the "show
|
passed in number of kilobytes per second. The value is available in the "show
|
||||||
info" on the line "CompressBpsRateLim" in bytes.
|
info" on the line "CompressBpsRateLim" in bytes.
|
||||||
|
|
||||||
set table <table> key <key> data.<data_type> <value>
|
set table <table> key <key> [data.<data_type> <value>]*
|
||||||
Create or update a stick-table entry in the table. If the key is not present,
|
Create or update a stick-table entry in the table. If the key is not present,
|
||||||
an entry is inserted. See stick-table in section 4.2 to find all possible
|
an entry is inserted. See stick-table in section 4.2 to find all possible
|
||||||
values for <data_type>. The most likely use consists in dynamically entering
|
values for <data_type>. The most likely use consists in dynamically entering
|
||||||
entries for source IP addresses, with a flag in gpc0 to dynamically block an
|
entries for source IP addresses, with a flag in gpc0 to dynamically block an
|
||||||
IP address or affect its quality of service.
|
IP address or affect its quality of service. It is possible to pass multiple
|
||||||
|
data_types in a single call.
|
||||||
|
|
||||||
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
|
||||||
|
@ -57,7 +57,8 @@
|
|||||||
#define MAX_LINE_ARGS 64
|
#define MAX_LINE_ARGS 64
|
||||||
|
|
||||||
// max # args on a stats socket
|
// max # args on a stats socket
|
||||||
#define MAX_STATS_ARGS 16
|
// This should cover at least 5 + twice the # of data_types
|
||||||
|
#define MAX_STATS_ARGS 64
|
||||||
|
|
||||||
// max # of matches per regexp
|
// max # of matches per regexp
|
||||||
#define MAX_MATCH 10
|
#define MAX_MATCH 10
|
||||||
|
@ -590,6 +590,7 @@ static void stats_sock_table_key_request(struct stream_interface *si, char **arg
|
|||||||
unsigned char ip6_key[sizeof(struct in6_addr)];
|
unsigned char ip6_key[sizeof(struct in6_addr)];
|
||||||
long long value;
|
long long value;
|
||||||
int data_type;
|
int data_type;
|
||||||
|
int cur_arg;
|
||||||
void *ptr;
|
void *ptr;
|
||||||
struct freq_ctr_period *frqp;
|
struct freq_ctr_period *frqp;
|
||||||
|
|
||||||
@ -680,31 +681,6 @@ static void stats_sock_table_key_request(struct stream_interface *si, char **arg
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case STAT_CLI_O_SET:
|
case STAT_CLI_O_SET:
|
||||||
if (strncmp(args[5], "data.", 5) != 0) {
|
|
||||||
si->applet.ctx.cli.msg = "\"data.<type>\" followed by a value expected\n";
|
|
||||||
si->applet.st0 = STAT_CLI_PRINT;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
data_type = stktable_get_data_type(args[5] + 5);
|
|
||||||
if (data_type < 0) {
|
|
||||||
si->applet.ctx.cli.msg = "Unknown data type\n";
|
|
||||||
si->applet.st0 = STAT_CLI_PRINT;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!px->table.data_ofs[data_type]) {
|
|
||||||
si->applet.ctx.cli.msg = "Data type not stored in this table\n";
|
|
||||||
si->applet.st0 = STAT_CLI_PRINT;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!*args[6] || strl2llrc(args[6], strlen(args[6]), &value) != 0) {
|
|
||||||
si->applet.ctx.cli.msg = "Require a valid integer value to store\n";
|
|
||||||
si->applet.st0 = STAT_CLI_PRINT;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ts)
|
if (ts)
|
||||||
stktable_touch(&px->table, ts, 1);
|
stktable_touch(&px->table, ts, 1);
|
||||||
else {
|
else {
|
||||||
@ -718,28 +694,56 @@ static void stats_sock_table_key_request(struct stream_interface *si, char **arg
|
|||||||
stktable_store(&px->table, ts, 1);
|
stktable_store(&px->table, ts, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr = stktable_data_ptr(&px->table, ts, data_type);
|
for (cur_arg = 5; *args[cur_arg]; cur_arg += 2) {
|
||||||
switch (stktable_data_types[data_type].std_type) {
|
if (strncmp(args[cur_arg], "data.", 5) != 0) {
|
||||||
case STD_T_SINT:
|
si->applet.ctx.cli.msg = "\"data.<type>\" followed by a value expected\n";
|
||||||
stktable_data_cast(ptr, std_t_sint) = value;
|
si->applet.st0 = STAT_CLI_PRINT;
|
||||||
break;
|
return;
|
||||||
case STD_T_UINT:
|
}
|
||||||
stktable_data_cast(ptr, std_t_uint) = value;
|
|
||||||
break;
|
data_type = stktable_get_data_type(args[cur_arg] + 5);
|
||||||
case STD_T_ULL:
|
if (data_type < 0) {
|
||||||
stktable_data_cast(ptr, std_t_ull) = value;
|
si->applet.ctx.cli.msg = "Unknown data type\n";
|
||||||
break;
|
si->applet.st0 = STAT_CLI_PRINT;
|
||||||
case STD_T_FRQP:
|
return;
|
||||||
/* We set both the current and previous values. That way
|
}
|
||||||
* the reported frequency is stable during all the period
|
|
||||||
* then slowly fades out. This allows external tools to
|
if (!px->table.data_ofs[data_type]) {
|
||||||
* push measures without having to update them too often.
|
si->applet.ctx.cli.msg = "Data type not stored in this table\n";
|
||||||
*/
|
si->applet.st0 = STAT_CLI_PRINT;
|
||||||
frqp = &stktable_data_cast(ptr, std_t_frqp);
|
return;
|
||||||
frqp->curr_tick = now_ms;
|
}
|
||||||
frqp->prev_ctr = 0;
|
|
||||||
frqp->curr_ctr = value;
|
if (!*args[cur_arg+1] || strl2llrc(args[cur_arg+1], strlen(args[cur_arg+1]), &value) != 0) {
|
||||||
break;
|
si->applet.ctx.cli.msg = "Require a valid integer value to store\n";
|
||||||
|
si->applet.st0 = STAT_CLI_PRINT;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ptr = stktable_data_ptr(&px->table, ts, data_type);
|
||||||
|
|
||||||
|
switch (stktable_data_types[data_type].std_type) {
|
||||||
|
case STD_T_SINT:
|
||||||
|
stktable_data_cast(ptr, std_t_sint) = value;
|
||||||
|
break;
|
||||||
|
case STD_T_UINT:
|
||||||
|
stktable_data_cast(ptr, std_t_uint) = value;
|
||||||
|
break;
|
||||||
|
case STD_T_ULL:
|
||||||
|
stktable_data_cast(ptr, std_t_ull) = value;
|
||||||
|
break;
|
||||||
|
case STD_T_FRQP:
|
||||||
|
/* We set both the current and previous values. That way
|
||||||
|
* the reported frequency is stable during all the period
|
||||||
|
* then slowly fades out. This allows external tools to
|
||||||
|
* push measures without having to update them too often.
|
||||||
|
*/
|
||||||
|
frqp = &stktable_data_cast(ptr, std_t_frqp);
|
||||||
|
frqp->curr_tick = now_ms;
|
||||||
|
frqp->prev_ctr = 0;
|
||||||
|
frqp->curr_ctr = value;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user