MINOR: config: add a function to dump all known config keywords

All registered config keywords that are valid in the config parser are
dumped to stdout organized like the regular sections (global, listen,
etc). Some keywords that are known to only be valid in frontends or
backends will be suffixed with [FE] or [BE].

All regularly registered "bind" and "server" keywords are also dumped,
one per "bind" or "server" line. Those depending on ssl are listed after
the "ssl" keyword. Doing so required to export the listener and server
keyword lists that were static.

The function is called from dump_registered_keywords() for keyword
class "cfg".
This commit is contained in:
Willy Tarreau 2022-03-29 15:02:44 +02:00
parent 76871a4f8c
commit ca1acd6080
5 changed files with 131 additions and 2 deletions

View File

@ -126,6 +126,7 @@ void free_email_alert(struct proxy *p);
const char *cfg_find_best_match(const char *word, const struct list *list, int section, const char **extra); const char *cfg_find_best_match(const char *word, const struct list *list, int section, const char **extra);
int warnifnotcap(struct proxy *proxy, int cap, const char *file, int line, const char *arg, const char *hint); int warnifnotcap(struct proxy *proxy, int cap, const char *file, int line, const char *arg, const char *hint);
int failifnotcap(struct proxy *proxy, int cap, const char *file, int line, const char *arg, const char *hint); int failifnotcap(struct proxy *proxy, int cap, const char *file, int line, const char *arg, const char *hint);
void cfg_dump_registered_keywords();
/* simplified way to define a section parser */ /* simplified way to define a section parser */
#define REGISTER_CONFIG_SECTION(name, parse, post) \ #define REGISTER_CONFIG_SECTION(name, parse, post) \

View File

