Cover OS hostname collision and enrollment resume regressions

This commit is contained in:
2026-10-04 12:00:31 +02:00
parent 4e99b2672a
commit 31b9714a4e
+51 -7
View File
@@ -53,12 +53,13 @@ printf 'MANAGERS=%s\n' "${MANAGERS[*]}"
self.assertIn('MANAGERS=133', r.stdout)
self.assertNotIn('UNEXPECTED MUTATION', r.stderr)
def run_worker(self, want_ts, want_wz, ssh=0, installed=False, failure=False, dns=0):
def run_worker(self, want_ts, want_wz, ssh=0, installed=False, failure=False, dns=0,
resume=0, ts_installed=None, state='NeedsLogin'):
with tempfile.TemporaryDirectory() as td:
p = Path(td)
(p/'ossec/var/run').mkdir(parents=True)
(p/'ossec/var/run/wazuh-agentd.state').write_text("status='connected'\n")
(p/'os-release').write_text('ID=debian\nVERSION_CODENAME=bookworm\nVERSION="12 (bookworm)"\n')
(p/'os-release').write_text('NAME="Debian GNU/Linux"\nID=debian\nVERSION_CODENAME=bookworm\nVERSION="12 (bookworm)"\n')
(p/'headscale.key').write_text('fixture-secret-not-for-logging')
worker = WORKER
for old, new in (
@@ -71,9 +72,14 @@ printf 'MANAGERS=%s\n' "${MANAGERS[*]}"
worker = worker.replace(old, new)
mocks = r'''
command() {
if [[ $1 == -v && $2 == tailscale ]]; then [[ $MOCK_INSTALLED == 1 ]]; else builtin command "$@"; fi
if [[ $1 == -v && $2 == tailscale ]]; then [[ $MOCK_TS == 1 ]]; else builtin command "$@"; fi
}
dpkg-query() {
case "${@: -1}" in
tailscale) [[ $MOCK_TS != 1 ]] || printf 'install ok installed';;
wazuh-agent) [[ $MOCK_INSTALLED != 1 ]] || printf 'install ok installed';;
esac
}
dpkg-query() { [[ $MOCK_INSTALLED != 1 ]] || printf 'install ok installed'; }
timeout() {
shift
if [[ $1 == bash && $2 == -c ]]; then echo "CHECK TCP ${@: -1}"; return 0; fi
@@ -81,6 +87,7 @@ timeout() {
}
apt-get() {
echo "APT $*"
if [[ " $* " == *' wazuh-agent='* ]]; then echo "WAZUH NAME $WAZUH_AGENT_NAME"; fi
if [[ $MOCK_FAILURE == 1 && " $* " == *' install '* ]]; then return 42; fi
}
apt-cache() { echo 'wazuh-agent | 4.14.8-1 | fixture'; }
@@ -88,13 +95,18 @@ apt-mark() { echo "MARK $*"; }
curl() { local last=''; for a in "$@"; do last=$a; done; printf 'fixture' >"$last"; }
gpg() { local prev='' out=''; for a in "$@"; do [[ $prev != -o ]] || out=$a; prev=$a; done; printf 'fixture' >"$out"; }
systemctl() { echo "SERVICE $*"; }
tailscale() { echo "TAILSCALE $*"; }
tailscale() {
if [[ $1 == status ]]; then printf '{"BackendState":"%s"}\n' "$MOCK_STATE"; return 0; fi
echo "TAILSCALE $*"
if [[ $1 == up ]]; then MOCK_STATE=Running; fi
}
id() { if [[ $1 == -u ]]; then echo 1000; else return 0; fi; }
'''
mocks = 'MOCK_INSTALLED=%d; MOCK_FAILURE=%d\n' % (installed, failure) + mocks
mocks = 'MOCK_INSTALLED=%d; MOCK_TS=%d; MOCK_FAILURE=%d; MOCK_STATE=%s\n' % (
installed, installed if ts_installed is None else ts_installed, failure, state) + mocks
r = bash(mocks + worker, td, 'manager.example.com', '4.14.8-1',
'https://headscale.example.com', 'fixture', str(want_ts), str(want_wz),
str(ssh), 'fixtureuser', '0', '0', str(dns))
str(ssh), 'fixtureuser', '0', '0', str(dns), str(resume))
self.assertNotIn('fixture-secret-not-for-logging', r.stdout+r.stderr)
self.assertFalse((p/'headscale.key').exists(), 'secret cleanup did not run')
return r
@@ -103,6 +115,9 @@ id() { if [[ $1 == -u ]]; then echo 1000; else return 0; fi; }
r = self.run_worker(1, 1)
self.assertEqual(r.returncode, 0, r.stderr)
self.assertIn('wazuh-agent=4.14.8-1', r.stdout)
self.assertIn('--hostname=fixture', r.stdout)
self.assertIn('WAZUH NAME fixture', r.stdout)
self.assertNotIn('Debian GNU/Linux', r.stdout)
self.assertIn('--auth-key=file:', r.stdout)
self.assertIn('--accept-dns=false', r.stdout)
self.assertIn('mit dem Manager verbunden', r.stdout)
@@ -114,6 +129,35 @@ id() { if [[ $1 == -u ]]; then echo 1000; else return 0; fi; }
self.assertNotIn('APT ', r.stdout)
self.assertNotIn('TAILSCALE up', r.stdout)
def test_resume_installed_unregistered_tailscale_before_wazuh(self):
r = self.run_worker(0, 1, ts_installed=True, resume=1, dns=1)
self.assertEqual(r.returncode, 0, r.stderr)
self.assertIn('TAILSCALE up', r.stdout)
self.assertIn('--hostname=fixture', r.stdout)
self.assertNotIn('install -y --no-install-recommends tailscale', r.stdout)
self.assertIn('WAZUH NAME fixture', r.stdout)
self.assertLess(r.stdout.index('TAILSCALE up'), r.stdout.index('CHECK TCP 1514'))
def test_resume_preserves_registered_client(self):
r = self.run_worker(0, 1, ts_installed=True, resume=1, state='Running')
self.assertEqual(r.returncode, 0, r.stderr)
self.assertNotIn('TAILSCALE up', r.stdout)
self.assertIn('Registrierung bleibt erhalten', r.stdout)
self.assertIn('wazuh-agent=4.14.8-1', r.stdout)
def test_resume_rejects_ambiguous_state_without_reauthentication(self):
r = self.run_worker(0, 1, ts_installed=True, resume=1, state='Stopped')
self.assertNotEqual(r.returncode, 0)
self.assertNotIn('TAILSCALE up', r.stdout)
self.assertNotIn('APT ', r.stdout)
def test_yes_no_accepts_numeric_answers_and_default(self):
fn = SOURCE.split('yes_no() {', 1)[1].split('\n}\n', 1)[0]
r = bash('fail() { exit 1; }; ask() { REPLY=$ANSWER; }; yes_no() {' + fn + '\n}\n' +
'for ANSWER in 1 0 j n ""; do yes_no prompt 1; echo "ANSWER=$REPLY"; done')
self.assertEqual(r.returncode, 0, r.stderr)
self.assertEqual(r.stdout.splitlines(), ['ANSWER=1', 'ANSWER=0', 'ANSWER=1', 'ANSWER=0', 'ANSWER=1'])
def test_magicdns_enabled_before_manager_connection(self):
r = self.run_worker(1, 1, dns=1)
self.assertEqual(r.returncode, 0, r.stderr)