mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-06 19:01:54 +00:00
OpenBao 2.7 removed the builtin LDAP auth engine from the server binary (openbao/openbao GH-3882). `bao auth enable ldap` answered "plugin not found in the catalog: ldap" and the deploy stopped there. The role now builds its own image. A multi-stage Dockerfile copies the openbao-plugin-auth-ldap binary out of the image declared as the `auth-ldap` service entry into /opt/openbao/plugins. A second server config file, plugins.hcl, names that directory and registers the plugin declaratively. It sets plugin_auto_register = true explicitly: the image starts the server with a config directory, and on that path 2.7.1 does not apply the documented default, so without the line the catalog stays empty. The Dockerfile sets the file mode in a helper stage instead of COPY --chmod, which only BuildKit accepts. The mount is enabled with -plugin-version=latest, so it follows whichever plugin version the image ships. A mount created by the former builtin engine is tuned and reloaded onto the plugin, which needs `update` on sys/plugins/reload/backend in the ansible-admin policy. The LDAP tasks move into tasks/addons/auth-ldap.yml and the plugin is declared under meta/addons as a required addon bridged to `ldap`. Its Playwright spec logs in through the mount and asserts that sys/auth reports an external running plugin version. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
46 lines
1.7 KiB
JavaScript
46 lines
1.7 KiB
JavaScript
const { test, expect } = require("@playwright/test");
|
|
const { normalizeBaseUrl, decodeDotenvQuotedValue } = require("../personas");
|
|
const { skipUnlessAddonEnabled } = require("../addon-gating");
|
|
const { resolveTimeout } = require("../timeouts");
|
|
|
|
const baseUrl = normalizeBaseUrl(process.env.OPENBAO_BASE_URL || "");
|
|
const adminUsername = decodeDotenvQuotedValue(process.env.ADMIN_USERNAME || "");
|
|
const adminPassword = decodeDotenvQuotedValue(process.env.ADMIN_PASSWORD || "");
|
|
|
|
test.use({ ignoreHTTPSErrors: true });
|
|
|
|
test("addon auth-ldap: the ldap mount is served by the external plugin", async ({ request }) => {
|
|
skipUnlessAddonEnabled("auth-ldap");
|
|
|
|
const login = await request.post(
|
|
`${baseUrl}/v1/auth/ldap/login/${encodeURIComponent(adminUsername)}`,
|
|
{ data: { password: adminPassword }, failOnStatusCode: false, timeout: resolveTimeout(30_000) },
|
|
);
|
|
expect(
|
|
login.status(),
|
|
`expected the LDAP plugin to accept the administrator, got ${login.status()}`,
|
|
).toBe(200);
|
|
const token = (await login.json()).auth.client_token;
|
|
|
|
const mounts = await request.get(`${baseUrl}/v1/sys/auth`, {
|
|
headers: { "X-Vault-Token": token },
|
|
failOnStatusCode: false,
|
|
timeout: resolveTimeout(30_000),
|
|
});
|
|
expect(
|
|
mounts.status(),
|
|
`expected the administrator policy to read sys/auth, got ${mounts.status()}`,
|
|
).toBe(200);
|
|
|
|
const ldap = (await mounts.json()).data["ldap/"];
|
|
expect(ldap, "sys/auth must list the ldap/ mount").toBeTruthy();
|
|
expect(
|
|
ldap.plugin_version,
|
|
"the mount must follow whichever plugin version the image ships",
|
|
).toBe("latest");
|
|
expect(
|
|
ldap.running_plugin_version,
|
|
"an external plugin reports its own semantic version",
|
|
).toMatch(/^v\d+\.\d+\.\d+/);
|
|
});
|