@ -4241,6 +4241,128 @@ void cfg_restore_sections(struct list *backup_sections)
} }
} }
/* dumps all registered keywords by section on stdout */
void cfg_dump_registered_keywords()
{
const char* sect_names[] = { "", "global", "listen", "userlist", "peers", 0 };
int section;
int index;
for (section = 1; sect_names[section]; section++) {
struct cfg_kw_list *kwl;
printf("%s\n", sect_names[section]);
list_for_each_entry(kwl, &cfg_keywords.list, list) {
for (index = 0; kwl->kw[index].kw != NULL; index++)
if (kwl->kw[index].section == section)
printf("\t%s\n", kwl->kw[index].kw);
}
if (section == CFG_LISTEN) {
/* there are plenty of other keywords there */
extern struct list tcp_req_conn_keywords, tcp_req_sess_keywords,
tcp_req_cont_keywords, tcp_res_cont_keywords;
extern struct bind_kw_list bind_keywords;
extern struct ssl_bind_kw ssl_bind_kws[] __maybe_unused;
extern struct srv_kw_list srv_keywords;
struct action_kw_list *akwl;
struct bind_kw_list *bkwl;
struct srv_kw_list *skwl;
list_for_each_entry(bkwl, &bind_keywords.list, list) {
for (index = 0; bkwl->kw[index].kw != NULL; index++) {
if (!bkwl->kw[index].skip)
printf("\tbind <addr> %s\n", bkwl->kw[index].kw);
else
printf("\tbind <addr> %s +%d\n", bkwl->kw[index].kw, bkwl->kw[index].skip);
}
}
#if defined(USE_OPENSSL)
for (index = 0; ssl_bind_kws[index].kw != NULL; index++) {
if (!ssl_bind_kws[index].skip)
printf("\tbind <addr> ssl %s\n", ssl_bind_kws[index].kw);
else
printf("\tbind <addr> ssl %s +%d\n", ssl_bind_kws[index].kw, ssl_bind_kws[index].skip);
}
#endif
list_for_each_entry(skwl, &srv_keywords.list, list) {
for (index = 0; skwl->kw[index].kw != NULL; index++) {
if (!skwl->kw[index].skip)
printf("\tserver <name> <addr> %s\n", skwl->kw[index].kw);
else
printf("\tserver <name> <addr> %s +%d\n", skwl->kw[index].kw, skwl->kw[index].skip);
}
}
for (index = 0; cfg_opts[index].name; index++) {
printf("\toption %s [ ", cfg_opts[index].name);
if (cfg_opts[index].cap & PR_CAP_FE)
printf("FE ");
if (cfg_opts[index].cap & PR_CAP_BE)
printf("BE ");
if (cfg_opts[index].mode == PR_MODE_HTTP)
printf("HTTP ");
printf("]\n");
}
for (index = 0; cfg_opts2[index].name; index++) {
printf("\toption %s [ ", cfg_opts2[index].name);
if (cfg_opts2[index].cap & PR_CAP_FE)
printf("FE ");
if (cfg_opts2[index].cap & PR_CAP_BE)
printf("BE ");
if (cfg_opts2[index].mode == PR_MODE_HTTP)
printf("HTTP ");
printf("]\n");
}
list_for_each_entry(akwl, &tcp_req_conn_keywords, list) {
for (index = 0; akwl->kw[index].kw != NULL; index++)
printf("\ttcp-request connection %s%s\n", akwl->kw[index].kw,
(akwl->kw[index].flags & KWF_MATCH_PREFIX) ? "*" : "");
}
list_for_each_entry(akwl, &tcp_req_sess_keywords, list) {
for (index = 0; akwl->kw[index].kw != NULL; index++)
printf("\ttcp-request session %s%s\n", akwl->kw[index].kw,
(akwl->kw[index].flags & KWF_MATCH_PREFIX) ? "*" : "");
}
list_for_each_entry(akwl, &tcp_req_cont_keywords, list) {
for (index = 0; akwl->kw[index].kw != NULL; index++)
printf("\ttcp-request content %s%s\n", akwl->kw[index].kw,
(akwl->kw[index].flags & KWF_MATCH_PREFIX) ? "*" : "");
}
list_for_each_entry(akwl, &tcp_res_cont_keywords, list) {
for (index = 0; akwl->kw[index].kw != NULL; index++)
printf("\ttcp-response content %s%s\n", akwl->kw[index].kw,
(akwl->kw[index].flags & KWF_MATCH_PREFIX) ? "*" : "");
}
list_for_each_entry(akwl, &http_req_keywords.list, list) {
for (index = 0; akwl->kw[index].kw != NULL; index++)
printf("\thttp-request %s%s\n", akwl->kw[index].kw,
(akwl->kw[index].flags & KWF_MATCH_PREFIX) ? "*" : "");
}
list_for_each_entry(akwl, &http_res_keywords.list, list) {
for (index = 0; akwl->kw[index].kw != NULL; index++)
printf("\thttp-response %s%s\n", akwl->kw[index].kw,
(akwl->kw[index].flags & KWF_MATCH_PREFIX) ? "*" : "");
}
list_for_each_entry(akwl, &http_after_res_keywords.list, list) {
for (index = 0; akwl->kw[index].kw != NULL; index++)
printf("\thttp-after-response %s%s\n", akwl->kw[index].kw,
(akwl->kw[index].flags & KWF_MATCH_PREFIX) ? "*" : "");
}
}
}
}
/* these are the config sections handled by default */ /* these are the config sections handled by default */
REGISTER_CONFIG_SECTION("listen", cfg_parse_listen, NULL); REGISTER_CONFIG_SECTION("listen", cfg_parse_listen, NULL);
REGISTER_CONFIG_SECTION("frontend", cfg_parse_listen, NULL); REGISTER_CONFIG_SECTION("frontend", cfg_parse_listen, NULL);

View File

@ -1825,11 +1825,17 @@ static void dump_registered_keywords(void)
if (strcmp(kwd_dump, "help") == 0) { if (strcmp(kwd_dump, "help") == 0) {
printf("# List of supported keyword classes:\n"); printf("# List of supported keyword classes:\n");
printf("all: list all keywords\n"); printf("all: list all keywords\n");
printf("cfg: configuration keywords\n");
continue; continue;
} }
else if (strcmp(kwd_dump, "all") == 0) { else if (strcmp(kwd_dump, "all") == 0) {
all = 1; all = 1;
} }
if (all || strcmp(kwd_dump, "cfg") == 0) {
printf("# List of registered configuration keywords:\n");
cfg_dump_registered_keywords();
}
} }
} }

View File

@ -40,7 +40,7 @@
/* List head of all known bind keywords */ /* List head of all known bind keywords */
static struct bind_kw_list bind_keywords = { struct bind_kw_list bind_keywords = {
.list = LIST_HEAD_INIT(bind_keywords.list) .list = LIST_HEAD_INIT(bind_keywords.list)
}; };

View File

@ -62,7 +62,7 @@ static const char *extra_kw_list[] = {
}; };
/* List head of all known server keywords */ /* List head of all known server keywords */
static struct srv_kw_list srv_keywords = { struct srv_kw_list srv_keywords = {
.list = LIST_HEAD_INIT(srv_keywords.list) .list = LIST_HEAD_INIT(srv_keywords.list)
}; };