From: Willy Tarreau Date: Tue, 22 Sep 2026 03:44:08 +0000 (+0000) Subject: REGTESTS: cli: test the privilege levels of the CLI X-Git-Tag: v3.5-dev8~41 X-Git-Url: https://git.kaiwu.me/?a=commitdiff_plain;h=c5810cf23553d02f98551c2b1d85838747cad6f8;p=haproxy.git REGTESTS: cli: test the privilege levels of the CLI The "operator" and "user" commands, which drop the privileges of the current connection, had no coverage, and "show cli level" was only reported by the smoke test. The test walks down the three levels and checks both what each of them still allows and what it refuses: reading the statistics and the process information is allowed everywhere, clearing the counters requires operator, and changing a global setting, a server state, an ACL or entering the expert or experimental modes requires admin. It also verifies that the levels only go down, and that a refused command really left the setting untouched. Each case chains the level change and the command it affects on a single line because the level only applies to the connection it was set on, and vtest opens a new connection for every "send". --- diff --git a/reg-tests/cli/levels.vtc b/reg-tests/cli/levels.vtc new file mode 100644 index 000000000..1e251837a --- /dev/null +++ b/reg-tests/cli/levels.vtc @@ -0,0 +1,86 @@ +varnishtest "Test the privilege levels of the CLI" + +# The "operator" and "user" CLI commands, which drop the privileges of +# the current connection, had no coverage, and "show cli level" was only +# reported by the smoke test. This test walks down the three levels and +# checks both what each of them still allows and what it refuses. +# +# The levels only apply to the connection they were set on, and vtest +# opens a new connection for every "send", so each case chains the +# level change and the command it is meant to affect in a single line. + +feature ignore_unknown_macro + +haproxy h1 -conf { + global + .if feature(THREAD) + thread-groups 1 + .endif + chroot / + + defaults + mode http + timeout connect "${HAPROXY_TEST_TIMEOUT-5s}" + timeout client "${HAPROXY_TEST_TIMEOUT-5s}" + timeout server "${HAPROXY_TEST_TIMEOUT-5s}" + + frontend fe + bind "fd@${fe}" + http-request return status 200 + + backend be + server s1 127.0.0.1:1 disabled +} -start + +haproxy h1 -cli { + # the socket declared by the test harness is an admin one + send "show cli level" + expect ~ "^admin" + + # dropping to operator, then to user + send "operator; show cli level" + expect ~ "\noperator" + send "user; show cli level" + expect ~ "\nuser" + # the levels only go down, an operator cannot become admin again + send "operator; user; show cli level" + expect ~ "\nuser" + + # reading the statistics is allowed at every level + send "operator; show stat" + expect ~ "\n# pxname,svname,qcur" + send "user; show stat" + expect ~ "\n# pxname,svname,qcur" + send "user; show info" + expect ~ "Name: HAProxy" + + # changing a global setting requires admin + send "set maxconn global 1234; show info" + expect ~ "\nMaxconn: 1234\n" + send "operator; set maxconn global 4321" + expect ~ "Permission denied" + send "user; set maxconn global 4321" + expect ~ "Permission denied" + # and it was really left untouched + send "show info" + expect ~ "\nMaxconn: 1234\n" + + # so does entering the expert or experimental modes + send "user; expert-mode on" + expect ~ "Permission denied" + send "operator; experimental-mode on" + expect ~ "Permission denied" + + # and so does modifying an ACL or a map + send "operator; add acl virt@nosuchacl foo" + expect ~ "Permission denied" + + # clearing the counters is what an operator is allowed to do, while + # changing a server state turns out to require admin as well + send "operator; clear counters" + expect !~ "Permission denied" + send "user; clear counters" + expect ~ "Permission denied" + send "operator; set server be/s1 state ready" + expect ~ "Permission denied" +}