Willy Tarreau 1c0715b12a CLEANUP: cli: move the status print context into its own context
Now that the CLI's print context is alone in the appctx, it's possible
to refine the appctx's ctx layout so that the cli part matches exactly
a regular svcctx, and as such move the CLI context into an svcctx like
other applets. External code will still build and work because the
struct cli perfectly maps onto the struct cli_print_ctx that's located
into svc.storage. This is of course only to make a smooth transition
during 2.6 and will disappear immediately after.

A tiny change had to be applied to the opentracing addon which performs
direct accesses to the CLI's err pointer in its own print function. The
rest uses the standard cli_print_* which were the only ones that needed
a small change.

The whole "ctx.cli" struct could be tagged as deprecated so that any
possibly existing external code that relies on it will get build
warnings, and the comments in the struct are pretty clear about the
way to fix it, and the lack of future of this old API.
2022-05-06 18:33:22 +02:00

398 lines
10 KiB
C

/***
* Copyright 2020 HAProxy Technologies
*
* This file is part of the HAProxy OpenTracing filter.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "include.h"
/***
* NAME
* flt_ot_cli_set_msg -
*
* ARGUMENTS
* appctx -
* err -
* msg -
* cli_state -
*
* DESCRIPTION
* -
*
* RETURN VALUE
* This function does not return a value.
*/
static void cmn_cli_set_msg(struct appctx *appctx, char *err, char *msg, int cli_state)
{
struct cli_print_ctx *ctx = applet_reserve_svcctx(appctx, sizeof(*ctx));
FLT_OT_FUNC("%p, %p, %p, %d", appctx, err, msg, cli_state);
if ((appctx == NULL) || ((err == NULL) && (msg == NULL)))
FLT_OT_RETURN();
ctx->err = (err == NULL) ? msg : err;
appctx->st0 = (ctx->err == NULL) ? CLI_ST_PROMPT : cli_state;
FLT_OT_DBG(1, "err(%d): \"%s\"", appctx->st0, ctx->err);
FLT_OT_RETURN();
}
#ifdef DEBUG_OT
/***
* NAME
* flt_ot_cli_parse_debug -
*
* ARGUMENTS
* args -
* payload -
* appctx -
* private -
*
* DESCRIPTION
* -
*
* RETURN VALUE
* -
*/
static int flt_ot_cli_parse_debug(char **args, char *payload, struct appctx *appctx, void *private)
{
char *err = NULL, *msg = NULL;
uint8_t value;
int retval = 0;
FLT_OT_FUNC("%p, \"%s\", %p, %p", args, payload, appctx, private);
FLT_OT_ARGS_DUMP();
if (FLT_OT_ARG_ISVALID(2)) {
value = flt_ot_strtoll(args[2], 0, 255, &err);
if (err == NULL) {
_HA_ATOMIC_STORE(&(flt_ot_debug.level), value);
(void)memprintf(&msg, FLT_OT_CLI_CMD " : debug level set to %hhu", value);
} else {
retval = 1;
}
} else {
value = _HA_ATOMIC_LOAD(&(flt_ot_debug.level));
(void)memprintf(&msg, FLT_OT_CLI_CMD " : current debug level is %hhu", value);
}
cmn_cli_set_msg(appctx, err, msg, CLI_ST_PRINT_FREE);
FLT_OT_RETURN_INT(retval);
}
#endif /* DEBUG_OT */
/***
* NAME
* flt_ot_cli_parse_disabled -
*
* ARGUMENTS
* args -
* payload -
* appctx -
* private -
*
* DESCRIPTION
* -
*
* RETURN VALUE
* -
*/
static int flt_ot_cli_parse_disabled(char **args, char *payload, struct appctx *appctx, void *private)
{
char *msg = NULL;
bool value = (uintptr_t)private;
int retval = 0;
FLT_OT_FUNC("%p, \"%s\", %p, %p", args, payload, appctx, private);
FLT_OT_ARGS_DUMP();
FLT_OT_PROXIES_LIST_START() {
_HA_ATOMIC_STORE(&(conf->tracer->flag_disabled), value);
(void)memprintf(&msg, "%s%s" FLT_OT_CLI_CMD " : filter %sabled", FLT_OT_CLI_MSG_CAT(msg), value ? "dis" : "en");
} FLT_OT_PROXIES_LIST_END();
cmn_cli_set_msg(appctx, NULL, msg, CLI_ST_PRINT_FREE);
FLT_OT_RETURN_INT(retval);
}
/***
* NAME
* flt_ot_cli_parse_option -
*
* ARGUMENTS
* args -
* payload -
* appctx -
* private -
*
* DESCRIPTION
* -
*
* RETURN VALUE
* -
*/
static int flt_ot_cli_parse_option(char **args, char *payload, struct appctx *appctx, void *private)
{
char *msg = NULL;
bool value = (uintptr_t)private;
int retval = 0;
FLT_OT_FUNC("%p, \"%s\", %p, %p", args, payload, appctx, private);
FLT_OT_ARGS_DUMP();
FLT_OT_PROXIES_LIST_START() {
_HA_ATOMIC_STORE(&(conf->tracer->flag_harderr), value);
(void)memprintf(&msg, "%s%s" FLT_OT_CLI_CMD " : filter set %s-errors", FLT_OT_CLI_MSG_CAT(msg), value ? "hard" : "soft");
} FLT_OT_PROXIES_LIST_END();
cmn_cli_set_msg(appctx, NULL, msg, CLI_ST_PRINT_FREE);
FLT_OT_RETURN_INT(retval);
}
/***
* NAME
* flt_ot_cli_parse_logging -
*
* ARGUMENTS
* args -
* payload -
* appctx -
* private -
*
* DESCRIPTION
* -
*
* RETURN VALUE
* -
*/
static int flt_ot_cli_parse_logging(char **args, char *payload, struct appctx *appctx, void *private)
{
char *err = NULL, *msg = NULL;
uint8_t value;
int retval = 0;
FLT_OT_FUNC("%p, \"%s\", %p, %p", args, payload, appctx, private);
FLT_OT_ARGS_DUMP();
if (FLT_OT_ARG_ISVALID(2)) {
if (strcasecmp(args[2], FLT_OT_CLI_LOGGING_OFF) == 0) {
value = FLT_OT_LOGGING_OFF;
}
else if (strcasecmp(args[2], FLT_OT_CLI_LOGGING_ON) == 0) {
value = FLT_OT_LOGGING_ON;
}
else if (strcasecmp(args[2], FLT_OT_CLI_LOGGING_NOLOGNORM) == 0) {
value = FLT_OT_LOGGING_ON | FLT_OT_LOGGING_NOLOGNORM;
}
else {
(void)memprintf(&err, "'%s' : invalid value, use <" FLT_OT_CLI_LOGGING_OFF " | " FLT_OT_CLI_LOGGING_ON " | " FLT_OT_CLI_LOGGING_NOLOGNORM ">", args[2]);
retval = 1;
}
if (retval == 0) {
FLT_OT_PROXIES_LIST_START() {
_HA_ATOMIC_STORE(&(conf->tracer->logging), value);
(void)memprintf(&msg, "%s%s" FLT_OT_CLI_CMD " : logging is %s", FLT_OT_CLI_MSG_CAT(msg), FLT_OT_CLI_LOGGING_STATE(value));
} FLT_OT_PROXIES_LIST_END();
}
} else {
FLT_OT_PROXIES_LIST_START() {
value = _HA_ATOMIC_LOAD(&(conf->tracer->logging));
(void)memprintf(&msg, "%s%s" FLT_OT_CLI_CMD " : logging is currently %s", FLT_OT_CLI_MSG_CAT(msg), FLT_OT_CLI_LOGGING_STATE(value));
} FLT_OT_PROXIES_LIST_END();
}
cmn_cli_set_msg(appctx, err, msg, CLI_ST_PRINT_FREE);
FLT_OT_RETURN_INT(retval);
}
/***
* NAME
* flt_ot_cli_parse_rate -
*
* ARGUMENTS
* args -
* payload -
* appctx -
* private -
*
* DESCRIPTION
* -
*
* RETURN VALUE
* -
*/
static int flt_ot_cli_parse_rate(char **args, char *payload, struct appctx *appctx, void *private)
{
char *err = NULL, *msg = NULL;
uint32_t value;
int retval = 0;
FLT_OT_FUNC("%p, \"%s\", %p, %p", args, payload, appctx, private);
FLT_OT_ARGS_DUMP();
if (FLT_OT_ARG_ISVALID(2)) {
value = FLT_OT_FLOAT_U32(flt_ot_strtod(args[2], 0.0, FLT_OT_RATE_LIMIT_MAX, &err), FLT_OT_RATE_LIMIT_MAX);
if (err == NULL) {
FLT_OT_PROXIES_LIST_START() {
_HA_ATOMIC_STORE(&(conf->tracer->rate_limit), value);
(void)memprintf(&msg, "%s%s" FLT_OT_CLI_CMD " : rate limit set to %.2f", FLT_OT_CLI_MSG_CAT(msg), FLT_OT_U32_FLOAT(value, FLT_OT_RATE_LIMIT_MAX));
} FLT_OT_PROXIES_LIST_END();
} else {
retval = 1;
}
} else {
FLT_OT_PROXIES_LIST_START() {
value = _HA_ATOMIC_LOAD(&(conf->tracer->rate_limit));
(void)memprintf(&msg, "%s%s" FLT_OT_CLI_CMD " : current rate limit is %.2f", FLT_OT_CLI_MSG_CAT(msg), FLT_OT_U32_FLOAT(value, FLT_OT_RATE_LIMIT_MAX));
} FLT_OT_PROXIES_LIST_END();
}
cmn_cli_set_msg(appctx, err, msg, CLI_ST_PRINT_FREE);
FLT_OT_RETURN_INT(retval);
}
/***
* NAME
* flt_ot_cli_parse_status -
*
* ARGUMENTS
* args -
* payload -
* appctx -
* private -
*
* DESCRIPTION
* -
*
* RETURN VALUE
* -
*/
static int flt_ot_cli_parse_status(char **args, char *payload, struct appctx *appctx, void *private)
{
const char *nl = "";
char *msg = NULL;
int retval = 0;
FLT_OT_FUNC("%p, \"%s\", %p, %p", args, payload, appctx, private);
FLT_OT_ARGS_DUMP();
flt_ot_filters_dump();
(void)memprintf(&msg, " " FLT_OT_OPT_NAME " filter status\n" FLT_OT_STR_DASH_78);
#ifdef DEBUG_OT
(void)memprintf(&msg, "%s\n debug level: 0x%02hhx\n", msg, flt_ot_debug.level);
#endif
FLT_OT_PROXIES_LIST_START() {
(void)memprintf(&msg, "%s\n%s filter %s\n", msg, nl, conf->id);
(void)memprintf(&msg, "%s configuration: %s\n", msg, conf->cfg_file);
(void)memprintf(&msg, "%s disable count: %" PRIu64 " %" PRIu64 "\n\n", msg, conf->cnt.disabled[0], conf->cnt.disabled[1]);
(void)memprintf(&msg, "%s tracer %s\n", msg, conf->tracer->id);
(void)memprintf(&msg, "%s configuration: %s\n", msg, conf->tracer->config);
(void)memprintf(&msg, "%s plugin: %s\n", msg, conf->tracer->plugin);
(void)memprintf(&msg, "%s rate limit: %.2f %%\n", msg, FLT_OT_U32_FLOAT(conf->tracer->rate_limit, FLT_OT_RATE_LIMIT_MAX));
(void)memprintf(&msg, "%s hard errors: %s\n", msg, FLT_OT_STR_FLAG_YN(conf->tracer->flag_harderr));
(void)memprintf(&msg, "%s disabled: %s\n", msg, FLT_OT_STR_FLAG_YN(conf->tracer->flag_disabled));
(void)memprintf(&msg, "%s logging: %s\n", msg, FLT_OT_CLI_LOGGING_STATE(conf->tracer->logging));
(void)memprintf(&msg, "%s analyzers: %08x", msg, conf->tracer->analyzers);
nl = "\n";
} FLT_OT_PROXIES_LIST_END();
cmn_cli_set_msg(appctx, NULL, msg, CLI_ST_PRINT_FREE);
FLT_OT_RETURN_INT(retval);
}
static struct cli_kw_list cli_kws = { { }, {
#ifdef DEBUG_OT
{ { FLT_OT_CLI_CMD, "debug", NULL }, FLT_OT_CLI_CMD " debug [level] : set the OT filter debug level (default: get current debug level)", flt_ot_cli_parse_debug, NULL, NULL, NULL, 0 },
#endif
{ { FLT_OT_CLI_CMD, "disable", NULL }, FLT_OT_CLI_CMD " disable : disable the OT filter", flt_ot_cli_parse_disabled, NULL, NULL, (void *)1, 0 },
{ { FLT_OT_CLI_CMD, "enable", NULL }, FLT_OT_CLI_CMD " enable : enable the OT filter", flt_ot_cli_parse_disabled, NULL, NULL, (void *)0, 0 },
{ { FLT_OT_CLI_CMD, "soft-errors", NULL }, FLT_OT_CLI_CMD " soft-errors : turning off hard-errors mode", flt_ot_cli_parse_option, NULL, NULL, (void *)0, 0 },
{ { FLT_OT_CLI_CMD, "hard-errors", NULL }, FLT_OT_CLI_CMD " hard-errors : enabling hard-errors mode", flt_ot_cli_parse_option, NULL, NULL, (void *)1, 0 },
{ { FLT_OT_CLI_CMD, "logging", NULL }, FLT_OT_CLI_CMD " logging [state] : set logging state (default: get current logging state)", flt_ot_cli_parse_logging, NULL, NULL, NULL, 0 },
{ { FLT_OT_CLI_CMD, "rate", NULL }, FLT_OT_CLI_CMD " rate [value] : set the rate limit (default: get current rate value)", flt_ot_cli_parse_rate, NULL, NULL, NULL, 0 },
{ { FLT_OT_CLI_CMD, "status", NULL }, FLT_OT_CLI_CMD " status : show the OT filter status", flt_ot_cli_parse_status, NULL, NULL, NULL, 0 },
{ /* END */ }
}};
/***
* NAME
* flt_ot_cli_init -
*
* ARGUMENTS
* This function takes no arguments.
*
* DESCRIPTION
* -
*
* RETURN VALUE
* This function does not return a value.
*/
void flt_ot_cli_init(void)
{
FLT_OT_FUNC("");
/* Register CLI keywords. */
cli_register_kw(&cli_kws);
FLT_OT_RETURN();
}
/*
* Local variables:
* c-indent-level: 8
* c-basic-offset: 8
* End:
*
* vi: noexpandtab shiftwidth=8 tabstop=8
*/