diff --git a/bin/varnishd/mgt/mgt_cli.c b/bin/varnishd/mgt/mgt_cli.c index 07894bcd02..44b8f9196c 100644 --- a/bin/varnishd/mgt/mgt_cli.c +++ b/bin/varnishd/mgt/mgt_cli.c @@ -69,6 +69,7 @@ static const int ncmds = vcountof(cmds); static int cli_i = -1, cli_o = -1; struct VCLS *mgt_cls; static const char *secret_file; +static char *admin_sockets; static struct vsb *cli_buf = NULL; @@ -322,11 +323,80 @@ mcf_help_json(struct cli *cli, const char * const *av, void *priv) mcf_askchild(cli, av, priv); } +static void v_matchproto_(cli_func_t) +mcf_admin_socket_info(struct cli *cli, const char * const *av, void *priv) +{ + char *as, *p; + const char *joint = ""; + + (void)av; + (void)priv; + + VCLI_Out(cli, "sockets="); + as = strdup(admin_sockets); + AN(as); + for (p = strtok(as, "\n"); p != NULL; p = strtok(NULL, "\n")) { + VCLI_Out(cli, "%s%s", joint, p); + joint = ","; + } + free(as); + + VCLI_Out(cli, "\nsecret=%s\n", secret_file); + VCLI_SetResult(cli, CLIS_OK); +} + +static void v_matchproto_(cli_func_t) +mcf_admin_socket_info_json(struct cli *cli, const char * const *av, void *priv) +{ + char *addr, *as, *port, *save; + const char *joint = ""; + (void)av; + (void)priv; + + + VCLI_JSON_begin(cli, 2, av); + VCLI_Out(cli, ",\n"); + VCLI_Out(cli, "{\n"); + VSB_indent(cli->sb, 2); + VCLI_Out(cli, "\"sockets\": ["); + + as = strdup(admin_sockets); + AN(as); + for (addr = strtok_r(as, "\n", &save); + addr != NULL; + addr = strtok_r(NULL, "%s{\n", &save)) { + port = strchr(addr, ' '); + AN(port); + *port++ = '\0'; + VCLI_Out(cli, "%s\n", joint); + VSB_indent(cli->sb, 2); + VCLI_Out(cli, "{\n"); + VSB_indent(cli->sb, 2); + VCLI_Out(cli, "\"address\": \"%s\",\n", addr); + VCLI_Out(cli, "\"port\": %s\n", port); + VSB_indent(cli->sb, -2); + VCLI_Out(cli, "}"); + VSB_indent(cli->sb, -2); + joint = ","; + } + free(as); + VCLI_Out(cli, "\n"); + VCLI_Out(cli, "],\n"); + VSB_indent(cli->sb, -2); + + VCLI_Out(cli, " \"secret\": \"%s\"\n", secret_file); + VCLI_Out(cli, "}"); + + VCLI_JSON_end(cli); +} + + static struct cli_proto cli_auth[] = { - { CLICMD_HELP, "", mcf_help, mcf_help_json }, - { CLICMD_PING, "", VCLS_func_ping, VCLS_func_ping_json }, - { CLICMD_AUTH, "", mcf_auth }, - { CLICMD_QUIT, "", VCLS_func_close }, + { CLICMD_HELP, "", mcf_help, mcf_help_json }, + { CLICMD_PING, "", VCLS_func_ping, VCLS_func_ping_json }, + { CLICMD_AUTH, "", mcf_auth }, + { CLICMD_ADMIN_SOCKET_INFO, "", mcf_admin_socket_info, mcf_admin_socket_info_json }, + { CLICMD_QUIT, "", VCLS_func_close }, { NULL } }; @@ -530,6 +600,12 @@ mct_callback(void *priv, const struct suckaddr *sa) return (0); } +static void +free_admin_sockets(void) +{ + free(admin_sockets); +} + void mgt_cli_telnet(const char *T_arg) { @@ -550,6 +626,11 @@ mgt_cli_telnet(const char *T_arg) ARGV_ERR("-T %s could not be listened on.\n", T_arg); /* Save in shmem */ mgt_SHM_static_alloc(VSB_data(vsb), VSB_len(vsb) + 1, "Arg", "-T"); + + if (admin_sockets == NULL) + AZ(atexit(free_admin_sockets)); + REPLACE(admin_sockets, VSB_data(vsb)); + VSB_destroy(&vsb); } diff --git a/bin/varnishtest/tests/b00094.vtc b/bin/varnishtest/tests/b00094.vtc new file mode 100644 index 0000000000..8951e47625 --- /dev/null +++ b/bin/varnishtest/tests/b00094.vtc @@ -0,0 +1,12 @@ +vtest "admin_socket.info" + +varnish v1 -vcl { + backend be none; +} -start + +varnish v1 -cliok "admin_socket.info" + +shell { + varnishadm -n ${v1_name} admin_socket.info | grep -E 'secret=${v1_name}/_.secret' + varnishadm -n ${v1_name} admin_socket.info | grep -E 'sockets=\S+ [0-9]+' +} diff --git a/bin/varnishtest/tests/b00095.vtc b/bin/varnishtest/tests/b00095.vtc new file mode 100644 index 0000000000..29fc302bdf --- /dev/null +++ b/bin/varnishtest/tests/b00095.vtc @@ -0,0 +1,23 @@ +vtest "admin_socket.info -j" + +feature cmd "jq -V" + +varnish v1 -vcl { + backend be none; +} -start + +varnish v1 -cliok "admin_socket.info -j" + +shell { + t() { + el=$1 + ty=$2 + [[ $(varnishadm -n ${v1_name} admin_socket.info -j | jq -r "$el | type") == $ty ]] + } + + t .[3].secret string + t .[3].sockets array + t .[3].sockets[0] object + t .[3].sockets[0].address string + t .[3].sockets[0].port number +} diff --git a/include/tbl/cli_cmds.h b/include/tbl/cli_cmds.h index 6f5eb5c90a..450ac8b82c 100644 --- a/include/tbl/cli_cmds.h +++ b/include/tbl/cli_cmds.h @@ -451,6 +451,13 @@ CLI_CMD(PID, 0, 0 ) +CLI_CMD(ADMIN_SOCKET_INFO, + "admin_socket.info", + "admin_socket.info [-j]", + "List admin socket addresses/ports as well as the secret file path.", + " ``-j`` specifies JSON output.", + 0, 0 +) #undef CLI_CMD /*lint -restore */