test(e2e): Add multiple credentials to target (#2333)

This commit is contained in:
Michael Li authored and GitHub committed 2024-06-17 10:14:44 -04:00
1 parent 40c1b3c6b5
commit 1a7b3f578c
3 files changed
+416 -143

No files matched your search

+99 -6
View File
@@ -231,7 +231,8 @@ exports.createVaultCredentialStore = async (page, vaultAddr, clientToken) => {
};
/**
* Uses the UI to create a static key pair credential . Assumes you have selected the desired project.
* Uses the UI to create a static key pair credential.
* Assumes you have selected the desired project.
* @param {Page} page Playwright page object
* @param {string} username username for the credential
* @param {string} keyPath path to the private key
@@ -240,7 +241,17 @@ exports.createVaultCredentialStore = async (page, vaultAddr, clientToken) => {
exports.createStaticCredentialKeyPair = async (page, username, keyPath) => {
const credentialName = 'Credential ' + nanoid();
await page.getByRole('link', { name: 'Credentials', exact: true }).click();
await page.getByRole('link', { name: 'New', exact: true }).click();
const newButtonIsVisible = await page
.getByRole('link', { name: 'New', exact: true })
.isVisible();
if (newButtonIsVisible) {
await page.getByRole('link', { name: 'New', exact: true }).click();
} else {
await page.getByText('Manage').click();
await page.getByRole('link', { name: 'New Credential' }).click();
}
await page.getByLabel('Name (Optional)').fill(credentialName);
await page.getByLabel('Description').fill('This is an automated test');
await page
@@ -266,6 +277,61 @@ exports.createStaticCredentialKeyPair = async (page, username, keyPath) => {
return credentialName;
};
/**
* Uses the UI to create a static username and password credential.
* Assumes you have selected the desired project.
* @param {Page} page Playwright page object
* @param {string} username username for the credential
* @param {string} password password for the credential
* @returns Name of the credential
*/
exports.createStaticCredentialUsernamePassword = async (
page,
username,
password,
) => {
const credentialsBreadcrumbIsVisible = await page
.getByRole('breadcrumbs', { name: 'Credentials' })
.isVisible();
if (credentialsBreadcrumbIsVisible) {
await page.getByRole('breadcrumbs', { name: 'Credentials' }).click();
} else {
await page.getByRole('link', { name: 'Credentials', exact: true }).click();
}
const newButtonIsVisible = await page
.getByRole('link', { name: 'New', exact: true })
.isVisible();
if (newButtonIsVisible) {
await page.getByRole('link', { name: 'New', exact: true }).click();
} else {
await page.getByText('Manage').click();
await page.getByRole('link', { name: 'New Credential' }).click();
}
const credentialName = 'Credential ' + nanoid();
await page.getByLabel('Name (Optional)').fill(credentialName);
await page.getByLabel('Description').fill('This is an automated test');
await page
.getByRole('group', { name: 'Type' })
.getByLabel('Username & Password')
.click();
await page.getByLabel('Username', { exact: true }).fill(username);
await page.getByLabel('Password', { exact: true }).fill(password);
await page.getByRole('button', { name: 'Save' }).click();
await expect(
page.getByRole('alert').getByText('Success', { exact: true }),
).toBeVisible();
await page.getByRole('button', { name: 'Dismiss' }).click();
await expect(
page
.getByRole('navigation', { name: 'breadcrumbs' })
.getByText(credentialName),
).toBeVisible();
return credentialName;
};
/**
* Uses the UI to create a vault-generic credential library. Assumes you have selected
* the desired credential store.
@@ -684,10 +750,22 @@ exports.addBrokeredCredentialsToTarget = async (
await page
.getByRole('link', { name: 'Brokered Credentials', exact: true })
.click();
await page
const addBrokeredCredentialsButtonIsVisible = await page
.getByRole('article')
.getByRole('link', { name: 'Add Brokered Credentials', exact: true })
.click();
.isVisible();
if (addBrokeredCredentialsButtonIsVisible) {
await page
.getByRole('article')
.getByRole('link', { name: 'Add Brokered Credentials', exact: true })
.click();
} else {
await page.getByText('Manage').click();
await page.getByRole('link', { name: 'Add Brokered Credentials' }).click();
}
await page
.getByRole('cell', { name: credentialName })
.locator('..')
@@ -725,13 +803,28 @@ exports.addInjectedCredentialsToTarget = async (
exact: true,
})
.click();
await page
const addInjectedCredentialsButtonIsVisible = await page
.getByRole('article')
.getByRole('link', {
name: 'Add Injected Application Credentials',
exact: true,
})
.click();
.isVisible();
if (addInjectedCredentialsButtonIsVisible) {
await page
.getByRole('article')
.getByRole('link', {
name: 'Add Injected Application Credentials',
exact: true,
})
.click();
} else {
await page.getByText('Manage').click();
await page.getByRole('link', { name: 'Add Injected Application' }).click();
}
await page
.getByRole('cell', { name: credentialName })
.locator('..')
@@ -0,0 +1,110 @@
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: BUSL-1.1
*/
/* eslint-disable no-undef */
const { test, expect } = require('@playwright/test');
const { execSync } = require('child_process');
const { checkEnv, authenticatedState } = require('../helpers/general');
const {
authenticateBoundaryCli,
checkBoundaryCli,
deleteOrgCli,
} = require('../helpers/boundary-cli');
const {
addBrokeredCredentialsToTarget,
addInjectedCredentialsToTarget,
createOrg,
createProject,
createSshTargetWithAddressEnt,
createStaticCredentialKeyPair,
createStaticCredentialStore,
createStaticCredentialUsernamePassword,
} = require('../helpers/boundary-ui');
test.use({ storageState: authenticatedState });
test.beforeAll(async () => {
await checkEnv([
'E2E_SSH_USER',
'E2E_SSH_KEY_PATH',
'E2E_TARGET_ADDRESS',
'E2E_TARGET_PORT',
]);
await checkBoundaryCli();
});
test('Multiple Credential Stores (ENT) @ent @aws @docker', async ({ page }) => {
let orgName;
try {
await page.goto('/');
orgName = await createOrg(page);
await createProject(page);
const targetName = await createSshTargetWithAddressEnt(
page,
process.env.E2E_TARGET_ADDRESS,
process.env.E2E_TARGET_PORT,
);
await createStaticCredentialStore(page);
const credentialName = await createStaticCredentialKeyPair(
page,
process.env.E2E_SSH_USER,
process.env.E2E_SSH_KEY_PATH,
);
const credentialName2 = await createStaticCredentialUsernamePassword(
page,
process.env.E2E_SSH_USER,
'testPassword',
);
await addBrokeredCredentialsToTarget(page, targetName, credentialName);
await addBrokeredCredentialsToTarget(page, targetName, credentialName2);
// Remove a credential from the target
await page
.getByRole('link', { name: credentialName2 })
.locator('..')
.locator('..')
.getByRole('button', { name: 'Manage' })
.click();
await page.getByRole('button', { name: 'Remove' }).click();
await page.getByRole('button', { name: 'OK' }).click();
await expect(
page.getByRole('alert').getByText('Success', { exact: true }),
).toBeVisible();
await page.getByRole('button', { name: 'Dismiss' }).click();
await addInjectedCredentialsToTarget(page, targetName, credentialName);
await addInjectedCredentialsToTarget(page, targetName, credentialName2);
// Remove a credential from the target
await page
.getByRole('link', { name: credentialName2 })
.locator('..')
.locator('..')
.getByRole('button', { name: 'Manage' })
.click();
await page.getByRole('button', { name: 'Remove' }).click();
await page.getByRole('button', { name: 'OK' }).click();
await expect(
page.getByRole('alert').getByText('Success', { exact: true }),
).toBeVisible();
await page.getByRole('button', { name: 'Dismiss' }).click();
} finally {
await authenticateBoundaryCli(
process.env.BOUNDARY_ADDR,
process.env.E2E_PASSWORD_AUTH_METHOD_ID,
process.env.E2E_PASSWORD_ADMIN_LOGIN_NAME,
process.env.E2E_PASSWORD_ADMIN_PASSWORD,
);
const orgs = JSON.parse(execSync('boundary scopes list -format json'));
const org = orgs.items.filter((obj) => obj.name == orgName)[0];
if (org) {
await deleteOrgCli(org.id);
}
}
});
@@ -5,21 +5,24 @@
/* eslint-disable no-undef */
const { test, expect } = require('@playwright/test');
const { execSync } = require('child_process');
const { readFile } = require('fs/promises');
const { nanoid } = require('nanoid');
const { checkEnv, authenticatedState } = require('../helpers/general');
const {
authenticateBoundaryCli,
checkBoundaryCli,
deleteOrgCli,
getSessionCli,
} = require('../helpers/boundary-cli');
const {
addBrokeredCredentialsToTarget,
createOrg,
createProject,
createTargetWithAddress,
createStaticCredentialStore,
createStaticCredentialKeyPair,
addBrokeredCredentialsToTarget,
createStaticCredentialUsernamePassword,
} = require('../helpers/boundary-ui');
test.use({ storageState: authenticatedState });
@@ -55,160 +58,227 @@ test.beforeEach(async ({ page }) => {
test('Static Credential Store (User & Key Pair) @ce @aws @docker', async ({
page,
}) => {
const credentialName = await createStaticCredentialKeyPair(
page,
process.env.E2E_SSH_USER,
process.env.E2E_SSH_KEY_PATH,
);
await addBrokeredCredentialsToTarget(page, targetName, credentialName);
await authenticateBoundaryCli(
process.env.BOUNDARY_ADDR,
process.env.E2E_PASSWORD_AUTH_METHOD_ID,
process.env.E2E_PASSWORD_ADMIN_LOGIN_NAME,
process.env.E2E_PASSWORD_ADMIN_PASSWORD,
);
const session = await getSessionCli(orgName, projectName, targetName);
const retrievedUser = session.item.credentials[0].credential.username;
const retrievedKey = session.item.credentials[0].credential.private_key;
if (process.env.E2E_SSH_USER != retrievedUser) {
throw new Error(
'Stored User does not match. EXPECTED: ' +
process.env.E2E_SSH_USER +
', ACTUAL: ' +
retrievedUser,
try {
const credentialName = await createStaticCredentialKeyPair(
page,
process.env.E2E_SSH_USER,
process.env.E2E_SSH_KEY_PATH,
);
}
await addBrokeredCredentialsToTarget(page, targetName, credentialName);
const keyData = await readFile(process.env.E2E_SSH_KEY_PATH, {
encoding: 'utf-8',
});
if (keyData != retrievedKey) {
throw new Error('Stored Key does not match');
await authenticateBoundaryCli(
process.env.BOUNDARY_ADDR,
process.env.E2E_PASSWORD_AUTH_METHOD_ID,
process.env.E2E_PASSWORD_ADMIN_LOGIN_NAME,
process.env.E2E_PASSWORD_ADMIN_PASSWORD,
);
const session = await getSessionCli(orgName, projectName, targetName);
const retrievedUser = session.item.credentials[0].credential.username;
const retrievedKey = session.item.credentials[0].credential.private_key;
if (process.env.E2E_SSH_USER != retrievedUser) {
throw new Error(
'Stored User does not match. EXPECTED: ' +
process.env.E2E_SSH_USER +
', ACTUAL: ' +
retrievedUser,
);
}
const keyData = await readFile(process.env.E2E_SSH_KEY_PATH, {
encoding: 'utf-8',
});
if (keyData != retrievedKey) {
throw new Error('Stored Key does not match');
}
} finally {
await authenticateBoundaryCli(
process.env.BOUNDARY_ADDR,
process.env.E2E_PASSWORD_AUTH_METHOD_ID,
process.env.E2E_PASSWORD_ADMIN_LOGIN_NAME,
process.env.E2E_PASSWORD_ADMIN_PASSWORD,
);
const orgs = JSON.parse(execSync('boundary scopes list -format json'));
const org = orgs.items.filter((obj) => obj.name == orgName)[0];
if (org) {
await deleteOrgCli(org.id);
}
}
});
test('Static Credential Store (Username & Password) @ce @aws @docker', async ({
page,
}) => {
const credentialName = 'Credential ' + nanoid();
await page.getByRole('link', { name: 'Credentials', exact: true }).click();
await page.getByRole('link', { name: 'New', exact: true }).click();
await page.getByLabel('Name (Optional)').fill(credentialName);
await page.getByLabel('Description').fill('This is an automated test');
await page
.getByRole('group', { name: 'Type' })
.getByLabel('Username & Password')
.click();
await page
.getByLabel('Username', { exact: true })
.fill(process.env.E2E_SSH_USER);
const testPassword = 'password';
await page.getByLabel('Password', { exact: true }).fill(testPassword);
await page.getByRole('button', { name: 'Save' }).click();
await expect(
page.getByRole('alert').getByText('Success', { exact: true }),
).toBeVisible();
await page.getByRole('button', { name: 'Dismiss' }).click();
await expect(
page
.getByRole('navigation', { name: 'breadcrumbs' })
.getByText(credentialName),
).toBeVisible();
await addBrokeredCredentialsToTarget(page, targetName, credentialName);
await authenticateBoundaryCli(
process.env.BOUNDARY_ADDR,
process.env.E2E_PASSWORD_AUTH_METHOD_ID,
process.env.E2E_PASSWORD_ADMIN_LOGIN_NAME,
process.env.E2E_PASSWORD_ADMIN_PASSWORD,
);
const session = await getSessionCli(orgName, projectName, targetName);
const retrievedUser = session.item.credentials[0].credential.username;
const retrievedPassword = session.item.credentials[0].credential.password;
if (process.env.E2E_SSH_USER != retrievedUser) {
throw new Error(
'Stored User does not match. EXPECTED: ' +
process.env.E2E_SSH_USER +
', ACTUAL: ' +
retrievedUser,
try {
const testPassword = 'password';
const credentialName = await createStaticCredentialUsernamePassword(
page,
process.env.E2E_SSH_USER,
testPassword,
);
}
if (testPassword != retrievedPassword) {
throw new Error(
'Stored Password does not match. EXPECTED: ' +
testPassword +
', ACTUAL: ' +
retrievedPassword,
await addBrokeredCredentialsToTarget(page, targetName, credentialName);
await authenticateBoundaryCli(
process.env.BOUNDARY_ADDR,
process.env.E2E_PASSWORD_AUTH_METHOD_ID,
process.env.E2E_PASSWORD_ADMIN_LOGIN_NAME,
process.env.E2E_PASSWORD_ADMIN_PASSWORD,
);
const session = await getSessionCli(orgName, projectName, targetName);
const retrievedUser = session.item.credentials[0].credential.username;
const retrievedPassword = session.item.credentials[0].credential.password;
if (process.env.E2E_SSH_USER != retrievedUser) {
throw new Error(
'Stored User does not match. EXPECTED: ' +
process.env.E2E_SSH_USER +
', ACTUAL: ' +
retrievedUser,
);
}
if (testPassword != retrievedPassword) {
throw new Error(
'Stored Password does not match. EXPECTED: ' +
testPassword +
', ACTUAL: ' +
retrievedPassword,
);
}
} finally {
await authenticateBoundaryCli(
process.env.BOUNDARY_ADDR,
process.env.E2E_PASSWORD_AUTH_METHOD_ID,
process.env.E2E_PASSWORD_ADMIN_LOGIN_NAME,
process.env.E2E_PASSWORD_ADMIN_PASSWORD,
);
const orgs = JSON.parse(execSync('boundary scopes list -format json'));
const org = orgs.items.filter((obj) => obj.name == orgName)[0];
if (org) {
await deleteOrgCli(org.id);
}
}
});
test('Static Credential Store (JSON) @ce @aws @docker', async ({ page }) => {
const credentialName = 'Credential ' + nanoid();
await page.getByRole('link', { name: 'Credentials', exact: true }).click();
await page.getByRole('link', { name: 'New', exact: true }).click();
await page.getByLabel('Name (Optional)').fill(credentialName);
await page.getByLabel('Description').fill('This is an automated test');
await page.getByRole('group', { name: 'Type' }).getByLabel('JSON').click();
await page.getByText('{}').click();
const testName = 'name-json';
const testPassword = 'password-json';
const testId = 'id-json';
await page.keyboard.type(
`"username": "${testName}",
try {
const credentialName = 'Credential ' + nanoid();
await page.getByRole('link', { name: 'Credentials', exact: true }).click();
await page.getByRole('link', { name: 'New', exact: true }).click();
await page.getByLabel('Name (Optional)').fill(credentialName);
await page.getByLabel('Description').fill('This is an automated test');
await page.getByRole('group', { name: 'Type' }).getByLabel('JSON').click();
await page.getByText('{}').click();
const testName = 'name-json';
const testPassword = 'password-json';
const testId = 'id-json';
await page.keyboard.type(
`"username": "${testName}",
"password": "${testPassword}",
"id": "${testId}"`,
);
await page.getByRole('button', { name: 'Save' }).click();
await expect(
page.getByRole('alert').getByText('Success', { exact: true }),
).toBeVisible();
await page.getByRole('button', { name: 'Dismiss' }).click();
await expect(
page
.getByRole('navigation', { name: 'breadcrumbs' })
.getByText(credentialName),
).toBeVisible();
await addBrokeredCredentialsToTarget(page, targetName, credentialName);
await authenticateBoundaryCli(
process.env.BOUNDARY_ADDR,
process.env.E2E_PASSWORD_AUTH_METHOD_ID,
process.env.E2E_PASSWORD_ADMIN_LOGIN_NAME,
process.env.E2E_PASSWORD_ADMIN_PASSWORD,
);
const session = await getSessionCli(orgName, projectName, targetName);
const retrievedUser = session.item.credentials[0].credential.username;
const retrievedPassword = session.item.credentials[0].credential.password;
const retrievedId = session.item.credentials[0].credential.id;
if (testName != retrievedUser) {
throw new Error(
'Stored User does not match. EXPECTED: ' +
process.env.E2E_SSH_USER +
', ACTUAL: ' +
retrievedUser,
);
}
if (testPassword != retrievedPassword) {
throw new Error(
'Stored Password does not match. EXPECTED: ' +
testPassword +
', ACTUAL: ' +
retrievedPassword,
await page.getByRole('button', { name: 'Save' }).click();
await expect(
page.getByRole('alert').getByText('Success', { exact: true }),
).toBeVisible();
await page.getByRole('button', { name: 'Dismiss' }).click();
await expect(
page
.getByRole('navigation', { name: 'breadcrumbs' })
.getByText(credentialName),
).toBeVisible();
await addBrokeredCredentialsToTarget(page, targetName, credentialName);
await authenticateBoundaryCli(
process.env.BOUNDARY_ADDR,
process.env.E2E_PASSWORD_AUTH_METHOD_ID,
process.env.E2E_PASSWORD_ADMIN_LOGIN_NAME,
process.env.E2E_PASSWORD_ADMIN_PASSWORD,
);
}
if (testId != retrievedId) {
throw new Error(
'Stored ID does not match. EXPECTED: ' +
testId +
', ACTUAL: ' +
retrievedId,
const session = await getSessionCli(orgName, projectName, targetName);
const retrievedUser = session.item.credentials[0].credential.username;
const retrievedPassword = session.item.credentials[0].credential.password;
const retrievedId = session.item.credentials[0].credential.id;
if (testName != retrievedUser) {
throw new Error(
'Stored User does not match. EXPECTED: ' +
process.env.E2E_SSH_USER +
', ACTUAL: ' +
retrievedUser,
);
}
if (testPassword != retrievedPassword) {
throw new Error(
'Stored Password does not match. EXPECTED: ' +
testPassword +
', ACTUAL: ' +
retrievedPassword,
);
}
if (testId != retrievedId) {
throw new Error(
'Stored ID does not match. EXPECTED: ' +
testId +
', ACTUAL: ' +
retrievedId,
);
}
} finally {
await authenticateBoundaryCli(
process.env.BOUNDARY_ADDR,
process.env.E2E_PASSWORD_AUTH_METHOD_ID,
process.env.E2E_PASSWORD_ADMIN_LOGIN_NAME,
process.env.E2E_PASSWORD_ADMIN_PASSWORD,
);
const orgs = JSON.parse(execSync('boundary scopes list -format json'));
const org = orgs.items.filter((obj) => obj.name == orgName)[0];
if (org) {
await deleteOrgCli(org.id);
}
}
});
test('Multiple Credential Stores (CE) @ce @aws @docker', async ({ page }) => {
try {
const credentialName = await createStaticCredentialKeyPair(
page,
process.env.E2E_SSH_USER,
process.env.E2E_SSH_KEY_PATH,
);
const credentialName2 = await createStaticCredentialUsernamePassword(
page,
process.env.E2E_SSH_USER,
'testPassword',
);
await addBrokeredCredentialsToTarget(page, targetName, credentialName);
await addBrokeredCredentialsToTarget(page, targetName, credentialName2);
// Remove the host source from the target
await page
.getByRole('link', { name: credentialName2 })
.locator('..')
.locator('..')
.getByRole('button', { name: 'Manage' })
.click();
await page.getByRole('button', { name: 'Remove' }).click();
await page.getByRole('button', { name: 'OK' }).click();
await expect(
page.getByRole('alert').getByText('Success', { exact: true }),
).toBeVisible();
await page.getByRole('button', { name: 'Dismiss' }).click();
} finally {
await authenticateBoundaryCli(
process.env.BOUNDARY_ADDR,
process.env.E2E_PASSWORD_AUTH_METHOD_ID,
process.env.E2E_PASSWORD_ADMIN_LOGIN_NAME,
process.env.E2E_PASSWORD_ADMIN_PASSWORD,
);
const orgs = JSON.parse(execSync('boundary scopes list -format json'));
const org = orgs.items.filter((obj) => obj.name == orgName)[0];
if (org) {
await deleteOrgCli(org.id);
}
}
});