test(e2e): Use new tags syntax (#2686)

* test(e2e): Use new tag syntax

* chore: Update yarn lock
This commit is contained in:
Michael Li authored and GitHub committed 2025-02-12 17:24:51 -05:00
1 parent 8fedb23399
commit f3232f34c2
27 files changed
+4111 -4505

No files matched your search

+261 -249
View File
@@ -20,178 +20,277 @@ test.beforeAll(async () => {
});
test.describe('Aliases (Enterprise)', () => {
test('Set up alias from target details page @ent @aws @docker', async ({
page,
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
sshUser,
sshKeyPath,
targetAddress,
targetPort,
}) => {
await page.goto('/');
let orgName;
let alias;
let connect;
const nanoid = customAlphabet('1234567890abcdefghijklmnopqrstuvwxyz', 10);
try {
const orgsPage = new OrgsPage(page);
orgName = await orgsPage.createOrg();
const projectsPage = new ProjectsPage(page);
await projectsPage.createProject();
test(
'Set up alias from target details page',
{ tag: ['@ent', '@aws', '@docker'] },
async ({
page,
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
sshUser,
sshKeyPath,
targetAddress,
targetPort,
}) => {
await page.goto('/');
let orgName;
let alias;
let connect;
const nanoid = customAlphabet('1234567890abcdefghijklmnopqrstuvwxyz', 10);
try {
const orgsPage = new OrgsPage(page);
orgName = await orgsPage.createOrg();
const projectsPage = new ProjectsPage(page);
await projectsPage.createProject();
const targetsPage = new TargetsPage(page);
const targetName = await targetsPage.createSshTargetWithAddressEnt(
targetAddress,
targetPort,
);
const credentialStoresPage = new CredentialStoresPage(page);
await credentialStoresPage.createStaticCredentialStore();
const credentialName =
await credentialStoresPage.createStaticCredentialKeyPair(
sshUser,
sshKeyPath,
const targetsPage = new TargetsPage(page);
const targetName = await targetsPage.createSshTargetWithAddressEnt(
targetAddress,
targetPort,
);
const credentialStoresPage = new CredentialStoresPage(page);
await credentialStoresPage.createStaticCredentialStore();
const credentialName =
await credentialStoresPage.createStaticCredentialKeyPair(
sshUser,
sshKeyPath,
);
await targetsPage.addInjectedCredentialsToTarget(
targetName,
credentialName,
);
await targetsPage.addInjectedCredentialsToTarget(
targetName,
credentialName,
);
// Create alias for target
await page
.getByRole('navigation', { name: 'breadcrumbs' })
.getByText(targetName)
.click();
const aliasName = 'Alias ' + nanoid();
alias = 'example.alias.' + nanoid();
await page.getByRole('link', { name: 'Add an alias' }).click();
await page.getByLabel('Name').fill(aliasName);
await page.getByLabel('Description').fill('This is an automated test');
await page.getByLabel('Alias Value').fill(alias);
await page.getByRole('button', { name: 'Save' }).click();
await expect(
page.getByRole('alert').getByText('Success', { exact: true }),
).toBeVisible();
await page.getByRole('button', { name: 'Dismiss' }).click();
// Create alias for target
await page
.getByRole('navigation', { name: 'breadcrumbs' })
.getByText(targetName)
.click();
const aliasName = 'Alias ' + nanoid();
alias = 'example.alias.' + nanoid();
await page.getByRole('link', { name: 'Add an alias' }).click();
await page.getByLabel('Name').fill(aliasName);
await page.getByLabel('Description').fill('This is an automated test');
await page.getByLabel('Alias Value').fill(alias);
await page.getByRole('button', { name: 'Save' }).click();
await expect(
page.getByRole('alert').getByText('Success', { exact: true }),
).toBeVisible();
await page.getByRole('button', { name: 'Dismiss' }).click();
// Connect to target using alias
await boundaryCli.authenticateBoundary(
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
);
connect = await boundaryCli.connectSshToAlias(alias);
const sessionsPage = new SessionsPage(page);
await sessionsPage.waitForSessionToBeVisible(targetName);
// Connect to target using alias
await boundaryCli.authenticateBoundary(
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
);
connect = await boundaryCli.connectSshToAlias(alias);
const sessionsPage = new SessionsPage(page);
await sessionsPage.waitForSessionToBeVisible(targetName);
// Clear destination from alias
await page
.getByRole('navigation', { name: 'Resources' })
.getByRole('link', { name: 'Targets' })
.click();
await page.getByRole('link', { name: targetName }).click();
await page.getByRole('link', { name: alias }).click();
// Note: On the Target details page, there is a section with the header
// "Aliases". The extra check here is to ensure that we are on the Alias
// details page and not the Target details page.
await expect(page.getByRole('heading', { name: 'Alias' })).not.toHaveText(
'Aliases',
);
await page.getByRole('button', { name: 'Manage' }).click();
await page.getByText('Clear', { exact: true }).click();
await page.getByText('OK', { exact: true }).click();
await expect(
page.getByRole('alert').getByText('Success', { exact: true }),
).toBeVisible();
await page.getByRole('button', { name: 'Dismiss' }).click();
} finally {
if (connect) {
connect.kill('SIGTERM');
}
await boundaryCli.authenticateBoundary(
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
);
if (orgName) {
const orgId = await boundaryCli.getOrgIdFromName(orgName);
if (orgId) {
await boundaryCli.deleteScope(orgId);
// Clear destination from alias
await page
.getByRole('navigation', { name: 'Resources' })
.getByRole('link', { name: 'Targets' })
.click();
await page.getByRole('link', { name: targetName }).click();
await page.getByRole('link', { name: alias }).click();
// Note: On the Target details page, there is a section with the header
// "Aliases". The extra check here is to ensure that we are on the Alias
// details page and not the Target details page.
await expect(
page.getByRole('heading', { name: 'Alias' }),
).not.toHaveText('Aliases');
await page.getByRole('button', { name: 'Manage' }).click();
await page.getByText('Clear', { exact: true }).click();
await page.getByText('OK', { exact: true }).click();
await expect(
page.getByRole('alert').getByText('Success', { exact: true }),
).toBeVisible();
await page.getByRole('button', { name: 'Dismiss' }).click();
} finally {
if (connect) {
connect.kill('SIGTERM');
}
await boundaryCli.authenticateBoundary(
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
);
if (orgName) {
const orgId = await boundaryCli.getOrgIdFromName(orgName);
if (orgId) {
await boundaryCli.deleteScope(orgId);
}
}
if (alias) {
await boundaryCli.deleteAlias(alias);
}
}
if (alias) {
await boundaryCli.deleteAlias(alias);
}
}
});
},
);
test('Set up alias from new target page @ent @aws @docker', async ({
page,
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
sshUser,
sshKeyPath,
targetAddress,
targetPort,
}) => {
await page.goto('/');
let orgName;
let alias;
let connect;
const nanoid = customAlphabet('1234567890abcdefghijklmnopqrstuvwxyz', 10);
try {
const orgsPage = new OrgsPage(page);
orgName = await orgsPage.createOrg();
await boundaryCli.authenticateBoundary(
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
);
const projectsPage = new ProjectsPage(page);
await projectsPage.createProject();
alias = 'example.alias.' + nanoid();
const targetsPage = new TargetsPage(page);
const targetName = await targetsPage.createTargetWithAddressAndAlias(
targetAddress,
targetPort,
alias,
);
const credentialStoresPage = new CredentialStoresPage(page);
await credentialStoresPage.createStaticCredentialStore();
const credentialName =
await credentialStoresPage.createStaticCredentialKeyPair(
sshUser,
sshKeyPath,
test(
'Set up alias from new target page',
{ tag: ['@ent', '@aws', '@docker'] },
async ({
page,
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
sshUser,
sshKeyPath,
targetAddress,
targetPort,
}) => {
await page.goto('/');
let orgName;
let alias;
let connect;
const nanoid = customAlphabet('1234567890abcdefghijklmnopqrstuvwxyz', 10);
try {
const orgsPage = new OrgsPage(page);
orgName = await orgsPage.createOrg();
await boundaryCli.authenticateBoundary(
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
);
const projectsPage = new ProjectsPage(page);
await projectsPage.createProject();
alias = 'example.alias.' + nanoid();
const targetsPage = new TargetsPage(page);
const targetName = await targetsPage.createTargetWithAddressAndAlias(
targetAddress,
targetPort,
alias,
);
const credentialStoresPage = new CredentialStoresPage(page);
await credentialStoresPage.createStaticCredentialStore();
const credentialName =
await credentialStoresPage.createStaticCredentialKeyPair(
sshUser,
sshKeyPath,
);
await targetsPage.addInjectedCredentialsToTarget(
targetName,
credentialName,
);
await targetsPage.addInjectedCredentialsToTarget(
targetName,
credentialName,
);
// Connect to target using alias
connect = await boundaryCli.connectSshToAlias(alias);
const sessionsPage = new SessionsPage(page);
await sessionsPage.waitForSessionToBeVisible(targetName);
} finally {
if (connect) {
connect.kill('SIGTERM');
// Connect to target using alias
connect = await boundaryCli.connectSshToAlias(alias);
const sessionsPage = new SessionsPage(page);
await sessionsPage.waitForSessionToBeVisible(targetName);
} finally {
if (connect) {
connect.kill('SIGTERM');
}
await boundaryCli.authenticateBoundary(
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
);
if (orgName) {
const orgId = await boundaryCli.getOrgIdFromName(orgName);
if (orgId) {
await boundaryCli.deleteScope(orgId);
}
if (alias) {
await boundaryCli.deleteAlias(alias);
}
}
}
await boundaryCli.authenticateBoundary(
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
);
},
);
test(
'Set up alias from aliases page',
{ tag: ['@ent', '@aws', '@docker'] },
async ({
page,
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
sshUser,
sshKeyPath,
targetAddress,
targetPort,
}) => {
await page.goto('/');
const nanoid = customAlphabet('1234567890abcdefghijklmnopqrstuvwxyz', 10);
let orgId;
let alias;
let connect;
try {
const orgsPage = new OrgsPage(page);
const orgName = await orgsPage.createOrg();
const projectsPage = new ProjectsPage(page);
const projectName = await projectsPage.createProject();
const targetsPage = new TargetsPage(page);
const targetName = await targetsPage.createSshTargetWithAddressEnt(
targetAddress,
targetPort,
);
const credentialStoresPage = new CredentialStoresPage(page);
await credentialStoresPage.createStaticCredentialStore();
const credentialName =
await credentialStoresPage.createStaticCredentialKeyPair(
sshUser,
sshKeyPath,
);
await targetsPage.addInjectedCredentialsToTarget(
targetName,
credentialName,
);
// Create new alias from scope page
await boundaryCli.authenticateBoundary(
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
);
orgId = await boundaryCli.getOrgIdFromName(orgName);
const projectId = await boundaryCli.getProjectIdFromName(
orgId,
projectName,
);
const targetId = await boundaryCli.getTargetIdFromName(
projectId,
targetName,
);
alias = 'example.alias.' + nanoid();
const aliasesPage = new AliasesPage(page);
await aliasesPage.createAliasForTarget(alias, targetId);
connect = await boundaryCli.connectSshToAlias(alias);
await page
.getByRole('navigation', { name: 'General' })
.getByRole('link', { name: 'Orgs' })
.click();
await page.getByRole('link', { name: orgName }).click();
await page.getByRole('link', { name: projectName }).click();
const sessionsPage = new SessionsPage(page);
await sessionsPage.waitForSessionToBeVisible(targetName);
} finally {
if (connect) {
connect.kill('SIGTERM');
}
await boundaryCli.authenticateBoundary(
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
);
if (orgName) {
const orgId = await boundaryCli.getOrgIdFromName(orgName);
if (orgId) {
await boundaryCli.deleteScope(orgId);
}
@@ -199,93 +298,6 @@ test.describe('Aliases (Enterprise)', () => {
await boundaryCli.deleteAlias(alias);
}
}
}
});
test('Set up alias from aliases page @ent @aws @docker', async ({
page,
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
sshUser,
sshKeyPath,
targetAddress,
targetPort,
}) => {
await page.goto('/');
const nanoid = customAlphabet('1234567890abcdefghijklmnopqrstuvwxyz', 10);
let orgId;
let alias;
let connect;
try {
const orgsPage = new OrgsPage(page);
const orgName = await orgsPage.createOrg();
const projectsPage = new ProjectsPage(page);
const projectName = await projectsPage.createProject();
const targetsPage = new TargetsPage(page);
const targetName = await targetsPage.createSshTargetWithAddressEnt(
targetAddress,
targetPort,
);
const credentialStoresPage = new CredentialStoresPage(page);
await credentialStoresPage.createStaticCredentialStore();
const credentialName =
await credentialStoresPage.createStaticCredentialKeyPair(
sshUser,
sshKeyPath,
);
await targetsPage.addInjectedCredentialsToTarget(
targetName,
credentialName,
);
// Create new alias from scope page
await boundaryCli.authenticateBoundary(
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
);
orgId = await boundaryCli.getOrgIdFromName(orgName);
const projectId = await boundaryCli.getProjectIdFromName(
orgId,
projectName,
);
const targetId = await boundaryCli.getTargetIdFromName(
projectId,
targetName,
);
alias = 'example.alias.' + nanoid();
const aliasesPage = new AliasesPage(page);
await aliasesPage.createAliasForTarget(alias, targetId);
connect = await boundaryCli.connectSshToAlias(alias);
await page
.getByRole('navigation', { name: 'General' })
.getByRole('link', { name: 'Orgs' })
.click();
await page.getByRole('link', { name: orgName }).click();
await page.getByRole('link', { name: projectName }).click();
const sessionsPage = new SessionsPage(page);
await sessionsPage.waitForSessionToBeVisible(targetName);
} finally {
if (connect) {
connect.kill('SIGTERM');
}
await boundaryCli.authenticateBoundary(
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
);
if (orgId) {
await boundaryCli.deleteScope(orgId);
}
if (alias) {
await boundaryCli.deleteAlias(alias);
}
}
});
},
);
});
+224 -212
View File
@@ -19,150 +19,236 @@ test.beforeAll(async () => {
});
test.describe('Aliases', () => {
test('Set up alias from target details page @ce @aws @docker', async ({
page,
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
targetAddress,
targetPort,
sshUser,
sshKeyPath,
}) => {
await page.goto('/');
let orgName;
let alias;
let connect;
const nanoid = customAlphabet('1234567890abcdefghijklmnopqrstuvwxyz', 10);
try {
const orgsPage = new OrgsPage(page);
orgName = await orgsPage.createOrg();
const projectsPage = new ProjectsPage(page);
await projectsPage.createProject();
const targetsPage = new TargetsPage(page);
const targetName = await targetsPage.createTargetWithAddress(
targetAddress,
targetPort,
);
test(
'Set up alias from target details page',
{ tag: ['@ce', '@aws', '@docker'] },
async ({
page,
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
targetAddress,
targetPort,
sshUser,
sshKeyPath,
}) => {
await page.goto('/');
let orgName;
let alias;
let connect;
const nanoid = customAlphabet('1234567890abcdefghijklmnopqrstuvwxyz', 10);
try {
const orgsPage = new OrgsPage(page);
orgName = await orgsPage.createOrg();
const projectsPage = new ProjectsPage(page);
await projectsPage.createProject();
const targetsPage = new TargetsPage(page);
const targetName = await targetsPage.createTargetWithAddress(
targetAddress,
targetPort,
);
// Create alias for target
const aliasName = 'Alias ' + nanoid();
alias = 'example.alias.' + nanoid();
await page.getByRole('link', { name: 'Add an alias' }).click();
await page.getByLabel('Name').fill(aliasName);
await page.getByLabel('Description').fill('This is an automated test');
await page.getByLabel('Alias Value').fill(alias);
await page.getByRole('button', { name: 'Save' }).click();
await expect(
page.getByRole('alert').getByText('Success', { exact: true }),
).toBeVisible();
await page.getByRole('button', { name: 'Dismiss' }).click();
// Create alias for target
const aliasName = 'Alias ' + nanoid();
alias = 'example.alias.' + nanoid();
await page.getByRole('link', { name: 'Add an alias' }).click();
await page.getByLabel('Name').fill(aliasName);
await page.getByLabel('Description').fill('This is an automated test');
await page.getByLabel('Alias Value').fill(alias);
await page.getByRole('button', { name: 'Save' }).click();
await expect(
page.getByRole('alert').getByText('Success', { exact: true }),
).toBeVisible();
await page.getByRole('button', { name: 'Dismiss' }).click();
// Connect to target using alias
await boundaryCli.authenticateBoundary(
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
);
connect = await boundaryCli.connectToAlias(alias, sshUser, sshKeyPath);
const sessionsPage = new SessionsPage(page);
await sessionsPage.waitForSessionToBeVisible(targetName);
// Connect to target using alias
await boundaryCli.authenticateBoundary(
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
);
connect = await boundaryCli.connectToAlias(alias, sshUser, sshKeyPath);
const sessionsPage = new SessionsPage(page);
await sessionsPage.waitForSessionToBeVisible(targetName);
// Clear destination from alias
await page
.getByRole('navigation', { name: 'Resources' })
.getByRole('link', { name: 'Targets' })
.click();
await page.getByRole('link', { name: targetName }).click();
await page.getByRole('link', { name: alias }).click();
// Note: On the Target details page, there is a section with the header
// "Aliases". The extra check here is to ensure that we are on the Alias
// details page and not the Target details page.
await expect(page.getByRole('heading', { name: 'Alias' })).not.toHaveText(
'Aliases',
);
await page.getByRole('button', { name: 'Manage' }).click();
await page.getByText('Clear', { exact: true }).click();
await page.getByText('OK', { exact: true }).click();
await expect(
page.getByRole('alert').getByText('Success', { exact: true }),
).toBeVisible();
await page.getByRole('button', { name: 'Dismiss' }).click();
} finally {
if (connect) {
connect.kill('SIGTERM');
}
await boundaryCli.authenticateBoundary(
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
);
if (orgName) {
const orgId = await boundaryCli.getOrgIdFromName(orgName);
if (orgId) {
await boundaryCli.deleteScope(orgId);
// Clear destination from alias
await page
.getByRole('navigation', { name: 'Resources' })
.getByRole('link', { name: 'Targets' })
.click();
await page.getByRole('link', { name: targetName }).click();
await page.getByRole('link', { name: alias }).click();
// Note: On the Target details page, there is a section with the header
// "Aliases". The extra check here is to ensure that we are on the Alias
// details page and not the Target details page.
await expect(
page.getByRole('heading', { name: 'Alias' }),
).not.toHaveText('Aliases');
await page.getByRole('button', { name: 'Manage' }).click();
await page.getByText('Clear', { exact: true }).click();
await page.getByText('OK', { exact: true }).click();
await expect(
page.getByRole('alert').getByText('Success', { exact: true }),
).toBeVisible();
await page.getByRole('button', { name: 'Dismiss' }).click();
} finally {
if (connect) {
connect.kill('SIGTERM');
}
await boundaryCli.authenticateBoundary(
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
);
if (orgName) {
const orgId = await boundaryCli.getOrgIdFromName(orgName);
if (orgId) {
await boundaryCli.deleteScope(orgId);
}
}
if (alias) {
await boundaryCli.deleteAlias(alias);
}
}
if (alias) {
await boundaryCli.deleteAlias(alias);
}
}
});
},
);
test('Set up alias from new target page @ce @aws @docker', async ({
page,
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
targetAddress,
targetPort,
sshUser,
sshKeyPath,
}) => {
await page.goto('/');
let orgName;
let alias;
let connect;
const nanoid = customAlphabet('1234567890abcdefghijklmnopqrstuvwxyz', 10);
try {
const orgsPage = new OrgsPage(page);
orgName = await orgsPage.createOrg();
await boundaryCli.authenticateBoundary(
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
);
const projectsPage = new ProjectsPage(page);
await projectsPage.createProject();
alias = 'example.alias.' + nanoid();
const targetsPage = new TargetsPage(page);
const targetName = await targetsPage.createTargetWithAddressAndAlias(
targetAddress,
targetPort,
alias,
);
test(
'Set up alias from new target page',
{ tag: ['@ce', '@aws', '@docker'] },
async ({
page,
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
targetAddress,
targetPort,
sshUser,
sshKeyPath,
}) => {
await page.goto('/');
let orgName;
let alias;
let connect;
const nanoid = customAlphabet('1234567890abcdefghijklmnopqrstuvwxyz', 10);
try {
const orgsPage = new OrgsPage(page);
orgName = await orgsPage.createOrg();
await boundaryCli.authenticateBoundary(
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
);
const projectsPage = new ProjectsPage(page);
await projectsPage.createProject();
alias = 'example.alias.' + nanoid();
const targetsPage = new TargetsPage(page);
const targetName = await targetsPage.createTargetWithAddressAndAlias(
targetAddress,
targetPort,
alias,
);
// Connect to target using alias
connect = await boundaryCli.connectToAlias(alias, sshUser, sshKeyPath);
const sessionsPage = new SessionsPage(page);
await sessionsPage.waitForSessionToBeVisible(targetName);
} finally {
if (connect) {
connect.kill('SIGTERM');
// Connect to target using alias
connect = await boundaryCli.connectToAlias(alias, sshUser, sshKeyPath);
const sessionsPage = new SessionsPage(page);
await sessionsPage.waitForSessionToBeVisible(targetName);
} finally {
if (connect) {
connect.kill('SIGTERM');
}
await boundaryCli.authenticateBoundary(
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
);
if (orgName) {
const orgId = await boundaryCli.getOrgIdFromName(orgName);
if (orgId) {
await boundaryCli.deleteScope(orgId);
}
if (alias) {
await boundaryCli.deleteAlias(alias);
}
}
}
await boundaryCli.authenticateBoundary(
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
);
if (orgName) {
const orgId = await boundaryCli.getOrgIdFromName(orgName);
},
);
test(
'Set up alias from aliases page',
{ tag: ['@ce', '@aws', '@docker'] },
async ({
page,
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
targetAddress,
targetPort,
sshUser,
sshKeyPath,
}) => {
await page.goto('/');
const nanoid = customAlphabet('1234567890abcdefghijklmnopqrstuvwxyz', 10);
let orgId;
let alias;
let connect;
try {
const orgsPage = new OrgsPage(page);
const orgName = await orgsPage.createOrg();
const projectsPage = new ProjectsPage(page);
const projectName = await projectsPage.createProject();
const targetsPage = new TargetsPage(page);
const targetName = await targetsPage.createTargetWithAddress(
targetAddress,
targetPort,
);
// Create new alias from scope page
await boundaryCli.authenticateBoundary(
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
);
orgId = await boundaryCli.getOrgIdFromName(orgName);
const projectId = await boundaryCli.getProjectIdFromName(
orgId,
projectName,
);
const targetId = await boundaryCli.getTargetIdFromName(
projectId,
targetName,
);
alias = 'example.alias.' + nanoid();
const aliasesPage = new AliasesPage(page);
await aliasesPage.createAliasForTarget(alias, targetId);
await page.getByRole('link', { name: 'Orgs', exact: true }).click();
await expect(page.getByRole('heading', { name: 'Orgs' })).toBeVisible();
await page.getByRole('link', { name: orgName }).click();
await page.getByRole('link', { name: projectName }).click();
connect = await boundaryCli.connectToAlias(alias, sshUser, sshKeyPath);
const sessionsPage = new SessionsPage(page);
await sessionsPage.waitForSessionToBeVisible(targetName);
} finally {
if (connect) {
connect.kill('SIGTERM');
}
await boundaryCli.authenticateBoundary(
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
);
if (orgId) {
await boundaryCli.deleteScope(orgId);
}
@@ -170,80 +256,6 @@ test.describe('Aliases', () => {
await boundaryCli.deleteAlias(alias);
}
}
}
});
test('Set up alias from aliases page @ce @aws @docker', async ({
page,
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
targetAddress,
targetPort,
sshUser,
sshKeyPath,
}) => {
await page.goto('/');
const nanoid = customAlphabet('1234567890abcdefghijklmnopqrstuvwxyz', 10);
let orgId;
let alias;
let connect;
try {
const orgsPage = new OrgsPage(page);
const orgName = await orgsPage.createOrg();
const projectsPage = new ProjectsPage(page);
const projectName = await projectsPage.createProject();
const targetsPage = new TargetsPage(page);
const targetName = await targetsPage.createTargetWithAddress(
targetAddress,
targetPort,
);
// Create new alias from scope page
await boundaryCli.authenticateBoundary(
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
);
orgId = await boundaryCli.getOrgIdFromName(orgName);
const projectId = await boundaryCli.getProjectIdFromName(
orgId,
projectName,
);
const targetId = await boundaryCli.getTargetIdFromName(
projectId,
targetName,
);
alias = 'example.alias.' + nanoid();
const aliasesPage = new AliasesPage(page);
await aliasesPage.createAliasForTarget(alias, targetId);
await page.getByRole('link', { name: 'Orgs', exact: true }).click();
await expect(page.getByRole('heading', { name: 'Orgs' })).toBeVisible();
await page.getByRole('link', { name: orgName }).click();
await page.getByRole('link', { name: projectName }).click();
connect = await boundaryCli.connectToAlias(alias, sshUser, sshKeyPath);
const sessionsPage = new SessionsPage(page);
await sessionsPage.waitForSessionToBeVisible(targetName);
} finally {
if (connect) {
connect.kill('SIGTERM');
}
await boundaryCli.authenticateBoundary(
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
);
if (orgId) {
await boundaryCli.deleteScope(orgId);
}
if (alias) {
await boundaryCli.deleteAlias(alias);
}
}
});
},
);
});
+284 -280
View File
@@ -21,288 +21,292 @@ test.beforeAll(async () => {
await boundaryCli.checkBoundaryCli();
});
test('Set up LDAP auth method @ce @ent @docker', async ({
page,
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
ldapAddr,
ldapAdminDn,
ldapAdminPassword,
ldapDomainDn,
ldapGroupName,
ldapUserName,
ldapUserPassword,
}) => {
await page.goto('/');
let orgName;
try {
// Log in
const loginPage = new LoginPage(page);
await loginPage.login(adminLoginName, adminPassword);
await expect(
page.getByRole('navigation', { name: 'breadcrumbs' }).getByText('Orgs'),
).toBeVisible();
test(
'Set up LDAP auth method',
{ tag: ['@ce', '@ent', '@docker'] },
async ({
page,
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
ldapAddr,
ldapAdminDn,
ldapAdminPassword,
ldapDomainDn,
ldapGroupName,
ldapUserName,
ldapUserPassword,
}) => {
await page.goto('/');
let orgName;
try {
// Log in
const loginPage = new LoginPage(page);
await loginPage.login(adminLoginName, adminPassword);
await expect(
page.getByRole('navigation', { name: 'breadcrumbs' }).getByText('Orgs'),
).toBeVisible();
// Create an LDAP auth method
const orgsPage = new OrgsPage(page);
orgName = await orgsPage.createOrg();
await page
.getByRole('navigation', { name: 'IAM' })
.getByRole('link', { name: 'Auth Methods' })
.click();
await page.getByRole('button', { name: 'New' }).click();
await page.getByRole('link', { name: 'LDAP' }).click();
const ldapAuthMethodName = 'LDAP ' + nanoid();
await page.getByLabel('Name').fill(ldapAuthMethodName);
await page.getByLabel('Description').fill('LDAP Auth Method');
await page.getByLabel('Address').fill(ldapAddr);
await page.getByLabel('Bind DN').fill(ldapAdminDn);
await page.getByLabel('Bind Password').fill(ldapAdminPassword);
await page.getByRole('switch', { name: 'Discover DN' }).click();
await page.getByLabel('User DN').fill(ldapDomainDn);
await page.getByLabel('User Attribute').fill('uid');
await page.getByLabel('Group DN').fill(ldapDomainDn);
await page.getByRole('switch', { name: 'Enable Groups' }).click();
await page
.getByRole('group', { name: 'Account Attribute Maps' })
.getByLabel('From Attribute')
.last()
.fill('cn');
await page
.getByRole('group', { name: 'Account Attribute Maps' })
.getByLabel('To Attribute')
.last()
.selectOption('fullName');
await page
.getByRole('group', { name: 'Account Attribute Maps' })
.getByRole('button', { name: 'Add' })
.click();
await page
.getByRole('group', { name: 'Account Attribute Maps' })
.getByLabel('From Attribute')
.last()
.fill('mail');
await page
.getByRole('group', { name: 'Account Attribute Maps' })
.getByLabel('To Attribute')
.last()
.selectOption('email');
await page
.getByRole('group', { name: 'Account Attribute Maps' })
.getByRole('button', { name: 'Add' })
.click();
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(ldapAuthMethodName),
).toBeVisible();
// Change state to active-public
await page.getByRole('button', { name: 'Inactive' }).click();
await page.getByText('Public').click();
await expect(
page.getByRole('alert').getByText('Success', { exact: true }),
).toBeVisible();
await page.getByRole('button', { name: 'Dismiss' }).click();
// Create an LDAP account
const ldapAccountName = 'LDAP Account ' + nanoid();
await page.getByText('Manage', { exact: true }).click();
await page.getByRole('link', { name: 'Create Account' }).click();
await page
.getByLabel('Name (Optional)', { exact: true })
.fill(ldapAccountName);
await page.getByLabel('Description').fill('This is an automated test');
await page.getByLabel('Login Name').fill(ldapUserName);
await page.getByRole('button', { name: 'Save' }).click();
await expect(
page.getByRole('alert').getByText('Success', { exact: true }),
).toBeVisible();
await page.getByRole('button', { name: 'Dismiss' }).click();
// Create an LDAP managed group
await page
.getByRole('navigation', { name: 'breadcrumbs' })
.getByText(ldapAuthMethodName)
.click();
await page.getByText('Manage', { exact: true }).click();
await page.getByRole('link', { name: 'Create Managed Group' }).click();
const ldapManagedGroupName = 'LDAP Managed Group ' + nanoid();
await page.getByLabel('Name (Optional)').fill(ldapManagedGroupName);
await page.getByLabel('Description').fill('This is an automated test');
await page.getByRole('textbox', { name: 'Value' }).fill(ldapGroupName);
await page.getByRole('button', { name: 'Add' }).click();
await page.getByRole('button', { name: 'Save' }).click();
await expect(
page.getByRole('alert').getByText('Success', { exact: true }),
).toBeVisible();
await page.getByRole('button', { name: 'Dismiss' }).click();
// Create a role and add LDAP managed group to role
const rolesPage = new RolesPage(page);
await rolesPage.createRole();
await rolesPage.addPrincipalToRole(ldapManagedGroupName);
// Create a user and attach LDAP account to it
const usersPage = new UsersPage(page);
const userName = await usersPage.createUser();
await usersPage.addAccountToUser(ldapUserName);
// Create a second auth method so that there's multiple auth methods on the
// login screen
const authMethodsPage = new AuthMethodsPage(page);
await authMethodsPage.createPasswordAuthMethod();
// Log in using ldap account
await loginPage.logout(adminLoginName);
await page.getByText('Choose a different scope').click();
await page.getByRole('link', { name: orgName }).click();
await page.getByRole('link', { name: ldapAuthMethodName }).click();
await loginPage.login(ldapUserName, ldapUserPassword);
await expect(
page
.getByRole('navigation', { name: 'breadcrumbs' })
.getByText('Projects'),
).toBeVisible();
// Log back in as an admin
await loginPage.logout(ldapUserName);
await loginPage.login(adminLoginName, adminPassword);
await expect(
page.getByRole('navigation', { name: 'breadcrumbs' }).getByText('Orgs'),
).toBeVisible();
// View the LDAP account and verify account attributes
await page.getByRole('link', { name: orgName }).click();
await page
.getByRole('navigation', { name: 'IAM' })
.getByRole('link', { name: 'Auth Methods' })
.click();
await page.getByRole('link', { name: ldapAuthMethodName }).click();
await page.getByRole('link', { name: 'Accounts' }).click();
await expect(
page
.getByRole('navigation', { name: 'breadcrumbs' })
.getByText('Accounts'),
).toBeVisible();
let headersCount = await page
.getByRole('table')
.getByRole('columnheader')
.count();
let fullNameIndex;
let emailIndex;
for (let i = 0; i < headersCount; i++) {
const header = await page
.getByRole('table')
.getByRole('columnheader')
.nth(i)
.innerText();
if (header == 'Full Name') {
fullNameIndex = i;
} else if (header == 'Email') {
emailIndex = i;
}
}
await expect(
page
.getByRole('cell', { name: ldapAccountName })
.locator('..')
.getByRole('cell')
.nth(fullNameIndex),
).toHaveText(ldapUserName);
await expect(
page
.getByRole('cell', { name: ldapAccountName })
.locator('..')
.getByRole('cell')
.nth(emailIndex),
).toHaveText(ldapUserName + '@mail.com');
// View the Managed Group
await page.getByRole('link', { name: 'Managed Groups' }).click();
await page.getByRole('link', { name: ldapManagedGroupName }).click();
await page.getByRole('link', { name: 'Members' }).click();
await expect(
page
.getByRole('navigation', { name: 'breadcrumbs' })
.getByText('Members'),
).toBeVisible();
headersCount = await page
.getByRole('table')
.getByRole('columnheader')
.count();
for (let i = 0; i < headersCount; i++) {
const header = await page
.getByRole('table')
.getByRole('columnheader')
.nth(i)
.innerText();
if (header == 'Full Name') {
fullNameIndex = i;
} else if (header == 'Email') {
emailIndex = i;
}
}
await expect(
page
.getByRole('cell', { name: ldapAccountName })
.locator('..')
.getByRole('cell')
.nth(fullNameIndex),
).toHaveText(ldapUserName);
await expect(
page
.getByRole('cell', { name: ldapAccountName })
.locator('..')
.getByRole('cell')
.nth(emailIndex),
).toHaveText(ldapUserName + '@mail.com');
// View the User account and verify attributes
await page
.getByRole('navigation', { name: 'IAM' })
.getByRole('link', { name: 'Users' })
.click();
await page.getByRole('link', { name: userName }).click();
await page.getByRole('link', { name: 'Accounts' }).click();
expect(
// Create an LDAP auth method
const orgsPage = new OrgsPage(page);
orgName = await orgsPage.createOrg();
await page
.getByRole('navigation', { name: 'IAM' })
.getByRole('link', { name: 'Auth Methods' })
.click();
await page.getByRole('button', { name: 'New' }).click();
await page.getByRole('link', { name: 'LDAP' }).click();
const ldapAuthMethodName = 'LDAP ' + nanoid();
await page.getByLabel('Name').fill(ldapAuthMethodName);
await page.getByLabel('Description').fill('LDAP Auth Method');
await page.getByLabel('Address').fill(ldapAddr);
await page.getByLabel('Bind DN').fill(ldapAdminDn);
await page.getByLabel('Bind Password').fill(ldapAdminPassword);
await page.getByRole('switch', { name: 'Discover DN' }).click();
await page.getByLabel('User DN').fill(ldapDomainDn);
await page.getByLabel('User Attribute').fill('uid');
await page.getByLabel('Group DN').fill(ldapDomainDn);
await page.getByRole('switch', { name: 'Enable Groups' }).click();
await page
.getByRole('group', { name: 'Account Attribute Maps' })
.getByLabel('From Attribute')
.last()
.fill('cn');
await page
.getByRole('group', { name: 'Account Attribute Maps' })
.getByLabel('To Attribute')
.last()
.selectOption('fullName');
await page
.getByRole('group', { name: 'Account Attribute Maps' })
.getByRole('button', { name: 'Add' })
.click();
await page
.getByRole('group', { name: 'Account Attribute Maps' })
.getByLabel('From Attribute')
.last()
.fill('mail');
await page
.getByRole('group', { name: 'Account Attribute Maps' })
.getByLabel('To Attribute')
.last()
.selectOption('email');
await page
.getByRole('group', { name: 'Account Attribute Maps' })
.getByRole('button', { name: 'Add' })
.click();
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(ldapAuthMethodName),
).toBeVisible();
// Change state to active-public
await page.getByRole('button', { name: 'Inactive' }).click();
await page.getByText('Public').click();
await expect(
page.getByRole('alert').getByText('Success', { exact: true }),
).toBeVisible();
await page.getByRole('button', { name: 'Dismiss' }).click();
// Create an LDAP account
const ldapAccountName = 'LDAP Account ' + nanoid();
await page.getByText('Manage', { exact: true }).click();
await page.getByRole('link', { name: 'Create Account' }).click();
await page
.getByLabel('Name (Optional)', { exact: true })
.fill(ldapAccountName);
await page.getByLabel('Description').fill('This is an automated test');
await page.getByLabel('Login Name').fill(ldapUserName);
await page.getByRole('button', { name: 'Save' }).click();
await expect(
page.getByRole('alert').getByText('Success', { exact: true }),
).toBeVisible();
await page.getByRole('button', { name: 'Dismiss' }).click();
// Create an LDAP managed group
await page
.getByRole('navigation', { name: 'breadcrumbs' })
.getByText(ldapAuthMethodName)
.click();
await page.getByText('Manage', { exact: true }).click();
await page.getByRole('link', { name: 'Create Managed Group' }).click();
const ldapManagedGroupName = 'LDAP Managed Group ' + nanoid();
await page.getByLabel('Name (Optional)').fill(ldapManagedGroupName);
await page.getByLabel('Description').fill('This is an automated test');
await page.getByRole('textbox', { name: 'Value' }).fill(ldapGroupName);
await page.getByRole('button', { name: 'Add' }).click();
await page.getByRole('button', { name: 'Save' }).click();
await expect(
page.getByRole('alert').getByText('Success', { exact: true }),
).toBeVisible();
await page.getByRole('button', { name: 'Dismiss' }).click();
// Create a role and add LDAP managed group to role
const rolesPage = new RolesPage(page);
await rolesPage.createRole();
await rolesPage.addPrincipalToRole(ldapManagedGroupName);
// Create a user and attach LDAP account to it
const usersPage = new UsersPage(page);
const userName = await usersPage.createUser();
await usersPage.addAccountToUser(ldapUserName);
// Create a second auth method so that there's multiple auth methods on the
// login screen
const authMethodsPage = new AuthMethodsPage(page);
await authMethodsPage.createPasswordAuthMethod();
// Log in using ldap account
await loginPage.logout(adminLoginName);
await page.getByText('Choose a different scope').click();
await page.getByRole('link', { name: orgName }).click();
await page.getByRole('link', { name: ldapAuthMethodName }).click();
await loginPage.login(ldapUserName, ldapUserPassword);
await expect(
page
.getByRole('navigation', { name: 'breadcrumbs' })
.getByText('Projects'),
).toBeVisible();
// Log back in as an admin
await loginPage.logout(ldapUserName);
await loginPage.login(adminLoginName, adminPassword);
await expect(
page.getByRole('navigation', { name: 'breadcrumbs' }).getByText('Orgs'),
).toBeVisible();
// View the LDAP account and verify account attributes
await page.getByRole('link', { name: orgName }).click();
await page
.getByRole('navigation', { name: 'IAM' })
.getByRole('link', { name: 'Auth Methods' })
.click();
await page.getByRole('link', { name: ldapAuthMethodName }).click();
await page.getByRole('link', { name: 'Accounts' }).click();
await expect(
page
.getByRole('navigation', { name: 'breadcrumbs' })
.getByText('Accounts'),
).toBeVisible();
let headersCount = await page
.getByRole('table')
.getByRole('row')
.nth(1) // Account row
.getByRole('cell')
.nth(0) // Name field
.innerText(),
).toContain(ldapUserName + '@mail.com');
} finally {
if (orgName) {
await boundaryCli.authenticateBoundary(
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
);
const orgId = await boundaryCli.getOrgIdFromName(orgName);
if (orgId) {
await boundaryCli.deleteScope(orgId);
.getByRole('columnheader')
.count();
let fullNameIndex;
let emailIndex;
for (let i = 0; i < headersCount; i++) {
const header = await page
.getByRole('table')
.getByRole('columnheader')
.nth(i)
.innerText();
if (header == 'Full Name') {
fullNameIndex = i;
} else if (header == 'Email') {
emailIndex = i;
}
}
await expect(
page
.getByRole('cell', { name: ldapAccountName })
.locator('..')
.getByRole('cell')
.nth(fullNameIndex),
).toHaveText(ldapUserName);
await expect(
page
.getByRole('cell', { name: ldapAccountName })
.locator('..')
.getByRole('cell')
.nth(emailIndex),
).toHaveText(ldapUserName + '@mail.com');
// View the Managed Group
await page.getByRole('link', { name: 'Managed Groups' }).click();
await page.getByRole('link', { name: ldapManagedGroupName }).click();
await page.getByRole('link', { name: 'Members' }).click();
await expect(
page
.getByRole('navigation', { name: 'breadcrumbs' })
.getByText('Members'),
).toBeVisible();
headersCount = await page
.getByRole('table')
.getByRole('columnheader')
.count();
for (let i = 0; i < headersCount; i++) {
const header = await page
.getByRole('table')
.getByRole('columnheader')
.nth(i)
.innerText();
if (header == 'Full Name') {
fullNameIndex = i;
} else if (header == 'Email') {
emailIndex = i;
}
}
await expect(
page
.getByRole('cell', { name: ldapAccountName })
.locator('..')
.getByRole('cell')
.nth(fullNameIndex),
).toHaveText(ldapUserName);
await expect(
page
.getByRole('cell', { name: ldapAccountName })
.locator('..')
.getByRole('cell')
.nth(emailIndex),
).toHaveText(ldapUserName + '@mail.com');
// View the User account and verify attributes
await page
.getByRole('navigation', { name: 'IAM' })
.getByRole('link', { name: 'Users' })
.click();
await page.getByRole('link', { name: userName }).click();
await page.getByRole('link', { name: 'Accounts' }).click();
expect(
await page
.getByRole('table')
.getByRole('row')
.nth(1) // Account row
.getByRole('cell')
.nth(0) // Name field
.innerText(),
).toContain(ldapUserName + '@mail.com');
} finally {
if (orgName) {
await boundaryCli.authenticateBoundary(
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
);
const orgId = await boundaryCli.getOrgIdFromName(orgName);
if (orgId) {
await boundaryCli.deleteScope(orgId);
}
}
}
}
});
},
);
@@ -26,242 +26,253 @@ test.beforeEach(async () => {
execSync(`vault auth disable userpass`);
});
test('Set up OIDC auth method @ce @ent @docker @aws', async ({
page,
context,
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
vaultAddr,
}) => {
await page.goto('/');
let orgName;
let policyName;
try {
const userName = 'end-user';
const password = 'password123';
const email = 'vault@hashicorp.com';
const { issuer, clientId, clientSecret, authPolicyName } =
await vaultCli.setupVaultOidc(
vaultAddr,
userName,
password,
email,
test(
'Set up OIDC auth method',
{ tag: ['@ce', '@ent', '@aws', '@docker'] },
async ({
page,
context,
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
vaultAddr,
}) => {
await page.goto('/');
let orgName;
let policyName;
try {
const userName = 'end-user';
const password = 'password123';
const email = 'vault@hashicorp.com';
const { issuer, clientId, clientSecret, authPolicyName } =
await vaultCli.setupVaultOidc(
vaultAddr,
userName,
password,
email,
baseURL,
);
policyName = authPolicyName;
// Log in
const loginPage = new LoginPage(page);
await loginPage.login(adminLoginName, adminPassword);
await expect(
page.getByRole('navigation', { name: 'breadcrumbs' }).getByText('Orgs'),
).toBeVisible();
// Create OIDC Auth Method
const orgsPage = new OrgsPage(page);
orgName = await orgsPage.createOrg();
const authMethodsPage = new AuthMethodsPage(page);
const oidcAuthMethodName = await authMethodsPage.createOidcAuthMethod(
issuer,
clientId,
clientSecret,
baseURL,
);
policyName = authPolicyName;
// Log in
const loginPage = new LoginPage(page);
await loginPage.login(adminLoginName, adminPassword);
await expect(
page.getByRole('navigation', { name: 'breadcrumbs' }).getByText('Orgs'),
).toBeVisible();
// Change OIDC Auth Method state to active-public
await page.getByRole('button', { name: 'Inactive' }).click();
await page.getByText('Public').click();
await expect(
page.getByRole('alert').getByText('Success', { exact: true }),
).toBeVisible();
await page.getByRole('button', { name: 'Dismiss' }).click();
// Create OIDC Auth Method
const orgsPage = new OrgsPage(page);
orgName = await orgsPage.createOrg();
const authMethodsPage = new AuthMethodsPage(page);
const oidcAuthMethodName = await authMethodsPage.createOidcAuthMethod(
issuer,
clientId,
clientSecret,
baseURL,
);
// Set auth method as primary
await page.getByText('Manage', { exact: true }).click();
await page.getByRole('button', { name: 'Make Primary' }).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();
// Change OIDC Auth Method state to active-public
await page.getByRole('button', { name: 'Inactive' }).click();
await page.getByText('Public').click();
await expect(
page.getByRole('alert').getByText('Success', { exact: true }),
).toBeVisible();
await page.getByRole('button', { name: 'Dismiss' }).click();
// Set auth method as primary
await page.getByText('Manage', { exact: true }).click();
await page.getByRole('button', { name: 'Make Primary' }).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();
// Create an OIDC managed group
await page
.getByRole('navigation', { name: 'breadcrumbs' })
.getByText(oidcAuthMethodName)
.click();
await page.getByText('Manage', { exact: true }).click();
await page.getByRole('link', { name: 'Create Managed Group' }).click();
const oidcManagedGroupName = 'OIDC Managed Group';
await page.getByLabel('Name (Optional)').fill(oidcManagedGroupName);
await page.getByLabel('Description').fill('This is an automated test');
await page.getByLabel('Filter').fill(`"engineering" in "/userinfo/groups"`);
await page.getByRole('button', { name: 'Save' }).click();
await expect(
page.getByRole('alert').getByText('Success', { exact: true }),
).toBeVisible();
await page.getByRole('button', { name: 'Dismiss' }).click();
// Create a role and add LDAP managed group to role
const rolesPage = new RolesPage(page);
await rolesPage.createRole();
await rolesPage.addPrincipalToRole(oidcManagedGroupName);
// Log in using oidc account
await loginPage.logout(adminLoginName);
await page.getByText('Choose a different scope').click();
await page.getByRole('link', { name: orgName }).click();
await page.getByRole('link', { name: oidcAuthMethodName }).click();
const pagePromise = context.waitForEvent('page');
await page.getByRole('button', { name: 'Sign In' }).click();
const vaultPage = await pagePromise;
await vaultPage.getByLabel('Method').selectOption('Username');
await vaultPage.getByLabel('Username').fill(userName);
await vaultPage.getByLabel('Password').fill(password);
await vaultPage.getByRole('button', { name: 'Sign In' }).click();
await expect(
page
.getByRole('navigation', { name: 'breadcrumbs' })
.getByText('Projects'),
).toBeVisible();
// Log back in as an admin
// WORKAROUND: Currently, users logging using OIDC don't have a username
// displayed in the UI, so there's no simple locator to access this menu.
await page.locator('details').filter({ hasText: 'Sign Out' }).click();
await page.getByRole('button', { name: 'Sign Out' }).click();
await expect(page.getByRole('button', { name: 'Sign In' })).toBeVisible();
await loginPage.login(adminLoginName, adminPassword);
await expect(
page.getByRole('navigation', { name: 'breadcrumbs' }).getByText('Orgs'),
).toBeVisible();
// View the OIDC account and verify account attributes
await page.getByRole('link', { name: orgName }).click();
await expect(
page.getByRole('navigation', { name: 'breadcrumbs' }).getByText(orgName),
).toBeVisible();
await page
.getByRole('navigation', { name: 'IAM' })
.getByRole('link', { name: 'Auth Methods' })
.click();
await page.getByRole('link', { name: oidcAuthMethodName }).click();
await page.getByRole('link', { name: 'Accounts' }).click();
await expect(
page
.getByRole('navigation', { name: 'breadcrumbs' })
.getByText('Accounts'),
).toBeVisible();
let headersCount = await page
.getByRole('table')
.getByRole('columnheader')
.count();
let fullNameIndex;
let emailIndex;
for (let i = 0; i < headersCount; i++) {
const header = await page
.getByRole('table')
.getByRole('columnheader')
.nth(i)
.innerText();
if (header == 'Full Name') {
fullNameIndex = i;
} else if (header == 'Email') {
emailIndex = i;
}
}
await expect(
page
.getByRole('cell', { name: userName })
.locator('..')
.getByRole('cell')
.nth(fullNameIndex),
).toHaveText(userName);
await expect(
page
.getByRole('cell', { name: userName })
.locator('..')
.getByRole('cell')
.nth(emailIndex),
).toHaveText(email);
// View the OIDC Managed Group and verify member in managed group
await page.getByRole('link', { name: 'Managed Groups' }).click();
await page.getByRole('link', { name: oidcManagedGroupName }).click();
await page.getByRole('link', { name: 'Members' }).click();
await expect(
page
.getByRole('navigation', { name: 'breadcrumbs' })
.getByText('Members'),
).toBeVisible();
headersCount = await page
.getByRole('table')
.getByRole('columnheader')
.count();
for (let i = 0; i < headersCount; i++) {
const header = await page
.getByRole('table')
.getByRole('columnheader')
.nth(i)
.innerText();
if (header == 'Full Name') {
fullNameIndex = i;
} else if (header == 'Email') {
emailIndex = i;
}
}
await expect(
page
.getByRole('cell', { name: userName })
.locator('..')
.getByRole('cell')
.nth(fullNameIndex),
).toHaveText(userName);
await expect(
page
.getByRole('cell', { name: userName })
.locator('..')
.getByRole('cell')
.nth(emailIndex),
).toHaveText(email);
// View the User account and verify attributes
await page
.getByRole('navigation', { name: 'IAM' })
.getByRole('link', { name: 'Users' })
.click();
await page.getByRole('cell', { hasText: email }).getByRole('link').click();
await page.getByRole('link', { name: 'Accounts' }).click();
expect(
// Create an OIDC managed group
await page
.getByRole('table')
.getByRole('row')
.nth(1) // Account row
.getByRole('cell')
.nth(0) // Name field
.innerText(),
).toContain(email);
} finally {
execSync(`vault auth disable userpass`);
execSync(`vault policy delete ${policyName}`);
.getByRole('navigation', { name: 'breadcrumbs' })
.getByText(oidcAuthMethodName)
.click();
await page.getByText('Manage', { exact: true }).click();
await page.getByRole('link', { name: 'Create Managed Group' }).click();
const oidcManagedGroupName = 'OIDC Managed Group';
await page.getByLabel('Name (Optional)').fill(oidcManagedGroupName);
await page.getByLabel('Description').fill('This is an automated test');
await page
.getByLabel('Filter')
.fill(`"engineering" in "/userinfo/groups"`);
await page.getByRole('button', { name: 'Save' }).click();
await expect(
page.getByRole('alert').getByText('Success', { exact: true }),
).toBeVisible();
await page.getByRole('button', { name: 'Dismiss' }).click();
if (orgName) {
await boundaryCli.authenticateBoundary(
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
);
const orgId = await boundaryCli.getOrgIdFromName(orgName);
if (orgId) {
await boundaryCli.deleteScope(orgId);
// Create a role and add LDAP managed group to role
const rolesPage = new RolesPage(page);
await rolesPage.createRole();
await rolesPage.addPrincipalToRole(oidcManagedGroupName);
// Log in using oidc account
await loginPage.logout(adminLoginName);
await page.getByText('Choose a different scope').click();
await page.getByRole('link', { name: orgName }).click();
await page.getByRole('link', { name: oidcAuthMethodName }).click();
const pagePromise = context.waitForEvent('page');
await page.getByRole('button', { name: 'Sign In' }).click();
const vaultPage = await pagePromise;
await vaultPage.getByLabel('Method').selectOption('Username');
await vaultPage.getByLabel('Username').fill(userName);
await vaultPage.getByLabel('Password').fill(password);
await vaultPage.getByRole('button', { name: 'Sign In' }).click();
await expect(
page
.getByRole('navigation', { name: 'breadcrumbs' })
.getByText('Projects'),
).toBeVisible();
// Log back in as an admin
// WORKAROUND: Currently, users logging using OIDC don't have a username
// displayed in the UI, so there's no simple locator to access this menu.
await page.locator('details').filter({ hasText: 'Sign Out' }).click();
await page.getByRole('button', { name: 'Sign Out' }).click();
await expect(page.getByRole('button', { name: 'Sign In' })).toBeVisible();
await loginPage.login(adminLoginName, adminPassword);
await expect(
page.getByRole('navigation', { name: 'breadcrumbs' }).getByText('Orgs'),
).toBeVisible();
// View the OIDC account and verify account attributes
await page.getByRole('link', { name: orgName }).click();
await expect(
page
.getByRole('navigation', { name: 'breadcrumbs' })
.getByText(orgName),
).toBeVisible();
await page
.getByRole('navigation', { name: 'IAM' })
.getByRole('link', { name: 'Auth Methods' })
.click();
await page.getByRole('link', { name: oidcAuthMethodName }).click();
await page.getByRole('link', { name: 'Accounts' }).click();
await expect(
page
.getByRole('navigation', { name: 'breadcrumbs' })
.getByText('Accounts'),
).toBeVisible();
let headersCount = await page
.getByRole('table')
.getByRole('columnheader')
.count();
let fullNameIndex;
let emailIndex;
for (let i = 0; i < headersCount; i++) {
const header = await page
.getByRole('table')
.getByRole('columnheader')
.nth(i)
.innerText();
if (header == 'Full Name') {
fullNameIndex = i;
} else if (header == 'Email') {
emailIndex = i;
}
}
await expect(
page
.getByRole('cell', { name: userName })
.locator('..')
.getByRole('cell')
.nth(fullNameIndex),
).toHaveText(userName);
await expect(
page
.getByRole('cell', { name: userName })
.locator('..')
.getByRole('cell')
.nth(emailIndex),
).toHaveText(email);
// View the OIDC Managed Group and verify member in managed group
await page.getByRole('link', { name: 'Managed Groups' }).click();
await page.getByRole('link', { name: oidcManagedGroupName }).click();
await page.getByRole('link', { name: 'Members' }).click();
await expect(
page
.getByRole('navigation', { name: 'breadcrumbs' })
.getByText('Members'),
).toBeVisible();
headersCount = await page
.getByRole('table')
.getByRole('columnheader')
.count();
for (let i = 0; i < headersCount; i++) {
const header = await page
.getByRole('table')
.getByRole('columnheader')
.nth(i)
.innerText();
if (header == 'Full Name') {
fullNameIndex = i;
} else if (header == 'Email') {
emailIndex = i;
}
}
await expect(
page
.getByRole('cell', { name: userName })
.locator('..')
.getByRole('cell')
.nth(fullNameIndex),
).toHaveText(userName);
await expect(
page
.getByRole('cell', { name: userName })
.locator('..')
.getByRole('cell')
.nth(emailIndex),
).toHaveText(email);
// View the User account and verify attributes
await page
.getByRole('navigation', { name: 'IAM' })
.getByRole('link', { name: 'Users' })
.click();
await page
.getByRole('cell', { hasText: email })
.getByRole('link')
.click();
await page.getByRole('link', { name: 'Accounts' }).click();
expect(
await page
.getByRole('table')
.getByRole('row')
.nth(1) // Account row
.getByRole('cell')
.nth(0) // Name field
.innerText(),
).toContain(email);
} finally {
execSync(`vault auth disable userpass`);
execSync(`vault policy delete ${policyName}`);
if (orgName) {
await boundaryCli.authenticateBoundary(
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
);
const orgId = await boundaryCli.getOrgIdFromName(orgName);
if (orgId) {
await boundaryCli.deleteScope(orgId);
}
}
}
}
});
},
);
+108 -102
View File
@@ -20,118 +20,124 @@ test.beforeAll(async () => {
await boundaryCli.checkBoundaryCli();
});
test('Verify new auth-method can be created and assigned to users @ce @ent @aws @docker', async ({
page,
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
}) => {
await page.goto('/');
let orgName;
let authMethodName;
try {
// Log in
const loginPage = new LoginPage(page);
await loginPage.login(adminLoginName, adminPassword);
await expect(
page.getByRole('navigation', { name: 'breadcrumbs' }).getByText('Orgs'),
).toBeVisible();
test(
'Verify new auth-method can be created and assigned to users',
{ tag: ['@ce', '@ent', '@aws', '@docker'] },
async ({
page,
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
}) => {
await page.goto('/');
let orgName;
let authMethodName;
try {
// Log in
const loginPage = new LoginPage(page);
await loginPage.login(adminLoginName, adminPassword);
await expect(
page.getByRole('navigation', { name: 'breadcrumbs' }).getByText('Orgs'),
).toBeVisible();
// Create a new password auth method and account
const orgsPage = new OrgsPage(page);
orgName = await orgsPage.createOrg();
// Create a new password auth method and account
const orgsPage = new OrgsPage(page);
orgName = await orgsPage.createOrg();
const authMethodsPage = new AuthMethodsPage(page);
authMethodName = await authMethodsPage.createPasswordAuthMethod();
const username = 'test-user';
const password = 'password';
const authMethodsPage = new AuthMethodsPage(page);
authMethodName = await authMethodsPage.createPasswordAuthMethod();
const username = 'test-user';
const password = 'password';
await authMethodsPage.createPasswordAccount(username, password);
await authMethodsPage.makeAuthMethodPrimary();
const usersPage = new UsersPage(page);
await usersPage.createUser();
await usersPage.addAccountToUser(username);
await authMethodsPage.createPasswordAccount(username, password);
await authMethodsPage.makeAuthMethodPrimary();
const usersPage = new UsersPage(page);
await usersPage.createUser();
await usersPage.addAccountToUser(username);
// Log in using new account
await loginPage.logout(adminLoginName);
await page.getByText('Choose a different scope').click();
await page.getByRole('link', { name: orgName }).click();
await page.getByRole('link', { name: authMethodName }).click();
// Log in using new account
await loginPage.logout(adminLoginName);
await page.getByText('Choose a different scope').click();
await page.getByRole('link', { name: orgName }).click();
await page.getByRole('link', { name: authMethodName }).click();
await loginPage.login(username, password);
await expect(
page
.getByRole('navigation', { name: 'breadcrumbs' })
.getByText('Projects'),
).toBeVisible();
await loginPage.login(username, password);
await expect(
page
.getByRole('navigation', { name: 'breadcrumbs' })
.getByText('Projects'),
).toBeVisible();
// Log back in as admin
await loginPage.logout(username);
await loginPage.login(adminLoginName, adminPassword);
// Log back in as admin
await loginPage.logout(username);
await loginPage.login(adminLoginName, adminPassword);
// Set a new password on the account
await page
.getByRole('navigation', { name: 'General' })
.getByRole('link', { name: 'Orgs' })
.click();
await page.getByRole('link', { name: orgName }).click();
await expect(
page.getByRole('navigation', { name: 'breadcrumbs' }).getByText(orgName),
).toBeVisible();
await page
.getByRole('navigation', { name: 'IAM' })
.getByRole('link', { name: 'Auth Methods' })
.click();
await page.getByRole('link', { name: authMethodName }).click();
await page.getByRole('link', { name: 'Accounts', exact: true }).click();
await page.getByRole('link', { name: username }).click();
const newPassword = 'new-password';
await authMethodsPage.setPasswordToAccount(newPassword);
// Set a new password on the account
await page
.getByRole('navigation', { name: 'General' })
.getByRole('link', { name: 'Orgs' })
.click();
await page.getByRole('link', { name: orgName }).click();
await expect(
page
.getByRole('navigation', { name: 'breadcrumbs' })
.getByText(orgName),
).toBeVisible();
await page
.getByRole('navigation', { name: 'IAM' })
.getByRole('link', { name: 'Auth Methods' })
.click();
await page.getByRole('link', { name: authMethodName }).click();
await page.getByRole('link', { name: 'Accounts', exact: true }).click();
await page.getByRole('link', { name: username }).click();
const newPassword = 'new-password';
await authMethodsPage.setPasswordToAccount(newPassword);
// Log in using new password
await loginPage.logout(adminLoginName);
// Log in using new password
await loginPage.logout(adminLoginName);
await page.getByText('Choose a different scope').click();
await page.getByRole('link', { name: orgName }).click();
await page.getByRole('link', { name: authMethodName }).click();
await loginPage.login(username, newPassword);
await expect(
page
.getByRole('navigation', { name: 'breadcrumbs' })
.getByText('Projects'),
).toBeVisible();
} finally {
await boundaryCli.authenticateBoundary(
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
);
// There is an issue with deleting an org that has an auth method unless you
// delete the auth method first
if (authMethodName) {
const authMethods = JSON.parse(
execSync('boundary auth-methods list --recursive -format json'),
await page.getByText('Choose a different scope').click();
await page.getByRole('link', { name: orgName }).click();
await page.getByRole('link', { name: authMethodName }).click();
await loginPage.login(username, newPassword);
await expect(
page
.getByRole('navigation', { name: 'breadcrumbs' })
.getByText('Projects'),
).toBeVisible();
} finally {
await boundaryCli.authenticateBoundary(
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
);
const authMethod = authMethods.items.filter(
(obj) => obj.name == authMethodName,
)[0];
if (authMethod) {
try {
execSync('boundary auth-methods delete -id=' + authMethod.id);
} catch (e) {
console.log(`${e.stderr}`);
// There is an issue with deleting an org that has an auth method unless you
// delete the auth method first
if (authMethodName) {
const authMethods = JSON.parse(
execSync('boundary auth-methods list --recursive -format json'),
);
const authMethod = authMethods.items.filter(
(obj) => obj.name == authMethodName,
)[0];
if (authMethod) {
try {
execSync('boundary auth-methods delete -id=' + authMethod.id);
} catch (e) {
console.log(`${e.stderr}`);
}
}
}
if (orgName) {
const orgId = await boundaryCli.getOrgIdFromName(orgName);
if (orgId) {
await boundaryCli.deleteScope(orgId);
}
}
}
if (orgName) {
const orgId = await boundaryCli.getOrgIdFromName(orgName);
if (orgId) {
await boundaryCli.deleteScope(orgId);
}
}
}
});
},
);
@@ -18,120 +18,93 @@ test.beforeAll(async () => {
await boundaryCli.checkBoundaryCli();
});
test('Multiple Credential Stores (ENT) @ent @aws @docker', async ({
page,
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
sshUser,
sshKeyPath,
targetAddress,
targetPort,
}) => {
let orgName;
try {
await page.goto('/');
test(
'Multiple Credential Stores (ENT)',
{ tag: ['@ent', '@aws', '@docker'] },
async ({
page,
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
sshUser,
sshKeyPath,
targetAddress,
targetPort,
}) => {
let orgName;
try {
await page.goto('/');
const orgsPage = new OrgsPage(page);
orgName = await orgsPage.createOrg();
const projectsPage = new ProjectsPage(page);
const projectName = await projectsPage.createProject();
const targetsPage = new TargetsPage(page);
const targetName = await targetsPage.createSshTargetWithAddressEnt(
targetAddress,
targetPort,
);
const credentialStoresPage = new CredentialStoresPage(page);
await credentialStoresPage.createStaticCredentialStore();
const credentialName =
await credentialStoresPage.createStaticCredentialKeyPair(
sshUser,
sshKeyPath,
const orgsPage = new OrgsPage(page);
orgName = await orgsPage.createOrg();
const projectsPage = new ProjectsPage(page);
const projectName = await projectsPage.createProject();
const targetsPage = new TargetsPage(page);
const targetName = await targetsPage.createSshTargetWithAddressEnt(
targetAddress,
targetPort,
);
const credentialName2 =
await credentialStoresPage.createStaticCredentialUsernamePassword(
sshUser,
'testPassword',
const credentialStoresPage = new CredentialStoresPage(page);
await credentialStoresPage.createStaticCredentialStore();
const credentialName =
await credentialStoresPage.createStaticCredentialKeyPair(
sshUser,
sshKeyPath,
);
const credentialName2 =
await credentialStoresPage.createStaticCredentialUsernamePassword(
sshUser,
'testPassword',
);
await targetsPage.addBrokeredCredentialsToTarget(
targetName,
credentialName,
);
await targetsPage.addBrokeredCredentialsToTarget(
targetName,
credentialName2,
);
await targetsPage.addBrokeredCredentialsToTarget(
targetName,
credentialName,
);
await targetsPage.addBrokeredCredentialsToTarget(
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', exact: true }).click();
await expect(
page.getByRole('alert').getByText('Success', { exact: true }),
).toBeVisible();
await page.getByRole('button', { name: 'Dismiss' }).click();
// 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', exact: true }).click();
await expect(
page.getByRole('alert').getByText('Success', { exact: true }),
).toBeVisible();
await page.getByRole('button', { name: 'Dismiss' }).click();
await targetsPage.addInjectedCredentialsToTarget(
targetName,
credentialName,
);
await targetsPage.addInjectedCredentialsToTarget(
targetName,
credentialName2,
);
await targetsPage.addInjectedCredentialsToTarget(
targetName,
credentialName,
);
await targetsPage.addInjectedCredentialsToTarget(
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', exact: true }).click();
await expect(
page.getByRole('alert').getByText('Success', { exact: true }),
).toBeVisible();
await page.getByRole('button', { name: 'Dismiss' }).click();
// 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', exact: true }).click();
await expect(
page.getByRole('alert').getByText('Success', { exact: true }),
).toBeVisible();
await page.getByRole('button', { name: 'Dismiss' }).click();
// Verify credentials
await boundaryCli.authenticateBoundary(
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
);
const orgId = await boundaryCli.getOrgIdFromName(orgName);
const projectId = await boundaryCli.getProjectIdFromName(
orgId,
projectName,
);
const targetId = await boundaryCli.getTargetIdFromName(
projectId,
targetName,
);
const session = await boundaryCli.authorizeSessionByTargetId(targetId);
const retrievedUser = session.item.credentials[0].credential.username;
const retrievedKey = session.item.credentials[0].credential.private_key;
expect(retrievedUser).toBe(sshUser);
const keyData = await readFile(sshKeyPath, {
encoding: 'utf-8',
});
expect(retrievedKey).toBe(keyData);
const sessionsPage = new SessionsPage(page);
await sessionsPage.waitForSessionToBeVisible(targetName);
} finally {
if (orgName) {
// Verify credentials
await boundaryCli.authenticateBoundary(
baseURL,
adminAuthMethodId,
@@ -139,9 +112,40 @@ test('Multiple Credential Stores (ENT) @ent @aws @docker', async ({
adminPassword,
);
const orgId = await boundaryCli.getOrgIdFromName(orgName);
if (orgId) {
await boundaryCli.deleteScope(orgId);
const projectId = await boundaryCli.getProjectIdFromName(
orgId,
projectName,
);
const targetId = await boundaryCli.getTargetIdFromName(
projectId,
targetName,
);
const session = await boundaryCli.authorizeSessionByTargetId(targetId);
const retrievedUser = session.item.credentials[0].credential.username;
const retrievedKey = session.item.credentials[0].credential.private_key;
expect(retrievedUser).toBe(sshUser);
const keyData = await readFile(sshKeyPath, {
encoding: 'utf-8',
});
expect(retrievedKey).toBe(keyData);
const sessionsPage = new SessionsPage(page);
await sessionsPage.waitForSessionToBeVisible(targetName);
} finally {
if (orgName) {
await boundaryCli.authenticateBoundary(
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
);
const orgId = await boundaryCli.getOrgIdFromName(orgName);
if (orgId) {
await boundaryCli.deleteScope(orgId);
}
}
}
}
});
},
);
@@ -39,58 +39,31 @@ test.beforeEach(async ({ page, targetAddress, targetPort }) => {
await credentialStoresPage.createStaticCredentialStore();
});
test('Static Credential Store (User & Key Pair) @ce @aws @docker', async ({
page,
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
sshUser,
sshKeyPath,
}) => {
try {
const credentialStoresPage = new CredentialStoresPage(page);
const credentialName =
await credentialStoresPage.createStaticCredentialKeyPair(
sshUser,
sshKeyPath,
test(
'Static Credential Store (User & Key Pair)',
{ tag: ['@ce', '@aws', '@docker'] },
async ({
page,
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
sshUser,
sshKeyPath,
}) => {
try {
const credentialStoresPage = new CredentialStoresPage(page);
const credentialName =
await credentialStoresPage.createStaticCredentialKeyPair(
sshUser,
sshKeyPath,
);
const targetsPage = new TargetsPage(page);
await targetsPage.addBrokeredCredentialsToTarget(
targetName,
credentialName,
);
const targetsPage = new TargetsPage(page);
await targetsPage.addBrokeredCredentialsToTarget(
targetName,
credentialName,
);
await boundaryCli.authenticateBoundary(
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
);
const orgId = await boundaryCli.getOrgIdFromName(orgName);
const projectId = await boundaryCli.getProjectIdFromName(
orgId,
projectName,
);
const targetId = await boundaryCli.getTargetIdFromName(
projectId,
targetName,
);
const session = await boundaryCli.authorizeSessionByTargetId(targetId);
const retrievedUser = session.item.credentials[0].credential.username;
const retrievedKey = session.item.credentials[0].credential.private_key;
expect(retrievedUser).toBe(sshUser);
const keyData = await readFile(sshKeyPath, {
encoding: 'utf-8',
});
expect(retrievedKey).toBe(keyData);
const sessionsPage = new SessionsPage(page);
await sessionsPage.waitForSessionToBeVisible(targetName);
} finally {
if (orgName) {
await boundaryCli.authenticateBoundary(
baseURL,
adminAuthMethodId,
@@ -98,61 +71,69 @@ test('Static Credential Store (User & Key Pair) @ce @aws @docker', async ({
adminPassword,
);
const orgId = await boundaryCli.getOrgIdFromName(orgName);
if (orgId) {
await boundaryCli.deleteScope(orgId);
const projectId = await boundaryCli.getProjectIdFromName(
orgId,
projectName,
);
const targetId = await boundaryCli.getTargetIdFromName(
projectId,
targetName,
);
const session = await boundaryCli.authorizeSessionByTargetId(targetId);
const retrievedUser = session.item.credentials[0].credential.username;
const retrievedKey = session.item.credentials[0].credential.private_key;
expect(retrievedUser).toBe(sshUser);
const keyData = await readFile(sshKeyPath, {
encoding: 'utf-8',
});
expect(retrievedKey).toBe(keyData);
const sessionsPage = new SessionsPage(page);
await sessionsPage.waitForSessionToBeVisible(targetName);
} finally {
if (orgName) {
await boundaryCli.authenticateBoundary(
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
);
const orgId = await boundaryCli.getOrgIdFromName(orgName);
if (orgId) {
await boundaryCli.deleteScope(orgId);
}
}
}
}
});
},
);
test('Static Credential Store (Username & Password) @ce @aws @docker', async ({
page,
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
sshUser,
}) => {
try {
const testPassword = 'password';
const credentialStoresPage = new CredentialStoresPage(page);
const credentialName =
await credentialStoresPage.createStaticCredentialUsernamePassword(
sshUser,
testPassword,
test(
'Static Credential Store (Username & Password)',
{ tag: ['@ce', '@aws', '@docker'] },
async ({
page,
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
sshUser,
}) => {
try {
const testPassword = 'password';
const credentialStoresPage = new CredentialStoresPage(page);
const credentialName =
await credentialStoresPage.createStaticCredentialUsernamePassword(
sshUser,
testPassword,
);
const targetsPage = new TargetsPage(page);
await targetsPage.addBrokeredCredentialsToTarget(
targetName,
credentialName,
);
const targetsPage = new TargetsPage(page);
await targetsPage.addBrokeredCredentialsToTarget(
targetName,
credentialName,
);
await boundaryCli.authenticateBoundary(
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
);
const orgId = await boundaryCli.getOrgIdFromName(orgName);
const projectId = await boundaryCli.getProjectIdFromName(
orgId,
projectName,
);
const targetId = await boundaryCli.getTargetIdFromName(
projectId,
targetName,
);
const session = await boundaryCli.authorizeSessionByTargetId(targetId);
const retrievedUser = session.item.credentials[0].credential.username;
const retrievedPassword = session.item.credentials[0].credential.password;
expect(retrievedUser).toBe(sshUser);
expect(retrievedPassword).toBe(testPassword);
const sessionsPage = new SessionsPage(page);
await sessionsPage.waitForSessionToBeVisible(targetName);
} finally {
if (orgName) {
await boundaryCli.authenticateBoundary(
baseURL,
adminAuthMethodId,
@@ -160,81 +141,88 @@ test('Static Credential Store (Username & Password) @ce @aws @docker', async ({
adminPassword,
);
const orgId = await boundaryCli.getOrgIdFromName(orgName);
if (orgId) {
await boundaryCli.deleteScope(orgId);
const projectId = await boundaryCli.getProjectIdFromName(
orgId,
projectName,
);
const targetId = await boundaryCli.getTargetIdFromName(
projectId,
targetName,
);
const session = await boundaryCli.authorizeSessionByTargetId(targetId);
const retrievedUser = session.item.credentials[0].credential.username;
const retrievedPassword = session.item.credentials[0].credential.password;
expect(retrievedUser).toBe(sshUser);
expect(retrievedPassword).toBe(testPassword);
const sessionsPage = new SessionsPage(page);
await sessionsPage.waitForSessionToBeVisible(targetName);
} finally {
if (orgName) {
await boundaryCli.authenticateBoundary(
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
);
const orgId = await boundaryCli.getOrgIdFromName(orgName);
if (orgId) {
await boundaryCli.deleteScope(orgId);
}
}
}
}
});
},
);
test('Static Credential Store (JSON) @ce @aws @docker', async ({
page,
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
}) => {
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}",
test(
'Static Credential Store (JSON)',
{ tag: ['@ce', '@aws', '@docker'] },
async ({
page,
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
}) => {
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 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();
const targetsPage = new TargetsPage(page);
await targetsPage.addBrokeredCredentialsToTarget(
targetName,
credentialName,
);
const targetsPage = new TargetsPage(page);
await targetsPage.addBrokeredCredentialsToTarget(
targetName,
credentialName,
);
await boundaryCli.authenticateBoundary(
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
);
const orgId = await boundaryCli.getOrgIdFromName(orgName);
const projectId = await boundaryCli.getProjectIdFromName(
orgId,
projectName,
);
const targetId = await boundaryCli.getTargetIdFromName(
projectId,
targetName,
);
const session = await boundaryCli.authorizeSessionByTargetId(targetId);
const retrievedUser = session.item.credentials[0].credential.username;
const retrievedPassword = session.item.credentials[0].credential.password;
const retrievedId = session.item.credentials[0].credential.id;
expect(retrievedUser).toBe(testName);
expect(retrievedPassword).toBe(testPassword);
expect(retrievedId).toBe(testId);
const sessionsPage = new SessionsPage(page);
await sessionsPage.waitForSessionToBeVisible(targetName);
} finally {
if (orgName) {
await boundaryCli.authenticateBoundary(
baseURL,
adminAuthMethodId,
@@ -242,70 +230,103 @@ test('Static Credential Store (JSON) @ce @aws @docker', async ({
adminPassword,
);
const orgId = await boundaryCli.getOrgIdFromName(orgName);
if (orgId) {
await boundaryCli.deleteScope(orgId);
const projectId = await boundaryCli.getProjectIdFromName(
orgId,
projectName,
);
const targetId = await boundaryCli.getTargetIdFromName(
projectId,
targetName,
);
const session = await boundaryCli.authorizeSessionByTargetId(targetId);
const retrievedUser = session.item.credentials[0].credential.username;
const retrievedPassword = session.item.credentials[0].credential.password;
const retrievedId = session.item.credentials[0].credential.id;
expect(retrievedUser).toBe(testName);
expect(retrievedPassword).toBe(testPassword);
expect(retrievedId).toBe(testId);
const sessionsPage = new SessionsPage(page);
await sessionsPage.waitForSessionToBeVisible(targetName);
} finally {
if (orgName) {
await boundaryCli.authenticateBoundary(
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
);
const orgId = await boundaryCli.getOrgIdFromName(orgName);
if (orgId) {
await boundaryCli.deleteScope(orgId);
}
}
}
}
});
},
);
test('Multiple Credential Stores (CE) @ce @aws @docker', async ({
page,
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
sshUser,
sshKeyPath,
}) => {
try {
const credentialStoresPage = new CredentialStoresPage(page);
const credentialName =
await credentialStoresPage.createStaticCredentialKeyPair(
sshUser,
sshKeyPath,
test(
'Multiple Credential Stores (CE)',
{ tag: ['@ce', '@aws', '@docker'] },
async ({
page,
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
sshUser,
sshKeyPath,
}) => {
try {
const credentialStoresPage = new CredentialStoresPage(page);
const credentialName =
await credentialStoresPage.createStaticCredentialKeyPair(
sshUser,
sshKeyPath,
);
const credentialName2 =
await credentialStoresPage.createStaticCredentialUsernamePassword(
sshUser,
'testPassword',
);
const targetsPage = new TargetsPage(page);
await targetsPage.addBrokeredCredentialsToTarget(
targetName,
credentialName,
);
const credentialName2 =
await credentialStoresPage.createStaticCredentialUsernamePassword(
sshUser,
'testPassword',
await targetsPage.addBrokeredCredentialsToTarget(
targetName,
credentialName2,
);
const targetsPage = new TargetsPage(page);
await targetsPage.addBrokeredCredentialsToTarget(
targetName,
credentialName,
);
await targetsPage.addBrokeredCredentialsToTarget(
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', exact: true }).click();
await expect(
page.getByRole('alert').getByText('Success', { exact: true }),
).toBeVisible();
await page.getByRole('button', { name: 'Dismiss' }).click();
} finally {
if (orgName) {
await boundaryCli.authenticateBoundary(
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
);
const orgId = await boundaryCli.getOrgIdFromName(orgName);
if (orgId) {
await boundaryCli.deleteScope(orgId);
// 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', exact: true }).click();
await expect(
page.getByRole('alert').getByText('Success', { exact: true }),
).toBeVisible();
await page.getByRole('button', { name: 'Dismiss' }).click();
} finally {
if (orgName) {
await boundaryCli.authenticateBoundary(
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
);
const orgId = await boundaryCli.getOrgIdFromName(orgName);
if (orgId) {
await boundaryCli.deleteScope(orgId);
}
}
}
}
});
},
);
@@ -34,97 +34,101 @@ test.afterEach(() => {
execSync(`vault secrets disable ${secretsPath}`);
});
test('Vault Credential Store (User & Key Pair) @ent @aws @docker', async ({
page,
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
sshUser,
sshKeyPath,
targetAddress,
targetPort,
vaultAddr,
}) => {
let orgId;
let connect;
try {
execSync(
`vault policy write ${boundaryPolicyName} ./admin/tests/fixtures/boundary-controller-policy.hcl`,
);
execSync(`vault secrets enable -path=${secretsPath} kv-v2`);
execSync(
`vault kv put -mount ${secretsPath} ${secretName} ` +
` username=${sshUser}` +
` private_key=@${sshKeyPath}`,
);
execSync(
`vault policy write ${secretPolicyName} ./admin/tests/fixtures/kv-policy.hcl`,
);
const vaultToken = JSON.parse(
test(
'Vault Credential Store (User & Key Pair)',
{ tag: ['@ent', '@aws', '@docker'] },
async ({
page,
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
sshUser,
sshKeyPath,
targetAddress,
targetPort,
vaultAddr,
}) => {
let orgId;
let connect;
try {
execSync(
`vault token create` +
` -no-default-policy=true` +
` -policy=${boundaryPolicyName}` +
` -policy=${secretPolicyName}` +
` -orphan=true` +
` -period=20m` +
` -renewable=true` +
` -format=json`,
),
);
const clientToken = vaultToken.auth.client_token;
const orgsPage = new OrgsPage(page);
const orgName = await orgsPage.createOrg();
const projectsPage = new ProjectsPage(page);
const projectName = await projectsPage.createProject();
const targetsPage = new TargetsPage(page);
const targetName = await targetsPage.createSshTargetWithAddressEnt(
targetAddress,
targetPort,
);
const credentialStoresPage = new CredentialStoresPage(page);
await credentialStoresPage.createVaultCredentialStore(
vaultAddr,
clientToken,
);
const credentialLibraryName =
await credentialStoresPage.createVaultGenericCredentialLibraryEnt(
`${secretsPath}/data/${secretName}`,
'SSH Private Key',
`vault policy write ${boundaryPolicyName} ./admin/tests/fixtures/boundary-controller-policy.hcl`,
);
await targetsPage.addInjectedCredentialsToTarget(
targetName,
credentialLibraryName,
);
execSync(`vault secrets enable -path=${secretsPath} kv-v2`);
execSync(
`vault kv put -mount ${secretsPath} ${secretName} ` +
` username=${sshUser}` +
` private_key=@${sshKeyPath}`,
);
execSync(
`vault policy write ${secretPolicyName} ./admin/tests/fixtures/kv-policy.hcl`,
);
const vaultToken = JSON.parse(
execSync(
`vault token create` +
` -no-default-policy=true` +
` -policy=${boundaryPolicyName}` +
` -policy=${secretPolicyName}` +
` -orphan=true` +
` -period=20m` +
` -renewable=true` +
` -format=json`,
),
);
const clientToken = vaultToken.auth.client_token;
// Verify that session can be established
await boundaryCli.authenticateBoundary(
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
);
orgId = await boundaryCli.getOrgIdFromName(orgName);
const projectId = await boundaryCli.getProjectIdFromName(
orgId,
projectName,
);
const targetId = await boundaryCli.getTargetIdFromName(
projectId,
targetName,
);
connect = await boundaryCli.connectSshToTarget(targetId);
const sessionsPage = new SessionsPage(page);
await sessionsPage.waitForSessionToBeVisible(targetName);
} finally {
if (connect) {
connect.kill('SIGTERM');
}
const orgsPage = new OrgsPage(page);
const orgName = await orgsPage.createOrg();
const projectsPage = new ProjectsPage(page);
const projectName = await projectsPage.createProject();
const targetsPage = new TargetsPage(page);
const targetName = await targetsPage.createSshTargetWithAddressEnt(
targetAddress,
targetPort,
);
const credentialStoresPage = new CredentialStoresPage(page);
await credentialStoresPage.createVaultCredentialStore(
vaultAddr,
clientToken,
);
const credentialLibraryName =
await credentialStoresPage.createVaultGenericCredentialLibraryEnt(
`${secretsPath}/data/${secretName}`,
'SSH Private Key',
);
await targetsPage.addInjectedCredentialsToTarget(
targetName,
credentialLibraryName,
);
if (orgId) {
await boundaryCli.deleteScope(orgId);
// Verify that session can be established
await boundaryCli.authenticateBoundary(
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
);
orgId = await boundaryCli.getOrgIdFromName(orgName);
const projectId = await boundaryCli.getProjectIdFromName(
orgId,
projectName,
);
const targetId = await boundaryCli.getTargetIdFromName(
projectId,
targetName,
);
connect = await boundaryCli.connectSshToTarget(targetId);
const sessionsPage = new SessionsPage(page);
await sessionsPage.waitForSessionToBeVisible(targetName);
} finally {
if (connect) {
connect.kill('SIGTERM');
}
if (orgId) {
await boundaryCli.deleteScope(orgId);
}
}
}
});
},
);
@@ -35,119 +35,123 @@ test.afterEach(() => {
execSync(`vault policy delete ${secretPolicyName}`);
execSync(`vault policy delete ${boundaryPolicyName}`);
execSync(`vault secrets disable ${secretsPath}`);
})
test('Vault Credential Store (User & Key Pair) @ce @aws @docker', async ({
page,
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
sshUser,
sshKeyPath,
targetAddress,
targetPort,
vaultAddr,
}) => {
let orgId;
try {
execSync(
`vault policy write ${boundaryPolicyName} ./admin/tests/fixtures/boundary-controller-policy.hcl`,
);
execSync(`vault secrets enable -path=${secretsPath} kv-v2`);
execSync(
`vault kv put -mount ${secretsPath} ${secretName} ` +
` username=${sshUser}` +
` private_key=@${sshKeyPath}`,
);
execSync(
`vault policy write ${secretPolicyName} ./admin/tests/fixtures/kv-policy.hcl`,
);
const vaultToken = JSON.parse(
execSync(
`vault token create` +
` -no-default-policy=true` +
` -policy=${boundaryPolicyName}` +
` -policy=${secretPolicyName}` +
` -orphan=true` +
` -period=20m` +
` -renewable=true` +
` -format=json`,
),
);
const clientToken = vaultToken.auth.client_token;
const orgsPage = new OrgsPage(page);
const orgName = await orgsPage.createOrg();
const projectsPage = new ProjectsPage(page);
const projectName = await projectsPage.createProject();
const targetsPage = new TargetsPage(page);
const targetName = await targetsPage.createTargetWithAddress(
targetAddress,
targetPort,
);
const credentialStoresPage = new CredentialStoresPage(page);
await credentialStoresPage.createVaultCredentialStore(
vaultAddr,
clientToken,
);
const credentialLibraryName = 'Credential Library ' + nanoid();
await page.getByRole('link', { name: 'Credential Libraries' }).click();
await page.getByRole('link', { name: 'New', exact: true }).click();
await page
.getByLabel('Name (Optional)', { exact: true })
.fill(credentialLibraryName);
await page
.getByLabel('Description (Optional)')
.fill('This is an automated test');
await page
.getByLabel('Vault Path')
.fill(`${secretsPath}/data/${secretName}`);
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 targetsPage.addBrokeredCredentialsToTarget(
targetName,
credentialLibraryName,
);
// Verify correct credentials are returned after authorizing session
await boundaryCli.authenticateBoundary(
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
);
orgId = await boundaryCli.getOrgIdFromName(orgName);
const projectId = await boundaryCli.getProjectIdFromName(
orgId,
projectName,
);
const targetId = await boundaryCli.getTargetIdFromName(
projectId,
targetName,
);
const session = await boundaryCli.authorizeSessionByTargetId(targetId);
const retrievedUser =
session.item.credentials[0].secret.decoded.data.username;
const retrievedKey =
session.item.credentials[0].secret.decoded.data.private_key;
expect(retrievedUser).toBe(sshUser);
const keyData = await readFile(sshKeyPath, {
encoding: 'utf-8',
});
expect(retrievedKey).toBe(keyData);
const sessionsPage = new SessionsPage(page);
await sessionsPage.waitForSessionToBeVisible(targetName);
} finally {
if (orgId) {
await boundaryCli.deleteScope(orgId);
}
}
});
test(
'Vault Credential Store (User & Key Pair)',
{ tag: ['@ce', '@aws', '@docker'] },
async ({
page,
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
sshUser,
sshKeyPath,
targetAddress,
targetPort,
vaultAddr,
}) => {
let orgId;
try {
execSync(
`vault policy write ${boundaryPolicyName} ./admin/tests/fixtures/boundary-controller-policy.hcl`,
);
execSync(`vault secrets enable -path=${secretsPath} kv-v2`);
execSync(
`vault kv put -mount ${secretsPath} ${secretName} ` +
` username=${sshUser}` +
` private_key=@${sshKeyPath}`,
);
execSync(
`vault policy write ${secretPolicyName} ./admin/tests/fixtures/kv-policy.hcl`,
);
const vaultToken = JSON.parse(
execSync(
`vault token create` +
` -no-default-policy=true` +
` -policy=${boundaryPolicyName}` +
` -policy=${secretPolicyName}` +
` -orphan=true` +
` -period=20m` +
` -renewable=true` +
` -format=json`,
),
);
const clientToken = vaultToken.auth.client_token;
const orgsPage = new OrgsPage(page);
const orgName = await orgsPage.createOrg();
const projectsPage = new ProjectsPage(page);
const projectName = await projectsPage.createProject();
const targetsPage = new TargetsPage(page);
const targetName = await targetsPage.createTargetWithAddress(
targetAddress,
targetPort,
);
const credentialStoresPage = new CredentialStoresPage(page);
await credentialStoresPage.createVaultCredentialStore(
vaultAddr,
clientToken,
);
const credentialLibraryName = 'Credential Library ' + nanoid();
await page.getByRole('link', { name: 'Credential Libraries' }).click();
await page.getByRole('link', { name: 'New', exact: true }).click();
await page
.getByLabel('Name (Optional)', { exact: true })
.fill(credentialLibraryName);
await page
.getByLabel('Description (Optional)')
.fill('This is an automated test');
await page
.getByLabel('Vault Path')
.fill(`${secretsPath}/data/${secretName}`);
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 targetsPage.addBrokeredCredentialsToTarget(
targetName,
credentialLibraryName,
);
// Verify correct credentials are returned after authorizing session
await boundaryCli.authenticateBoundary(
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
);
orgId = await boundaryCli.getOrgIdFromName(orgName);
const projectId = await boundaryCli.getProjectIdFromName(
orgId,
projectName,
);
const targetId = await boundaryCli.getTargetIdFromName(
projectId,
targetName,
);
const session = await boundaryCli.authorizeSessionByTargetId(targetId);
const retrievedUser =
session.item.credentials[0].secret.decoded.data.username;
const retrievedKey =
session.item.credentials[0].secret.decoded.data.private_key;
expect(retrievedUser).toBe(sshUser);
const keyData = await readFile(sshKeyPath, {
encoding: 'utf-8',
});
expect(retrievedKey).toBe(keyData);
const sessionsPage = new SessionsPage(page);
await sessionsPage.waitForSessionToBeVisible(targetName);
} finally {
if (orgId) {
await boundaryCli.deleteScope(orgId);
}
}
},
);
+122 -122
View File
@@ -39,126 +39,126 @@ test.beforeEach(
test.afterEach(() => {
execSync(`vault policy delete ${secretPolicyName}`);
execSync(`vault policy delete ${boundaryPolicyName}`);
})
test('Verify resources can be deleted (enterprise) @ent @aws', async ({
page,
awsRegion,
vaultAddr,
}) => {
let orgId;
let orgDeleted = false;
try {
orgId = await boundaryCli.createOrg();
let projectId = await boundaryCli.createProject(orgId);
// Create boundary resources using CLI
let workerId = await boundaryCli.createControllerLedWorker();
let authMethodId = await boundaryCli.createPasswordAuthMethod(orgId);
await boundaryCli.makeAuthMethodPrimary(orgId, authMethodId);
let passwordAccountId =
await boundaryCli.createPasswordAccount(authMethodId);
let projectScopeRoleId = await boundaryCli.createRole(projectId);
let orgScopeRoleId = await boundaryCli.createRole(orgId);
let globalScopeRoleId = await boundaryCli.createRole('global');
let groupId = await boundaryCli.createGroup(orgId);
let userId = await boundaryCli.createUser(orgId);
let staticHostCatalogId =
await boundaryCli.createStaticHostCatalog(projectId);
let dynamicAwsHostCatalogId = await boundaryCli.createDynamicAwsHostCatalog(
projectId,
awsRegion,
);
let staticHostId = await boundaryCli.createStaticHost(staticHostCatalogId);
let staticHostSetId = await boundaryCli.createHostSet(staticHostCatalogId);
let staticCredentialStoreId =
await boundaryCli.createStaticCredentialStore(projectId);
const vaultToken = await vaultCli.getVaultToken(
boundaryPolicyName,
secretPolicyName,
);
let vaultCredentialStoreId = await boundaryCli.createVaultCredentialStore(
projectId,
vaultAddr,
vaultToken,
);
let usernamePasswordCredentialId =
await boundaryCli.createUsernamePasswordCredential(
staticCredentialStoreId,
);
let tcpTargetId = await boundaryCli.createTcpTarget(projectId);
// Create enterprise boundary resources using CLI
let sshTargetId = await boundaryCli.createSshTarget(projectId);
// Delete resources
const baseResourcePage = new BaseResourcePage(page);
await page.goto(`/scopes/${projectId}/targets/${tcpTargetId}`);
await baseResourcePage.deleteResource(page);
await page.goto(
`/scopes/${projectId}/credential-stores/${staticCredentialStoreId}/credentials/${usernamePasswordCredentialId}`,
);
await baseResourcePage.deleteResource(page);
await page.goto(
`/scopes/${projectId}/credential-stores/${staticCredentialStoreId}`,
);
await baseResourcePage.deleteResource(page);
await page.goto(
`/scopes/${projectId}/credential-stores/${vaultCredentialStoreId}`,
);
await baseResourcePage.deleteResource(page);
await page.goto(
`/scopes/${projectId}/host-catalogs/${staticHostCatalogId}/host-sets/${staticHostSetId}`,
);
await baseResourcePage.deleteResource(page);
await page.goto(
`/scopes/${projectId}/host-catalogs/${staticHostCatalogId}/hosts/${staticHostId}`,
);
await baseResourcePage.deleteResource(page);
await page.goto(
`/scopes/${projectId}/host-catalogs/${staticHostCatalogId}`,
);
await baseResourcePage.deleteResource(page);
await page.goto(
`/scopes/${projectId}/host-catalogs/${dynamicAwsHostCatalogId}`,
);
await baseResourcePage.deleteResource(page);
await page.goto(`/scopes/${projectId}/users/${userId}`);
await baseResourcePage.deleteResource(page);
await page.goto(`/scopes/${projectId}/groups/${groupId}`);
await baseResourcePage.deleteResource(page);
await page.goto(`/scopes/global/roles/${globalScopeRoleId}`);
await baseResourcePage.deleteResource(page);
await page.goto(`/scopes/${projectId}/roles/${orgScopeRoleId}`);
await baseResourcePage.deleteResource(page);
await page.goto(`/scopes/${projectId}/roles/${projectScopeRoleId}`);
await baseResourcePage.deleteResource(page);
await page.goto(
`/scopes/${orgId}/auth-methods/${authMethodId}/accounts/${passwordAccountId}`,
);
await baseResourcePage.deleteResource(page);
await page.goto(`/scopes/${orgId}/auth-methods/${authMethodId}`);
const authMethodsPage = new AuthMethodsPage(page);
await authMethodsPage.removeAuthMethodAsPrimary();
await baseResourcePage.deleteResource(page);
await page.goto(`/scopes/global/workers/${workerId}`);
const workersPage = new WorkersPage(page);
await workersPage.deleteResource(page);
// Delete enterprise resources
await page.goto(`/scopes/${projectId}/targets/${sshTargetId}`);
await baseResourcePage.deleteResource(page);
// Delete project and org
await page.goto(`/scopes/${projectId}`);
await baseResourcePage.deleteResource(page);
await page.goto(`/scopes/${orgId}/edit`);
await baseResourcePage.deleteResource(page);
orgDeleted = true;
} finally {
if (orgId && orgDeleted == false) {
await boundaryCli.deleteScope(orgId);
}
}
});
test(
'Verify resources can be deleted (enterprise)',
{ tag: ['@ent', '@aws'] },
async ({ page, awsRegion, vaultAddr }) => {
let orgId;
let orgDeleted = false;
try {
orgId = await boundaryCli.createOrg();
let projectId = await boundaryCli.createProject(orgId);
// Create boundary resources using CLI
let workerId = await boundaryCli.createControllerLedWorker();
let authMethodId = await boundaryCli.createPasswordAuthMethod(orgId);
await boundaryCli.makeAuthMethodPrimary(orgId, authMethodId);
let passwordAccountId =
await boundaryCli.createPasswordAccount(authMethodId);
let projectScopeRoleId = await boundaryCli.createRole(projectId);
let orgScopeRoleId = await boundaryCli.createRole(orgId);
let globalScopeRoleId = await boundaryCli.createRole('global');
let groupId = await boundaryCli.createGroup(orgId);
let userId = await boundaryCli.createUser(orgId);
let staticHostCatalogId =
await boundaryCli.createStaticHostCatalog(projectId);
let dynamicAwsHostCatalogId =
await boundaryCli.createDynamicAwsHostCatalog(projectId, awsRegion);
let staticHostId =
await boundaryCli.createStaticHost(staticHostCatalogId);
let staticHostSetId =
await boundaryCli.createHostSet(staticHostCatalogId);
let staticCredentialStoreId =
await boundaryCli.createStaticCredentialStore(projectId);
const vaultToken = await vaultCli.getVaultToken(
boundaryPolicyName,
secretPolicyName,
);
let vaultCredentialStoreId = await boundaryCli.createVaultCredentialStore(
projectId,
vaultAddr,
vaultToken,
);
let usernamePasswordCredentialId =
await boundaryCli.createUsernamePasswordCredential(
staticCredentialStoreId,
);
let tcpTargetId = await boundaryCli.createTcpTarget(projectId);
// Create enterprise boundary resources using CLI
let sshTargetId = await boundaryCli.createSshTarget(projectId);
// Delete resources
const baseResourcePage = new BaseResourcePage(page);
await page.goto(`/scopes/${projectId}/targets/${tcpTargetId}`);
await baseResourcePage.deleteResource(page);
await page.goto(
`/scopes/${projectId}/credential-stores/${staticCredentialStoreId}/credentials/${usernamePasswordCredentialId}`,
);
await baseResourcePage.deleteResource(page);
await page.goto(
`/scopes/${projectId}/credential-stores/${staticCredentialStoreId}`,
);
await baseResourcePage.deleteResource(page);
await page.goto(
`/scopes/${projectId}/credential-stores/${vaultCredentialStoreId}`,
);
await baseResourcePage.deleteResource(page);
await page.goto(
`/scopes/${projectId}/host-catalogs/${staticHostCatalogId}/host-sets/${staticHostSetId}`,
);
await baseResourcePage.deleteResource(page);
await page.goto(
`/scopes/${projectId}/host-catalogs/${staticHostCatalogId}/hosts/${staticHostId}`,
);
await baseResourcePage.deleteResource(page);
await page.goto(
`/scopes/${projectId}/host-catalogs/${staticHostCatalogId}`,
);
await baseResourcePage.deleteResource(page);
await page.goto(
`/scopes/${projectId}/host-catalogs/${dynamicAwsHostCatalogId}`,
);
await baseResourcePage.deleteResource(page);
await page.goto(`/scopes/${projectId}/users/${userId}`);
await baseResourcePage.deleteResource(page);
await page.goto(`/scopes/${projectId}/groups/${groupId}`);
await baseResourcePage.deleteResource(page);
await page.goto(`/scopes/global/roles/${globalScopeRoleId}`);
await baseResourcePage.deleteResource(page);
await page.goto(`/scopes/${projectId}/roles/${orgScopeRoleId}`);
await baseResourcePage.deleteResource(page);
await page.goto(`/scopes/${projectId}/roles/${projectScopeRoleId}`);
await baseResourcePage.deleteResource(page);
await page.goto(
`/scopes/${orgId}/auth-methods/${authMethodId}/accounts/${passwordAccountId}`,
);
await baseResourcePage.deleteResource(page);
await page.goto(`/scopes/${orgId}/auth-methods/${authMethodId}`);
const authMethodsPage = new AuthMethodsPage(page);
await authMethodsPage.removeAuthMethodAsPrimary();
await baseResourcePage.deleteResource(page);
await page.goto(`/scopes/global/workers/${workerId}`);
const workersPage = new WorkersPage(page);
await workersPage.deleteResource(page);
// Delete enterprise resources
await page.goto(`/scopes/${projectId}/targets/${sshTargetId}`);
await baseResourcePage.deleteResource(page);
// Delete project and org
await page.goto(`/scopes/${projectId}`);
await baseResourcePage.deleteResource(page);
await page.goto(`/scopes/${orgId}/edit`);
await baseResourcePage.deleteResource(page);
orgDeleted = true;
} finally {
if (orgId && orgDeleted == false) {
await boundaryCli.deleteScope(orgId);
}
}
},
);
+125 -125
View File
@@ -41,149 +41,149 @@ test.afterEach(() => {
execSync(`vault policy delete ${boundaryPolicyName}`);
});
test('Verify resources can be deleted @ce @aws', async ({
page,
awsRegion,
vaultAddr,
}) => {
let orgId;
let orgDeleted = false;
try {
// Create boundary resources using CLI
orgId = await boundaryCli.createOrg();
let projectId = await boundaryCli.createProject(orgId);
let workerId = await boundaryCli.createControllerLedWorker();
let authMethodId = await boundaryCli.createPasswordAuthMethod(orgId);
await boundaryCli.makeAuthMethodPrimary(orgId, authMethodId);
let passwordAccountId =
await boundaryCli.createPasswordAccount(authMethodId);
let projectScopeRoleId = await boundaryCli.createRole(projectId);
let orgScopeRoleId = await boundaryCli.createRole(orgId);
let globalScopeRoleId = await boundaryCli.createRole('global');
let groupId = await boundaryCli.createGroup(orgId);
let userId = await boundaryCli.createUser(orgId);
let staticHostCatalogId =
await boundaryCli.createStaticHostCatalog(projectId);
let dynamicAwsHostCatalogId = await boundaryCli.createDynamicAwsHostCatalog(
projectId,
awsRegion,
);
let staticHostId = await boundaryCli.createStaticHost(staticHostCatalogId);
let staticHostSetId = await boundaryCli.createHostSet(staticHostCatalogId);
let staticCredentialStoreId =
await boundaryCli.createStaticCredentialStore(projectId);
const vaultToken = await vaultCli.getVaultToken(
boundaryPolicyName,
secretPolicyName,
);
let vaultCredentialStoreId = await boundaryCli.createVaultCredentialStore(
projectId,
vaultAddr,
vaultToken,
);
let usernamePasswordCredentialId =
await boundaryCli.createUsernamePasswordCredential(
staticCredentialStoreId,
test(
'Verify resources can be deleted',
{ tag: ['@ce', '@aws'] },
async ({ page, awsRegion, vaultAddr }) => {
let orgId;
let orgDeleted = false;
try {
// Create boundary resources using CLI
orgId = await boundaryCli.createOrg();
let projectId = await boundaryCli.createProject(orgId);
let workerId = await boundaryCli.createControllerLedWorker();
let authMethodId = await boundaryCli.createPasswordAuthMethod(orgId);
await boundaryCli.makeAuthMethodPrimary(orgId, authMethodId);
let passwordAccountId =
await boundaryCli.createPasswordAccount(authMethodId);
let projectScopeRoleId = await boundaryCli.createRole(projectId);
let orgScopeRoleId = await boundaryCli.createRole(orgId);
let globalScopeRoleId = await boundaryCli.createRole('global');
let groupId = await boundaryCli.createGroup(orgId);
let userId = await boundaryCli.createUser(orgId);
let staticHostCatalogId =
await boundaryCli.createStaticHostCatalog(projectId);
let dynamicAwsHostCatalogId =
await boundaryCli.createDynamicAwsHostCatalog(projectId, awsRegion);
let staticHostId =
await boundaryCli.createStaticHost(staticHostCatalogId);
let staticHostSetId =
await boundaryCli.createHostSet(staticHostCatalogId);
let staticCredentialStoreId =
await boundaryCli.createStaticCredentialStore(projectId);
const vaultToken = await vaultCli.getVaultToken(
boundaryPolicyName,
secretPolicyName,
);
let tcpTargetId = await boundaryCli.createTcpTarget(projectId);
let vaultCredentialStoreId = await boundaryCli.createVaultCredentialStore(
projectId,
vaultAddr,
vaultToken,
);
let usernamePasswordCredentialId =
await boundaryCli.createUsernamePasswordCredential(
staticCredentialStoreId,
);
let tcpTargetId = await boundaryCli.createTcpTarget(projectId);
const baseResourcePage = new BaseResourcePage(page);
const baseResourcePage = new BaseResourcePage(page);
// Delete TCP target
await page.goto(`/scopes/${projectId}/targets/${tcpTargetId}`);
await baseResourcePage.deleteResource(page);
// Delete TCP target
await page.goto(`/scopes/${projectId}/targets/${tcpTargetId}`);
await baseResourcePage.deleteResource(page);
// Delete username-password credentials
await page.goto(
`/scopes/${projectId}/credential-stores/${staticCredentialStoreId}/credentials/${usernamePasswordCredentialId}`,
);
await baseResourcePage.deleteResource(page);
// Delete username-password credentials
await page.goto(
`/scopes/${projectId}/credential-stores/${staticCredentialStoreId}/credentials/${usernamePasswordCredentialId}`,
);
await baseResourcePage.deleteResource(page);
// Delete static credential store
await page.goto(
`/scopes/${projectId}/credential-stores/${staticCredentialStoreId}`,
);
await baseResourcePage.deleteResource(page);
// Delete static credential store
await page.goto(
`/scopes/${projectId}/credential-stores/${staticCredentialStoreId}`,
);
await baseResourcePage.deleteResource(page);
// Delete vault credential store
await page.goto(
`/scopes/${projectId}/credential-stores/${vaultCredentialStoreId}`,
);
await baseResourcePage.deleteResource(page);
// Delete vault credential store
await page.goto(
`/scopes/${projectId}/credential-stores/${vaultCredentialStoreId}`,
);
await baseResourcePage.deleteResource(page);
// Delete static host set
await page.goto(
`/scopes/${projectId}/host-catalogs/${staticHostCatalogId}/host-sets/${staticHostSetId}`,
);
await baseResourcePage.deleteResource(page);
// Delete static host set
await page.goto(
`/scopes/${projectId}/host-catalogs/${staticHostCatalogId}/host-sets/${staticHostSetId}`,
);
await baseResourcePage.deleteResource(page);
// Delete static host
await page.goto(
`/scopes/${projectId}/host-catalogs/${staticHostCatalogId}/hosts/${staticHostId}`,
);
await baseResourcePage.deleteResource(page);
// Delete static host
await page.goto(
`/scopes/${projectId}/host-catalogs/${staticHostCatalogId}/hosts/${staticHostId}`,
);
await baseResourcePage.deleteResource(page);
// Delete static host catalog
await page.goto(
`/scopes/${projectId}/host-catalogs/${staticHostCatalogId}`,
);
await baseResourcePage.deleteResource(page);
// Delete static host catalog
await page.goto(
`/scopes/${projectId}/host-catalogs/${staticHostCatalogId}`,
);
await baseResourcePage.deleteResource(page);
// Delete dynamic aws host catalog
await page.goto(
`/scopes/${projectId}/host-catalogs/${dynamicAwsHostCatalogId}`,
);
await baseResourcePage.deleteResource(page);
// Delete dynamic aws host catalog
await page.goto(
`/scopes/${projectId}/host-catalogs/${dynamicAwsHostCatalogId}`,
);
await baseResourcePage.deleteResource(page);
// Delete user
await page.goto(`/scopes/${projectId}/users/${userId}`);
await baseResourcePage.deleteResource(page);
// Delete user
await page.goto(`/scopes/${projectId}/users/${userId}`);
await baseResourcePage.deleteResource(page);
// Delete group
await page.goto(`/scopes/${projectId}/groups/${groupId}`);
await baseResourcePage.deleteResource(page);
// Delete group
await page.goto(`/scopes/${projectId}/groups/${groupId}`);
await baseResourcePage.deleteResource(page);
// Delete role under global scope
await page.goto(`/scopes/global/roles/${globalScopeRoleId}`);
await baseResourcePage.deleteResource(page);
// Delete role under global scope
await page.goto(`/scopes/global/roles/${globalScopeRoleId}`);
await baseResourcePage.deleteResource(page);
// Delete role under org scope
await page.goto(`/scopes/${projectId}/roles/${orgScopeRoleId}`);
await baseResourcePage.deleteResource(page);
// Delete role under org scope
await page.goto(`/scopes/${projectId}/roles/${orgScopeRoleId}`);
await baseResourcePage.deleteResource(page);
// Delete role under project scope
await page.goto(`/scopes/${projectId}/roles/${projectScopeRoleId}`);
await baseResourcePage.deleteResource(page);
// Delete role under project scope
await page.goto(`/scopes/${projectId}/roles/${projectScopeRoleId}`);
await baseResourcePage.deleteResource(page);
// Delete password account
await page.goto(
`/scopes/${orgId}/auth-methods/${authMethodId}/accounts/${passwordAccountId}`,
);
await baseResourcePage.deleteResource(page);
// Delete password account
await page.goto(
`/scopes/${orgId}/auth-methods/${authMethodId}/accounts/${passwordAccountId}`,
);
await baseResourcePage.deleteResource(page);
// Delete auth method
await page.goto(`/scopes/${orgId}/auth-methods/${authMethodId}`);
const authMethodsPage = new AuthMethodsPage(page);
await authMethodsPage.removeAuthMethodAsPrimary();
await baseResourcePage.deleteResource(page);
// Delete auth method
await page.goto(`/scopes/${orgId}/auth-methods/${authMethodId}`);
const authMethodsPage = new AuthMethodsPage(page);
await authMethodsPage.removeAuthMethodAsPrimary();
await baseResourcePage.deleteResource(page);
// Delete worker
await page.goto(`/scopes/global/workers/${workerId}`);
const workersPage = new WorkersPage(page);
await workersPage.deleteResource(page);
// Delete worker
await page.goto(`/scopes/global/workers/${workerId}`);
const workersPage = new WorkersPage(page);
await workersPage.deleteResource(page);
// Delete project
await page.goto(`/scopes/${projectId}`);
await baseResourcePage.deleteResource(page);
// Delete project
await page.goto(`/scopes/${projectId}`);
await baseResourcePage.deleteResource(page);
// Delete org
await page.goto(`/scopes/${orgId}/edit`);
await baseResourcePage.deleteResource(page);
orgDeleted = true;
} finally {
// Delete org in case the test failed before deleting the org using UI
if (orgId && orgDeleted === false) {
await boundaryCli.deleteScope(orgId);
// Delete org
await page.goto(`/scopes/${orgId}/edit`);
await baseResourcePage.deleteResource(page);
orgDeleted = true;
} finally {
// Delete org in case the test failed before deleting the org using UI
if (orgId && orgDeleted === false) {
await boundaryCli.deleteScope(orgId);
}
}
}
});
},
);
@@ -20,217 +20,221 @@ test.beforeEach(async ({ page }) => {
});
test.describe('AWS', () => {
test('Create an AWS Dynamic Host Catalog and set up Host Sets @ent @aws', async ({
page,
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
awsAccessKeyId,
awsHostSetFilter,
awsHostSetIps,
awsRegion,
awsSecretAccessKey,
targetPort,
sshUser,
sshKeyPath,
}) => {
let orgName;
let connect;
try {
const orgsPage = new OrgsPage(page);
orgName = await orgsPage.createOrg();
const projectsPage = new ProjectsPage(page);
const projectName = await projectsPage.createProject();
test(
'Create an AWS Dynamic Host Catalog and set up Host Sets',
{ tag: ['@ent', '@aws'] },
async ({
page,
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
awsAccessKeyId,
awsHostSetFilter,
awsHostSetIps,
awsRegion,
awsSecretAccessKey,
targetPort,
sshUser,
sshKeyPath,
}) => {
let orgName;
let connect;
try {
const orgsPage = new OrgsPage(page);
orgName = await orgsPage.createOrg();
const projectsPage = new ProjectsPage(page);
const projectName = await projectsPage.createProject();
// Create host catalog
const hostCatalogName = 'Host Catalog ' + nanoid();
await page
.getByRole('navigation', { name: 'Resources' })
.getByRole('link', { name: 'Host Catalogs' })
.click();
await page.getByRole('link', { name: 'New', exact: true }).click();
await page.getByLabel('Name').fill(hostCatalogName);
await page.getByLabel('Description').fill('This is an automated test');
await page
.getByRole('group', { name: 'Type' })
.getByLabel('Dynamic')
.click();
await page
.getByRole('group', { name: 'Provider' })
.getByLabel('AWS')
.click();
await page.getByLabel('AWS Region').fill(awsRegion);
await page.getByLabel('Access Key ID').fill(awsAccessKeyId);
await page.getByLabel('Secret Access Key').fill(awsSecretAccessKey);
await page
.getByLabel('Disable credential rotation')
.click({ force: true });
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(hostCatalogName),
).toBeVisible();
// Create first host set
const hostSetName = 'Host Set ' + nanoid();
await page.getByRole('link', { name: 'Host Sets' }).click();
await page.getByRole('link', { name: 'New', exact: true }).click();
await page.getByLabel('Name (Optional)').fill(hostSetName);
await page.getByLabel('Description').fill('This is an automated test');
await page
.getByRole('group', { name: 'Filter' })
.getByRole('textbox')
.fill(awsHostSetFilter);
await page
.getByRole('group', { name: 'Filter' })
.getByRole('button', { name: 'Add' })
.click();
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(hostSetName),
).toBeVisible();
await page.getByRole('link', { name: 'Hosts' }).click();
await expect(
page
.getByRole('navigation', { name: 'breadcrumbs' })
.getByText('Hosts'),
).toBeVisible();
// Check number of hosts in host set
const expectedHosts = JSON.parse(awsHostSetIps);
await expect(async () => {
const rowCount = await page
.getByRole('table')
.getByRole('row')
.filter({ hasNot: page.getByRole('columnheader') })
.count();
if (rowCount !== expectedHosts.length) {
await page.reload();
await page
.getByRole('navigation', { name: 'breadcrumbs' })
.getByText(hostSetName)
.waitFor();
}
expect(rowCount).toBe(expectedHosts.length);
}).toPass();
// Navigate to each host in the host set
for (const row of await page
.getByRole('table')
.getByRole('rowgroup')
.nth(1)
.getByRole('row')
.all()) {
const host = row.getByRole('link');
let hostName = await host.innerText();
await host.click();
// Create host catalog
const hostCatalogName = 'Host Catalog ' + nanoid();
await page
.getByRole('navigation', { name: 'Resources' })
.getByRole('link', { name: 'Host Catalogs' })
.click();
await page.getByRole('link', { name: 'New', exact: true }).click();
await page.getByLabel('Name').fill(hostCatalogName);
await page.getByLabel('Description').fill('This is an automated test');
await page
.getByRole('group', { name: 'Type' })
.getByLabel('Dynamic')
.click();
await page
.getByRole('group', { name: 'Provider' })
.getByLabel('AWS')
.click();
await page.getByLabel('AWS Region').fill(awsRegion);
await page.getByLabel('Access Key ID').fill(awsAccessKeyId);
await page.getByLabel('Secret Access Key').fill(awsSecretAccessKey);
await page
.getByLabel('Disable credential rotation')
.click({ force: true });
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(hostName),
.getByText(hostCatalogName),
).toBeVisible();
// Create first host set
const hostSetName = 'Host Set ' + nanoid();
await page.getByRole('link', { name: 'Host Sets' }).click();
await page.getByRole('link', { name: 'New', exact: true }).click();
await page.getByLabel('Name (Optional)').fill(hostSetName);
await page.getByLabel('Description').fill('This is an automated test');
await page
.getByRole('navigation', { name: 'breadcrumbs' })
.getByText(hostSetName)
.getByRole('group', { name: 'Filter' })
.getByRole('textbox')
.fill(awsHostSetFilter);
await page
.getByRole('group', { name: 'Filter' })
.getByRole('button', { name: 'Add' })
.click();
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(hostSetName),
).toBeVisible();
await page.getByRole('link', { name: 'Hosts' }).click();
}
await expect(
page
.getByRole('navigation', { name: 'breadcrumbs' })
.getByText('Hosts'),
).toBeVisible();
// Create a target and add DHC host set as a host source
const targetsPage = new TargetsPage(page);
const targetName = await targetsPage.createSshTargetEnt(targetPort);
await targetsPage.addHostSourceToTarget(hostSetName);
// Check number of hosts in host set
const expectedHosts = JSON.parse(awsHostSetIps);
await expect(async () => {
const rowCount = await page
.getByRole('table')
.getByRole('row')
.filter({ hasNot: page.getByRole('columnheader') })
.count();
// Add another host source
const hostCatalogsPage = new HostCatalogsPage(page);
await hostCatalogsPage.createHostCatalog();
const newHostSetName = await hostCatalogsPage.createHostSet();
await page
.getByRole('navigation', { name: 'Resources' })
.getByRole('link', { name: 'Targets' })
.click();
await page.getByRole('link', { name: targetName }).click();
await targetsPage.addHostSourceToTarget(newHostSetName);
if (rowCount !== expectedHosts.length) {
await page.reload();
await page
.getByRole('navigation', { name: 'breadcrumbs' })
.getByText(hostSetName)
.waitFor();
}
expect(rowCount).toBe(expectedHosts.length);
}).toPass();
// Remove the host source from the target
await page
.getByRole('link', { name: newHostSetName })
.locator('..')
.locator('..')
.getByRole('button', { name: 'Manage' })
.click();
await page.getByRole('button', { name: 'Remove' }).click();
await page.getByRole('button', { name: 'OK', exact: true }).click();
await expect(
page.getByRole('alert').getByText('Success', { exact: true }),
).toBeVisible();
await page.getByRole('button', { name: 'Dismiss' }).click();
// Navigate to each host in the host set
for (const row of await page
.getByRole('table')
.getByRole('rowgroup')
.nth(1)
.getByRole('row')
.all()) {
const host = row.getByRole('link');
let hostName = await host.innerText();
await host.click();
await expect(
page
.getByRole('navigation', { name: 'breadcrumbs' })
.getByText(hostName),
).toBeVisible();
// Set up target credentials
const credentialStoresPage = new CredentialStoresPage(page);
await credentialStoresPage.createStaticCredentialStore();
const credentialName =
await credentialStoresPage.createStaticCredentialKeyPair(
sshUser,
sshKeyPath,
await page
.getByRole('navigation', { name: 'breadcrumbs' })
.getByText(hostSetName)
.click();
await page.getByRole('link', { name: 'Hosts' }).click();
}
// Create a target and add DHC host set as a host source
const targetsPage = new TargetsPage(page);
const targetName = await targetsPage.createSshTargetEnt(targetPort);
await targetsPage.addHostSourceToTarget(hostSetName);
// Add another host source
const hostCatalogsPage = new HostCatalogsPage(page);
await hostCatalogsPage.createHostCatalog();
const newHostSetName = await hostCatalogsPage.createHostSet();
await page
.getByRole('navigation', { name: 'Resources' })
.getByRole('link', { name: 'Targets' })
.click();
await page.getByRole('link', { name: targetName }).click();
await targetsPage.addHostSourceToTarget(newHostSetName);
// Remove the host source from the target
await page
.getByRole('link', { name: newHostSetName })
.locator('..')
.locator('..')
.getByRole('button', { name: 'Manage' })
.click();
await page.getByRole('button', { name: 'Remove' }).click();
await page.getByRole('button', { name: 'OK', exact: true }).click();
await expect(
page.getByRole('alert').getByText('Success', { exact: true }),
).toBeVisible();
await page.getByRole('button', { name: 'Dismiss' }).click();
// Set up target credentials
const credentialStoresPage = new CredentialStoresPage(page);
await credentialStoresPage.createStaticCredentialStore();
const credentialName =
await credentialStoresPage.createStaticCredentialKeyPair(
sshUser,
sshKeyPath,
);
await targetsPage.addInjectedCredentialsToTarget(
targetName,
credentialName,
);
await targetsPage.addInjectedCredentialsToTarget(
targetName,
credentialName,
);
// Connect to target
await boundaryCli.authenticateBoundary(
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
);
const orgId = await boundaryCli.getOrgIdFromName(orgName);
const projectId = await boundaryCli.getProjectIdFromName(
orgId,
projectName,
);
const targetId = await boundaryCli.getTargetIdFromName(
projectId,
targetName,
);
connect = await boundaryCli.connectSshToTarget(targetId);
const sessionsPage = new SessionsPage(page);
await sessionsPage.waitForSessionToBeVisible(targetName);
} finally {
if (connect) {
connect.kill('SIGTERM');
}
await boundaryCli.authenticateBoundary(
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
);
if (orgName) {
// Connect to target
await boundaryCli.authenticateBoundary(
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
);
const orgId = await boundaryCli.getOrgIdFromName(orgName);
if (orgId) {
await boundaryCli.deleteScope(orgId);
const projectId = await boundaryCli.getProjectIdFromName(
orgId,
projectName,
);
const targetId = await boundaryCli.getTargetIdFromName(
projectId,
targetName,
);
connect = await boundaryCli.connectSshToTarget(targetId);
const sessionsPage = new SessionsPage(page);
await sessionsPage.waitForSessionToBeVisible(targetName);
} finally {
if (connect) {
connect.kill('SIGTERM');
}
await boundaryCli.authenticateBoundary(
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
);
if (orgName) {
const orgId = await boundaryCli.getOrgIdFromName(orgName);
if (orgId) {
await boundaryCli.deleteScope(orgId);
}
}
}
}
});
},
);
});
@@ -20,217 +20,221 @@ test.beforeEach(async ({ page }) => {
});
test.describe('AWS', () => {
test('Create an AWS Dynamic Host Catalog and set up Host Sets @ce @aws', async ({
page,
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
awsAccessKeyId,
awsHostSetFilter,
awsHostSetIps,
awsRegion,
awsSecretAccessKey,
targetPort,
sshUser,
sshKeyPath,
}) => {
let orgName;
let connect;
try {
const orgsPage = new OrgsPage(page);
orgName = await orgsPage.createOrg();
const projectsPage = new ProjectsPage(page);
const projectName = await projectsPage.createProject();
test(
'Create an AWS Dynamic Host Catalog and set up Host Sets',
{ tag: ['@ce', '@aws'] },
async ({
page,
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
awsAccessKeyId,
awsHostSetFilter,
awsHostSetIps,
awsRegion,
awsSecretAccessKey,
targetPort,
sshUser,
sshKeyPath,
}) => {
let orgName;
let connect;
try {
const orgsPage = new OrgsPage(page);
orgName = await orgsPage.createOrg();
const projectsPage = new ProjectsPage(page);
const projectName = await projectsPage.createProject();
// Create host catalog
const hostCatalogName = 'Host Catalog ' + nanoid();
await page
.getByRole('navigation', { name: 'Resources' })
.getByRole('link', { name: 'Host Catalogs' })
.click();
await page.getByRole('link', { name: 'New', exact: true }).click();
await page.getByLabel('Name').fill(hostCatalogName);
await page.getByLabel('Description').fill('This is an automated test');
await page
.getByRole('group', { name: 'Type' })
.getByLabel('Dynamic')
.click();
await page
.getByRole('group', { name: 'Provider' })
.getByLabel('AWS')
.click();
await page.getByLabel('AWS Region').fill(awsRegion);
await page.getByLabel('Access Key ID').fill(awsAccessKeyId);
await page.getByLabel('Secret Access Key').fill(awsSecretAccessKey);
await page
.getByLabel('Disable credential rotation')
.click({ force: true });
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(hostCatalogName),
).toBeVisible();
// Create first host set
const hostSetName = 'Host Set ' + nanoid();
await page.getByRole('link', { name: 'Host Sets' }).click();
await page.getByRole('link', { name: 'New', exact: true }).click();
await page.getByLabel('Name (Optional)').fill(hostSetName);
await page.getByLabel('Description').fill('This is an automated test');
await page
.getByRole('group', { name: 'Filter' })
.getByRole('textbox')
.fill(awsHostSetFilter);
await page
.getByRole('group', { name: 'Filter' })
.getByRole('button', { name: 'Add' })
.click();
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(hostSetName),
).toBeVisible();
await page.getByRole('link', { name: 'Hosts' }).click();
await expect(
page
.getByRole('navigation', { name: 'breadcrumbs' })
.getByText('Hosts'),
).toBeVisible();
// Check number of hosts in host set
const expectedHosts = JSON.parse(awsHostSetIps);
await expect(async () => {
const rowCount = await page
.getByRole('table')
.getByRole('row')
.filter({ hasNot: page.getByRole('columnheader') })
.count();
if (rowCount !== expectedHosts.length) {
await page.reload();
await page
.getByRole('navigation', { name: 'breadcrumbs' })
.getByText(hostSetName)
.waitFor();
}
expect(rowCount).toBe(expectedHosts.length);
}).toPass();
// Navigate to each host in the host set
for (const row of await page
.getByRole('table')
.getByRole('rowgroup')
.nth(1)
.getByRole('row')
.all()) {
const host = row.getByRole('link');
let hostName = await host.innerText();
await host.click();
// Create host catalog
const hostCatalogName = 'Host Catalog ' + nanoid();
await page
.getByRole('navigation', { name: 'Resources' })
.getByRole('link', { name: 'Host Catalogs' })
.click();
await page.getByRole('link', { name: 'New', exact: true }).click();
await page.getByLabel('Name').fill(hostCatalogName);
await page.getByLabel('Description').fill('This is an automated test');
await page
.getByRole('group', { name: 'Type' })
.getByLabel('Dynamic')
.click();
await page
.getByRole('group', { name: 'Provider' })
.getByLabel('AWS')
.click();
await page.getByLabel('AWS Region').fill(awsRegion);
await page.getByLabel('Access Key ID').fill(awsAccessKeyId);
await page.getByLabel('Secret Access Key').fill(awsSecretAccessKey);
await page
.getByLabel('Disable credential rotation')
.click({ force: true });
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(hostName),
.getByText(hostCatalogName),
).toBeVisible();
// Create first host set
const hostSetName = 'Host Set ' + nanoid();
await page.getByRole('link', { name: 'Host Sets' }).click();
await page.getByRole('link', { name: 'New', exact: true }).click();
await page.getByLabel('Name (Optional)').fill(hostSetName);
await page.getByLabel('Description').fill('This is an automated test');
await page
.getByRole('navigation', { name: 'breadcrumbs' })
.getByText(hostSetName)
.getByRole('group', { name: 'Filter' })
.getByRole('textbox')
.fill(awsHostSetFilter);
await page
.getByRole('group', { name: 'Filter' })
.getByRole('button', { name: 'Add' })
.click();
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(hostSetName),
).toBeVisible();
await page.getByRole('link', { name: 'Hosts' }).click();
}
await expect(
page
.getByRole('navigation', { name: 'breadcrumbs' })
.getByText('Hosts'),
).toBeVisible();
// Create a target and add DHC host set as a host source
const targetsPage = new TargetsPage(page);
const targetName = await targetsPage.createTarget(targetPort);
await targetsPage.addHostSourceToTarget(hostSetName);
// Check number of hosts in host set
const expectedHosts = JSON.parse(awsHostSetIps);
await expect(async () => {
const rowCount = await page
.getByRole('table')
.getByRole('row')
.filter({ hasNot: page.getByRole('columnheader') })
.count();
// Add another host source
const hostCatalogsPage = new HostCatalogsPage(page);
await hostCatalogsPage.createHostCatalog();
const newHostSetName = await hostCatalogsPage.createHostSet();
await page
.getByRole('navigation', { name: 'Resources' })
.getByRole('link', { name: 'Targets' })
.click();
await page.getByRole('link', { name: targetName }).click();
await targetsPage.addHostSourceToTarget(newHostSetName);
if (rowCount !== expectedHosts.length) {
await page.reload();
await page
.getByRole('navigation', { name: 'breadcrumbs' })
.getByText(hostSetName)
.waitFor();
}
expect(rowCount).toBe(expectedHosts.length);
}).toPass();
// Remove the host source from the target
await page
.getByRole('link', { name: newHostSetName })
.locator('..')
.locator('..')
.getByRole('button', { name: 'Manage' })
.click();
await page.getByRole('button', { name: 'Remove' }).click();
await page.getByRole('button', { name: 'OK', exact: true }).click();
await expect(
page.getByRole('alert').getByText('Success', { exact: true }),
).toBeVisible();
await page.getByRole('button', { name: 'Dismiss' }).click();
// Navigate to each host in the host set
for (const row of await page
.getByRole('table')
.getByRole('rowgroup')
.nth(1)
.getByRole('row')
.all()) {
const host = row.getByRole('link');
let hostName = await host.innerText();
await host.click();
await expect(
page
.getByRole('navigation', { name: 'breadcrumbs' })
.getByText(hostName),
).toBeVisible();
// Set up target credentials
const credentialStoresPage = new CredentialStoresPage(page);
await credentialStoresPage.createStaticCredentialStore();
const credentialName =
await credentialStoresPage.createStaticCredentialKeyPair(
sshUser,
sshKeyPath,
await page
.getByRole('navigation', { name: 'breadcrumbs' })
.getByText(hostSetName)
.click();
await page.getByRole('link', { name: 'Hosts' }).click();
}
// Create a target and add DHC host set as a host source
const targetsPage = new TargetsPage(page);
const targetName = await targetsPage.createTarget(targetPort);
await targetsPage.addHostSourceToTarget(hostSetName);
// Add another host source
const hostCatalogsPage = new HostCatalogsPage(page);
await hostCatalogsPage.createHostCatalog();
const newHostSetName = await hostCatalogsPage.createHostSet();
await page
.getByRole('navigation', { name: 'Resources' })
.getByRole('link', { name: 'Targets' })
.click();
await page.getByRole('link', { name: targetName }).click();
await targetsPage.addHostSourceToTarget(newHostSetName);
// Remove the host source from the target
await page
.getByRole('link', { name: newHostSetName })
.locator('..')
.locator('..')
.getByRole('button', { name: 'Manage' })
.click();
await page.getByRole('button', { name: 'Remove' }).click();
await page.getByRole('button', { name: 'OK', exact: true }).click();
await expect(
page.getByRole('alert').getByText('Success', { exact: true }),
).toBeVisible();
await page.getByRole('button', { name: 'Dismiss' }).click();
// Set up target credentials
const credentialStoresPage = new CredentialStoresPage(page);
await credentialStoresPage.createStaticCredentialStore();
const credentialName =
await credentialStoresPage.createStaticCredentialKeyPair(
sshUser,
sshKeyPath,
);
await targetsPage.addBrokeredCredentialsToTarget(
targetName,
credentialName,
);
await targetsPage.addBrokeredCredentialsToTarget(
targetName,
credentialName,
);
// Connect to target
await boundaryCli.authenticateBoundary(
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
);
const orgId = await boundaryCli.getOrgIdFromName(orgName);
const projectId = await boundaryCli.getProjectIdFromName(
orgId,
projectName,
);
const targetId = await boundaryCli.getTargetIdFromName(
projectId,
targetName,
);
connect = await boundaryCli.connectSshToTarget(targetId);
const sessionsPage = new SessionsPage(page);
await sessionsPage.waitForSessionToBeVisible(targetName);
} finally {
if (connect) {
connect.kill('SIGTERM');
}
await boundaryCli.authenticateBoundary(
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
);
if (orgName) {
// Connect to target
await boundaryCli.authenticateBoundary(
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
);
const orgId = await boundaryCli.getOrgIdFromName(orgName);
if (orgId) {
await boundaryCli.deleteScope(orgId);
const projectId = await boundaryCli.getProjectIdFromName(
orgId,
projectName,
);
const targetId = await boundaryCli.getTargetIdFromName(
projectId,
targetName,
);
connect = await boundaryCli.connectSshToTarget(targetId);
const sessionsPage = new SessionsPage(page);
await sessionsPage.waitForSessionToBeVisible(targetName);
} finally {
if (connect) {
connect.kill('SIGTERM');
}
await boundaryCli.authenticateBoundary(
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
);
if (orgName) {
const orgId = await boundaryCli.getOrgIdFromName(orgName);
if (orgId) {
await boundaryCli.deleteScope(orgId);
}
}
}
}
});
},
);
});
+50 -46
View File
@@ -10,52 +10,56 @@ import * as boundaryCli from '../../helpers/boundary-cli';
import { OrgsPage } from '../pages/orgs.js';
import { StoragePoliciesPage } from '../pages/storage-policies.js';
test('Global Settings @ent @aws @docker', async ({
page,
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
}) => {
await page.goto('/');
let policyName;
try {
// Create a storage policy
const storagePoliciesPage = new StoragePoliciesPage(page);
policyName = await storagePoliciesPage.createStoragePolicy();
const orgsPage = new OrgsPage(page);
await orgsPage.attachStoragePolicy(policyName);
test(
'Global Settings',
{ tag: ['@ent', '@aws', '@docker'] },
async ({
page,
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
}) => {
await page.goto('/');
let policyName;
try {
// Create a storage policy
const storagePoliciesPage = new StoragePoliciesPage(page);
policyName = await storagePoliciesPage.createStoragePolicy();
const orgsPage = new OrgsPage(page);
await orgsPage.attachStoragePolicy(policyName);
// Detach storage policy
await page.getByRole('button', { name: 'Manage', exact: true }).click();
await page
.getByRole('button', { name: 'Detach Storage Policy', exact: true })
.click();
await page.getByRole('button', { name: 'OK', exact: true }).click();
await expect(
page.getByRole('alert').getByText('Success', { exact: true }),
).toBeVisible();
await page.getByRole('button', { name: 'Dismiss' }).click();
// Detach storage policy
await page.getByRole('button', { name: 'Manage', exact: true }).click();
await page
.getByRole('button', { name: 'Detach Storage Policy', exact: true })
.click();
await page.getByRole('button', { name: 'OK', exact: true }).click();
await expect(
page.getByRole('alert').getByText('Success', { exact: true }),
).toBeVisible();
await page.getByRole('button', { name: 'Dismiss' }).click();
// Navigate to orgs page when done
await page
.getByRole('navigation', { name: 'General' })
.getByRole('link', { name: 'Orgs' })
.click();
await expect(page.getByRole('heading', { name: 'Orgs' })).toBeVisible();
} finally {
if (policyName) {
await boundaryCli.authenticateBoundary(
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
);
const storagePolicyId = await boundaryCli.getPolicyIdFromName(
'global',
policyName,
);
await boundaryCli.deletePolicy(storagePolicyId);
// Navigate to orgs page when done
await page
.getByRole('navigation', { name: 'General' })
.getByRole('link', { name: 'Orgs' })
.click();
await expect(page.getByRole('heading', { name: 'Orgs' })).toBeVisible();
} finally {
if (policyName) {
await boundaryCli.authenticateBoundary(
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
);
const storagePolicyId = await boundaryCli.getPolicyIdFromName(
'global',
policyName,
);
await boundaryCli.deletePolicy(storagePolicyId);
}
}
}
});
},
);
+35 -31
View File
@@ -14,35 +14,39 @@ test.beforeAll(async () => {
await boundaryCli.checkBoundaryCli();
});
test('Verify a new role can be created and associated with a group @ce @ent @aws @docker', async ({
page,
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
}) => {
await page.goto('/');
let orgName;
try {
const orgsPage = new OrgsPage(page);
orgName = await orgsPage.createOrg();
const groupsPage = new GroupsPage(page);
const groupName = await groupsPage.createGroup();
await groupsPage.addMemberToGroup('admin');
const rolesPage = new RolesPage(page);
await rolesPage.createRole();
await rolesPage.addPrincipalToRole(groupName);
await rolesPage.addGrantsToRole('ids=*;type=*;actions=read,list');
} finally {
await boundaryCli.authenticateBoundary(
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
);
const orgId = await boundaryCli.getOrgIdFromName(orgName);
if (orgId) {
await boundaryCli.deleteScope(orgId);
test(
'Verify a new role can be created and associated with a group',
{ tag: ['@ce', '@ent', '@aws', '@docker'] },
async ({
page,
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
}) => {
await page.goto('/');
let orgName;
try {
const orgsPage = new OrgsPage(page);
orgName = await orgsPage.createOrg();
const groupsPage = new GroupsPage(page);
const groupName = await groupsPage.createGroup();
await groupsPage.addMemberToGroup('admin');
const rolesPage = new RolesPage(page);
await rolesPage.createRole();
await rolesPage.addPrincipalToRole(groupName);
await rolesPage.addGrantsToRole('ids=*;type=*;actions=read,list');
} finally {
await boundaryCli.authenticateBoundary(
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
);
const orgId = await boundaryCli.getOrgIdFromName(orgName);
if (orgId) {
await boundaryCli.deleteScope(orgId);
}
}
}
});
},
);
+55 -53
View File
@@ -11,68 +11,70 @@ import { LoginPage } from '../pages/login.js';
// Reset storage state for this file to avoid being authenticated
test.use({ storageState: { cookies: [], origins: [] } });
test('Log in, log out, and then log back in @ce @ent @aws @docker', async ({
page,
adminLoginName,
adminPassword,
}) => {
await page.goto('/');
test(
'Log in, log out, and then log back in',
{ tag: ['@ce', '@ent', '@aws', '@docker'] },
async ({ page, adminLoginName, adminPassword }) => {
await page.goto('/');
// Log in
const loginPage = new LoginPage(page);
await loginPage.login(adminLoginName, adminPassword);
await expect(
page.getByRole('navigation', { name: 'breadcrumbs' }).getByText('Orgs'),
).toBeVisible();
// Log in
const loginPage = new LoginPage(page);
await loginPage.login(adminLoginName, adminPassword);
await expect(
page.getByRole('navigation', { name: 'breadcrumbs' }).getByText('Orgs'),
).toBeVisible();
// Log out
await loginPage.logout(adminLoginName);
await page.reload();
// Log out
await loginPage.logout(adminLoginName);
await page.reload();
// Log back in
await loginPage.login(adminLoginName, adminPassword);
await expect(
page.getByRole('navigation', { name: 'breadcrumbs' }).getByText('Orgs'),
).toBeVisible();
});
// Log back in
await loginPage.login(adminLoginName, adminPassword);
await expect(
page.getByRole('navigation', { name: 'breadcrumbs' }).getByText('Orgs'),
).toBeVisible();
},
);
test.describe('Failure Cases', () => {
test.beforeEach(async ({ page }) => {
await page.goto('/');
});
test('Log in with invalid password @ce @ent @aws @docker', async ({
page,
adminLoginName,
}) => {
await page.getByLabel('Login Name').fill(adminLoginName);
await page.getByLabel('Password', { exact: true }).fill('badpassword');
await page.getByRole('button', { name: 'Sign In' }).click();
await expect(page.getByRole('alert').getByText('Error')).toBeVisible();
await expect(page.getByRole('button', { name: 'Sign In' })).toBeVisible();
await expect(page.getByText(adminLoginName)).toBeHidden();
});
test(
'Log in with invalid password',
{ tag: ['@ce', '@ent', '@aws', '@docker'] },
async ({ page, adminLoginName }) => {
await page.getByLabel('Login Name').fill(adminLoginName);
await page.getByLabel('Password', { exact: true }).fill('badpassword');
await page.getByRole('button', { name: 'Sign In' }).click();
await expect(page.getByRole('alert').getByText('Error')).toBeVisible();
await expect(page.getByRole('button', { name: 'Sign In' })).toBeVisible();
await expect(page.getByText(adminLoginName)).toBeHidden();
},
);
test('Log in with only username @ce @ent @aws @docker', async ({
page,
adminLoginName,
}) => {
await page.getByLabel('Login Name').fill('testuser');
await page.getByRole('button', { name: 'Sign In' }).click();
await expect(page.getByRole('alert').getByText('Error')).toBeVisible();
await expect(page.getByRole('button', { name: 'Sign In' })).toBeVisible();
await expect(page.getByText(adminLoginName)).toBeHidden();
});
test(
'Log in with only username',
{ tag: ['@ce', '@ent', '@aws', '@docker'] },
async ({ page, adminLoginName }) => {
await page.getByLabel('Login Name').fill('testuser');
await page.getByRole('button', { name: 'Sign In' }).click();
await expect(page.getByRole('alert').getByText('Error')).toBeVisible();
await expect(page.getByRole('button', { name: 'Sign In' })).toBeVisible();
await expect(page.getByText(adminLoginName)).toBeHidden();
},
);
test('Log in with only password @ce @ent @aws @docker', async ({
page,
adminLoginName,
adminPassword,
}) => {
await page.getByLabel('Password', { exact: true }).fill(adminPassword);
await page.getByRole('button', { name: 'Sign In' }).click();
await expect(page.getByRole('alert').getByText('Error')).toBeVisible();
await expect(page.getByRole('button', { name: 'Sign In' })).toBeVisible();
await expect(page.getByText(adminLoginName)).toBeHidden();
});
test(
'Log in with only password',
{ tag: ['@ce', '@ent', '@aws', '@docker'] },
async ({ page, adminLoginName, adminPassword }) => {
await page.getByLabel('Password', { exact: true }).fill(adminPassword);
await page.getByRole('button', { name: 'Sign In' }).click();
await expect(page.getByRole('alert').getByText('Error')).toBeVisible();
await expect(page.getByRole('button', { name: 'Sign In' })).toBeVisible();
await expect(page.getByText(adminLoginName)).toBeHidden();
},
);
});
+151 -148
View File
@@ -8,153 +8,156 @@ import { expect } from '@playwright/test';
import * as boundaryHttp from '../../helpers/boundary-http.js';
test('Search and Pagination (Targets) @ce @ent @aws @docker', async ({
page,
request,
}) => {
let org;
try {
org = await boundaryHttp.createOrg(request);
const project = await boundaryHttp.createProject(request, org.id);
test(
'Search and Pagination (Targets)',
{ tag: ['@ce', '@ent', '@aws', '@docker'] },
async ({ page, request }) => {
let org;
try {
org = await boundaryHttp.createOrg(request);
const project = await boundaryHttp.createProject(request, org.id);
// Create targets
let targets = [];
const targetCount = 15;
for (let i = 0; i < targetCount; i++) {
const target = await boundaryHttp.createTarget(request, {
scopeId: project.id,
type: 'tcp',
port: 22,
});
targets.push(target);
// Create targets
let targets = [];
const targetCount = 15;
for (let i = 0; i < targetCount; i++) {
const target = await boundaryHttp.createTarget(request, {
scopeId: project.id,
type: 'tcp',
port: 22,
});
targets.push(target);
}
// Navigate to targets page
await page.goto('/');
await page.getByRole('link', { name: org.name }).click();
await page.getByRole('link', { name: project.name }).click();
await page
.getByRole('navigation', { name: 'Resources' })
.getByRole('link', { name: 'Targets' })
.click();
await expect(
page.getByRole('heading', { name: 'Targets' }),
).toBeVisible();
// Check pagination
// The most recent target should be visible. The oldest target should not be
// visible since there are 15 targets and the default page size is 10.
await expect(
page.getByRole('link', { name: targets[targets.length - 1].name }),
).toBeVisible();
await expect(
page.getByRole('link', { name: targets[0].name }),
).toBeHidden();
// Navigate to the second page. The oldest target should now be visible.
await page
.getByRole('navigation', { name: 'pagination' })
.getByRole('link', { name: 'page 2' })
.click();
await expect(
page.getByRole('link', { name: targets[0].name }),
).toBeVisible();
await expect(
page.getByRole('link', { name: targets[targets.length - 1].name }),
).toBeHidden();
// Use the "previous page" button to navigate back to the first page.
await page
.getByRole('navigation', { name: 'pagination' })
.getByRole('link', { name: 'Previous page' })
.click();
await expect(
page.getByRole('link', { name: targets[0].name }),
).toBeHidden();
await expect(
page.getByRole('link', { name: targets[targets.length - 1].name }),
).toBeVisible();
// Use the "next page" button to navigate back to the second page.
await page
.getByRole('navigation', { name: 'pagination' })
.getByRole('link', { name: 'Next page' })
.click();
await expect(
page.getByRole('link', { name: targets[0].name }),
).toBeVisible();
await expect(
page.getByRole('link', { name: targets[targets.length - 1].name }),
).toBeHidden();
// Use the search box to find the most recent target.
await page
.getByRole('searchbox', { name: 'Search' })
.fill(targets[targets.length - 1].name);
await expect(
page.getByRole('link', { name: targets[0].name }),
).toBeHidden();
await expect(
page.getByRole('link', { name: targets[targets.length - 1].name }),
).toBeVisible();
await expect(
page.getByRole('link', { name: targets[targets.length - 2].name }),
).toBeHidden();
// Clear the search box
await page.getByRole('searchbox', { name: 'Search' }).clear();
await expect(
page.getByRole('link', { name: targets[0].name }),
).toBeHidden();
await expect(
page.getByRole('link', { name: targets[targets.length - 2].name }),
).toBeVisible();
await expect(
page.getByRole('link', { name: targets[targets.length - 1].name }),
).toBeVisible();
// Use the "Items per page" options to show 30 items per page.
await page
.getByRole('combobox', { name: 'Items per page' })
.selectOption('30');
await expect(
page.getByRole('link', { name: targets[0].name }),
).toBeVisible();
await expect(
page.getByRole('link', { name: targets[targets.length - 1].name }),
).toBeVisible();
await expect(
page.getByRole('link', { name: targets[targets.length - 2].name }),
).toBeVisible();
// Use the "Items per page" options to show 50 items per page.
await page
.getByRole('combobox', { name: 'Items per page' })
.selectOption('50');
await expect(
page.getByRole('link', { name: targets[0].name }),
).toBeVisible();
await expect(
page.getByRole('link', { name: targets[targets.length - 1].name }),
).toBeVisible();
await expect(
page.getByRole('link', { name: targets[targets.length - 2].name }),
).toBeVisible();
// Use the "Items per page" options to show 10 items per page.
await page
.getByRole('combobox', { name: 'Items per page' })
.selectOption('10');
await expect(
page.getByRole('link', { name: targets[0].name }),
).toBeHidden();
await expect(
page.getByRole('link', { name: targets[targets.length - 2].name }),
).toBeVisible();
await expect(
page.getByRole('link', { name: targets[targets.length - 1].name }),
).toBeVisible();
} finally {
if (org.id) {
org = await request.delete(`/v1/scopes/${org.id}`);
}
}
// Navigate to targets page
await page.goto('/');
await page.getByRole('link', { name: org.name }).click();
await page.getByRole('link', { name: project.name }).click();
await page
.getByRole('navigation', { name: 'Resources' })
.getByRole('link', { name: 'Targets' })
.click();
await expect(page.getByRole('heading', { name: 'Targets' })).toBeVisible();
// Check pagination
// The most recent target should be visible. The oldest target should not be
// visible since there are 15 targets and the default page size is 10.
await expect(
page.getByRole('link', { name: targets[targets.length - 1].name }),
).toBeVisible();
await expect(
page.getByRole('link', { name: targets[0].name }),
).toBeHidden();
// Navigate to the second page. The oldest target should now be visible.
await page
.getByRole('navigation', { name: 'pagination' })
.getByRole('link', { name: 'page 2' })
.click();
await expect(
page.getByRole('link', { name: targets[0].name }),
).toBeVisible();
await expect(
page.getByRole('link', { name: targets[targets.length - 1].name }),
).toBeHidden();
// Use the "previous page" button to navigate back to the first page.
await page
.getByRole('navigation', { name: 'pagination' })
.getByRole('link', { name: 'Previous page' })
.click();
await expect(
page.getByRole('link', { name: targets[0].name }),
).toBeHidden();
await expect(
page.getByRole('link', { name: targets[targets.length - 1].name }),
).toBeVisible();
// Use the "next page" button to navigate back to the second page.
await page
.getByRole('navigation', { name: 'pagination' })
.getByRole('link', { name: 'Next page' })
.click();
await expect(
page.getByRole('link', { name: targets[0].name }),
).toBeVisible();
await expect(
page.getByRole('link', { name: targets[targets.length - 1].name }),
).toBeHidden();
// Use the search box to find the most recent target.
await page
.getByRole('searchbox', { name: 'Search' })
.fill(targets[targets.length - 1].name);
await expect(
page.getByRole('link', { name: targets[0].name }),
).toBeHidden();
await expect(
page.getByRole('link', { name: targets[targets.length - 1].name }),
).toBeVisible();
await expect(
page.getByRole('link', { name: targets[targets.length - 2].name }),
).toBeHidden();
// Clear the search box
await page.getByRole('searchbox', { name: 'Search' }).clear();
await expect(
page.getByRole('link', { name: targets[0].name }),
).toBeHidden();
await expect(
page.getByRole('link', { name: targets[targets.length - 2].name }),
).toBeVisible();
await expect(
page.getByRole('link', { name: targets[targets.length - 1].name }),
).toBeVisible();
// Use the "Items per page" options to show 30 items per page.
await page
.getByRole('combobox', { name: 'Items per page' })
.selectOption('30');
await expect(
page.getByRole('link', { name: targets[0].name }),
).toBeVisible();
await expect(
page.getByRole('link', { name: targets[targets.length - 1].name }),
).toBeVisible();
await expect(
page.getByRole('link', { name: targets[targets.length - 2].name }),
).toBeVisible();
// Use the "Items per page" options to show 50 items per page.
await page
.getByRole('combobox', { name: 'Items per page' })
.selectOption('50');
await expect(
page.getByRole('link', { name: targets[0].name }),
).toBeVisible();
await expect(
page.getByRole('link', { name: targets[targets.length - 1].name }),
).toBeVisible();
await expect(
page.getByRole('link', { name: targets[targets.length - 2].name }),
).toBeVisible();
// Use the "Items per page" options to show 10 items per page.
await page
.getByRole('combobox', { name: 'Items per page' })
.selectOption('10');
await expect(
page.getByRole('link', { name: targets[0].name }),
).toBeHidden();
await expect(
page.getByRole('link', { name: targets[targets.length - 2].name }),
).toBeVisible();
await expect(
page.getByRole('link', { name: targets[targets.length - 1].name }),
).toBeVisible();
} finally {
if (org.id) {
org = await request.delete(`/v1/scopes/${org.id}`);
}
}
});
},
);
@@ -21,227 +21,237 @@ test.beforeAll(async () => {
await boundaryCli.checkBoundaryCli();
});
test('Session Recording Test (AWS) @ent @aws', async ({
page,
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
awsAccessKeyId,
awsBucketName,
awsRegion,
awsSecretAccessKey,
sshUser,
sshKeyPath,
targetAddress,
targetPort,
workerTagEgress,
}) => {
await page.goto('/');
let orgId;
let policyName;
let storageBucket;
let connect;
try {
await boundaryCli.authenticateBoundary(
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
);
// Create org
const orgsPage = new OrgsPage(page);
const orgName = await orgsPage.createOrg();
// Create project
const projectsPage = new ProjectsPage(page);
const projectName = await projectsPage.createProject();
// Create storage bucket
await page.getByRole('link', { name: 'Orgs', exact: true }).click();
const storageBucketsPage = new StorageBucketsPage(page);
const storageBucketName = await storageBucketsPage.createStorageBucketAws(
orgName,
awsBucketName,
awsRegion,
awsAccessKeyId,
awsSecretAccessKey,
`"${workerTagEgress}" in "/tags/type"`,
);
const storageBuckets = JSON.parse(
execSync('boundary storage-buckets list --recursive -format json'),
);
storageBucket = storageBuckets.items.filter(
(obj) => obj.name == storageBucketName,
)[0];
// Create target
await page.getByRole('link', { name: 'Orgs', exact: true }).click();
await expect(page.getByRole('heading', { name: 'Orgs' })).toBeVisible();
await page.getByRole('link', { name: orgName }).click();
await page.getByRole('link', { name: projectName }).click();
const targetsPage = new TargetsPage(page);
const targetName = await targetsPage.createSshTargetWithAddressEnt(
targetAddress,
targetPort,
);
await targetsPage.addEgressWorkerFilterToTarget(
`"${workerTagEgress}" in "/tags/type"`,
);
const credentialStoresPage = new CredentialStoresPage(page);
await credentialStoresPage.createStaticCredentialStore();
const credentialName =
await credentialStoresPage.createStaticCredentialKeyPair(
sshUser,
sshKeyPath,
test(
'Session Recording Test (AWS)',
{ tag: ['@ent', '@aws'] },
async ({
page,
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
awsAccessKeyId,
awsBucketName,
awsRegion,
awsSecretAccessKey,
sshUser,
sshKeyPath,
targetAddress,
targetPort,
workerTagEgress,
}) => {
await page.goto('/');
let orgId;
let policyName;
let storageBucket;
let connect;
try {
await boundaryCli.authenticateBoundary(
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
);
await targetsPage.addInjectedCredentialsToTarget(
targetName,
credentialName,
);
await page.getByRole('link', { name: targetName }).click();
await targetsPage.enableSessionRecording(storageBucketName);
// Create storage policy in org scope: keep session recordings forever
await page.getByRole('link', { name: 'Orgs', exact: true }).click();
await expect(page.getByRole('heading', { name: 'Orgs' })).toBeVisible();
await page.getByRole('link', { name: orgName }).click();
await expect(
page.getByRole('navigation', { name: 'breadcrumbs' }).getByText(orgName),
).toBeVisible();
const storagePoliciesPage = new StoragePoliciesPage(page);
policyName = await storagePoliciesPage.createStoragePolicy();
await orgsPage.attachStoragePolicy(policyName);
// Create org
const orgsPage = new OrgsPage(page);
const orgName = await orgsPage.createOrg();
// Establish connection to target and cancel it
orgId = await boundaryCli.getOrgIdFromName(orgName);
const projectId = await boundaryCli.getProjectIdFromName(
orgId,
projectName,
);
const targetId = await boundaryCli.getTargetIdFromName(
projectId,
targetName,
);
connect = await boundaryCli.connectSshToTarget(targetId);
await page.getByRole('link', { name: 'Projects', exact: true }).click();
await page.getByRole('link', { name: projectName }).click();
const sessionsPage = new SessionsPage(page);
await sessionsPage.waitForSessionToBeVisible(targetName);
await page
.getByRole('cell', { name: targetName })
.locator('..')
.getByRole('button', { name: 'Cancel' })
.click();
await expect(
page.getByRole('alert').getByText('Success', { exact: true }),
).toBeVisible();
await page.getByRole('button', { name: 'Dismiss', exact: true }).click();
await boundaryCli.waitForSessionRecording(storageBucket.id);
// Create project
const projectsPage = new ProjectsPage(page);
const projectName = await projectsPage.createProject();
// Play back session recording
await page.getByRole('link', { name: 'Orgs', exact: true }).click();
await page
.getByRole('navigation', { name: 'General' })
.getByRole('link', { name: 'Session Recordings', exact: true })
.click();
await page
.getByRole('row', { name: targetName })
.getByRole('link', { name: 'View' })
.click();
await page
.getByRole('cell', { name: 'Channel 1' })
.locator('..')
.getByRole('link', { name: 'Play' })
.click();
await page.locator('div.session-recording-player').hover();
await page.locator('.ap-playback-button').click();
// Create storage bucket
await page.getByRole('link', { name: 'Orgs', exact: true }).click();
const storageBucketsPage = new StorageBucketsPage(page);
const storageBucketName = await storageBucketsPage.createStorageBucketAws(
orgName,
awsBucketName,
awsRegion,
awsAccessKeyId,
awsSecretAccessKey,
`"${workerTagEgress}" in "/tags/type"`,
);
const storageBuckets = JSON.parse(
execSync('boundary storage-buckets list --recursive -format json'),
);
storageBucket = storageBuckets.items.filter(
(obj) => obj.name == storageBucketName,
)[0];
// Try to delete session recording: expect failure
await page.getByRole('link', { name: 'Orgs', exact: true }).click();
await page
.getByRole('navigation', { name: 'General' })
.getByRole('link', { name: 'Session Recordings', exact: true })
.click();
await page
.getByRole('row', { name: targetName })
.getByRole('link', { name: 'View' })
.click();
await page.getByText('Manage').click();
await page.getByRole('button', { name: 'Delete recording' }).click();
await page.getByRole('button', { name: 'OK', exact: true }).click();
await expect(
page.getByRole('alert').getByText('Error', { exact: true }),
).toBeVisible();
await page.getByRole('button', { name: 'Dismiss' }).click();
// Create target
await page.getByRole('link', { name: 'Orgs', exact: true }).click();
await expect(page.getByRole('heading', { name: 'Orgs' })).toBeVisible();
await page.getByRole('link', { name: orgName }).click();
await page.getByRole('link', { name: projectName }).click();
const targetsPage = new TargetsPage(page);
const targetName = await targetsPage.createSshTargetWithAddressEnt(
targetAddress,
targetPort,
);
await targetsPage.addEgressWorkerFilterToTarget(
`"${workerTagEgress}" in "/tags/type"`,
);
const credentialStoresPage = new CredentialStoresPage(page);
await credentialStoresPage.createStaticCredentialStore();
const credentialName =
await credentialStoresPage.createStaticCredentialKeyPair(
sshUser,
sshKeyPath,
);
await targetsPage.addInjectedCredentialsToTarget(
targetName,
credentialName,
);
await page.getByRole('link', { name: targetName }).click();
await targetsPage.enableSessionRecording(storageBucketName);
// Edit storage policy: do not protect from deletion
await page.getByRole('link', { name: 'Orgs', exact: true }).click();
await expect(page.getByRole('heading', { name: 'Orgs' })).toBeVisible();
await page.getByRole('link', { name: orgName }).click();
await expect(
page.getByRole('navigation', { name: 'breadcrumbs' }).getByText(orgName),
).toBeVisible();
await page
.getByRole('link', { name: 'Storage Policies', exact: true })
.click();
await page.getByRole('link', { name: policyName }).click();
await page.getByRole('button', { name: 'Edit form' }).click();
await page
.getByLabel('Retention Policy')
.selectOption({ label: 'Do not protect, allow deletion any time' });
await page.getByLabel('Deletion Policy').selectOption({ label: 'Custom' });
await page.getByRole('button', { name: 'Save' }).click();
await expect(
page.getByRole('alert').getByText('Success', { exact: true }),
).toBeVisible();
await page.getByRole('button', { name: 'Dismiss' }).click();
// Create storage policy in org scope: keep session recordings forever
await page.getByRole('link', { name: 'Orgs', exact: true }).click();
await expect(page.getByRole('heading', { name: 'Orgs' })).toBeVisible();
await page.getByRole('link', { name: orgName }).click();
await expect(
page
.getByRole('navigation', { name: 'breadcrumbs' })
.getByText(orgName),
).toBeVisible();
const storagePoliciesPage = new StoragePoliciesPage(page);
policyName = await storagePoliciesPage.createStoragePolicy();
await orgsPage.attachStoragePolicy(policyName);
// BUG? After the error trying to delete the session recording, subsequent
// actions result in an error. Reloading the page fixes the issue. This is a
// temporary workaround.
await page.reload();
// Re-apply storage policy to the session recording and delete
await page.getByRole('link', { name: 'Orgs', exact: true }).click();
await page
.getByRole('link', { name: 'Session Recordings', exact: true })
.click();
await page
.getByRole('row', { name: targetName })
.getByRole('link', { name: 'View' })
.click();
const sessionRecordingsPage = new SessionRecordingsPage(page);
await sessionRecordingsPage.reapplyStoragePolicy();
await sessionRecordingsPage.deleteResource();
// Detach storage bucket from target
await page.getByRole('link', { name: 'Orgs', exact: true }).click();
await expect(page.getByRole('heading', { name: 'Orgs' })).toBeVisible();
await page.getByRole('link', { name: orgName }).click();
await page.getByRole('link', { name: projectName }).click();
await page.getByRole('link', { name: 'Targets', exact: true }).click();
await page.getByRole('link', { name: targetName }).click();
await targetsPage.detachStorageBucket();
} finally {
// End `boundary connect` process
if (connect) {
connect.kill('SIGTERM');
}
if (policyName) {
const storagePolicyId = await boundaryCli.getPolicyIdFromName(
// Establish connection to target and cancel it
orgId = await boundaryCli.getOrgIdFromName(orgName);
const projectId = await boundaryCli.getProjectIdFromName(
orgId,
policyName,
projectName,
);
await boundaryCli.deletePolicy(storagePolicyId);
const targetId = await boundaryCli.getTargetIdFromName(
projectId,
targetName,
);
connect = await boundaryCli.connectSshToTarget(targetId);
await page.getByRole('link', { name: 'Projects', exact: true }).click();
await page.getByRole('link', { name: projectName }).click();
const sessionsPage = new SessionsPage(page);
await sessionsPage.waitForSessionToBeVisible(targetName);
await page
.getByRole('cell', { name: targetName })
.locator('..')
.getByRole('button', { name: 'Cancel' })
.click();
await expect(
page.getByRole('alert').getByText('Success', { exact: true }),
).toBeVisible();
await page.getByRole('button', { name: 'Dismiss', exact: true }).click();
await boundaryCli.waitForSessionRecording(storageBucket.id);
// Play back session recording
await page.getByRole('link', { name: 'Orgs', exact: true }).click();
await page
.getByRole('navigation', { name: 'General' })
.getByRole('link', { name: 'Session Recordings', exact: true })
.click();
await page
.getByRole('row', { name: targetName })
.getByRole('link', { name: 'View' })
.click();
await page
.getByRole('cell', { name: 'Channel 1' })
.locator('..')
.getByRole('link', { name: 'Play' })
.click();
await page.locator('div.session-recording-player').hover();
await page.locator('.ap-playback-button').click();
// Try to delete session recording: expect failure
await page.getByRole('link', { name: 'Orgs', exact: true }).click();
await page
.getByRole('navigation', { name: 'General' })
.getByRole('link', { name: 'Session Recordings', exact: true })
.click();
await page
.getByRole('row', { name: targetName })
.getByRole('link', { name: 'View' })
.click();
await page.getByText('Manage').click();
await page.getByRole('button', { name: 'Delete recording' }).click();
await page.getByRole('button', { name: 'OK', exact: true }).click();
await expect(
page.getByRole('alert').getByText('Error', { exact: true }),
).toBeVisible();
await page.getByRole('button', { name: 'Dismiss' }).click();
// Edit storage policy: do not protect from deletion
await page.getByRole('link', { name: 'Orgs', exact: true }).click();
await expect(page.getByRole('heading', { name: 'Orgs' })).toBeVisible();
await page.getByRole('link', { name: orgName }).click();
await expect(
page
.getByRole('navigation', { name: 'breadcrumbs' })
.getByText(orgName),
).toBeVisible();
await page
.getByRole('link', { name: 'Storage Policies', exact: true })
.click();
await page.getByRole('link', { name: policyName }).click();
await page.getByRole('button', { name: 'Edit form' }).click();
await page
.getByLabel('Retention Policy')
.selectOption({ label: 'Do not protect, allow deletion any time' });
await page
.getByLabel('Deletion Policy')
.selectOption({ label: 'Custom' });
await page.getByRole('button', { name: 'Save' }).click();
await expect(
page.getByRole('alert').getByText('Success', { exact: true }),
).toBeVisible();
await page.getByRole('button', { name: 'Dismiss' }).click();
// BUG? After the error trying to delete the session recording, subsequent
// actions result in an error. Reloading the page fixes the issue. This is a
// temporary workaround.
await page.reload();
// Re-apply storage policy to the session recording and delete
await page.getByRole('link', { name: 'Orgs', exact: true }).click();
await page
.getByRole('link', { name: 'Session Recordings', exact: true })
.click();
await page
.getByRole('row', { name: targetName })
.getByRole('link', { name: 'View' })
.click();
const sessionRecordingsPage = new SessionRecordingsPage(page);
await sessionRecordingsPage.reapplyStoragePolicy();
await sessionRecordingsPage.deleteResource();
// Detach storage bucket from target
await page.getByRole('link', { name: 'Orgs', exact: true }).click();
await expect(page.getByRole('heading', { name: 'Orgs' })).toBeVisible();
await page.getByRole('link', { name: orgName }).click();
await page.getByRole('link', { name: projectName }).click();
await page.getByRole('link', { name: 'Targets', exact: true }).click();
await page.getByRole('link', { name: targetName }).click();
await targetsPage.detachStorageBucket();
} finally {
// End `boundary connect` process
if (connect) {
connect.kill('SIGTERM');
}
if (policyName) {
const storagePolicyId = await boundaryCli.getPolicyIdFromName(
orgId,
policyName,
);
await boundaryCli.deletePolicy(storagePolicyId);
}
if (storageBucket) {
await boundaryCli.deleteStorageBucket(storageBucket.id);
}
if (orgId) {
await boundaryCli.deleteScope(orgId);
}
}
if (storageBucket) {
await boundaryCli.deleteStorageBucket(storageBucket.id);
}
if (orgId) {
await boundaryCli.deleteScope(orgId);
}
}
});
},
);
@@ -21,234 +21,245 @@ test.beforeAll(async () => {
await boundaryCli.checkBoundaryCli();
});
test('Session Recording Test (MinIO) @ent @docker', async ({
page,
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
bucketAccessKeyId,
bucketEndpointUrl,
bucketName,
bucketSecretAccessKey,
region,
sshUser,
sshKeyPath,
targetAddress,
targetPort,
workerTagEgress,
}) => {
await page.goto('/');
test(
'Session Recording Test (MinIO)',
{ tag: ['@ent', '@docker'] },
async ({
page,
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
bucketAccessKeyId,
bucketEndpointUrl,
bucketName,
bucketSecretAccessKey,
region,
sshUser,
sshKeyPath,
targetAddress,
targetPort,
workerTagEgress,
}) => {
await page.goto('/');
let orgId;
let policyName;
let storageBucket;
let connect;
try {
await boundaryCli.authenticateBoundary(
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
);
// Create org
const orgsPage = new OrgsPage(page);
const orgName = await orgsPage.createOrg();
// Create project
const projectsPage = new ProjectsPage(page);
const projectName = await projectsPage.createProject();
// Create storage bucket
await page.getByRole('link', { name: 'Orgs', exact: true }).click();
const storageBucketsPage = new StorageBucketsPage(page);
const storageBucketName = await storageBucketsPage.createStorageBucketMinio(
orgName,
bucketEndpointUrl,
bucketName,
region,
bucketAccessKeyId,
bucketSecretAccessKey,
`"${workerTagEgress}" in "/tags/type"`,
);
const storageBuckets = JSON.parse(
execSync('boundary storage-buckets list --recursive -format json'),
);
storageBucket = storageBuckets.items.filter(
(obj) => obj.name == storageBucketName,
)[0];
// Create target
await page.getByRole('link', { name: 'Orgs', exact: true }).click();
await expect(page.getByRole('heading', { name: 'Orgs' })).toBeVisible();
await page.getByRole('link', { name: orgName }).click();
await page.getByRole('link', { name: projectName }).click();
const targetsPage = new TargetsPage(page);
const targetName = await targetsPage.createSshTargetWithAddressEnt(
targetAddress,
targetPort,
);
await targetsPage.addIngressWorkerFilterToTarget(
`"${workerTagEgress}" in "/tags/type"`,
);
await targetsPage.addEgressWorkerFilterToTarget(
`"${workerTagEgress}" in "/tags/type"`,
);
const credentialStoresPage = new CredentialStoresPage(page);
await credentialStoresPage.createStaticCredentialStore();
const credentialName =
await credentialStoresPage.createStaticCredentialKeyPair(
sshUser,
sshKeyPath,
let orgId;
let policyName;
let storageBucket;
let connect;
try {
await boundaryCli.authenticateBoundary(
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
);
await targetsPage.addInjectedCredentialsToTarget(
targetName,
credentialName,
);
await page.getByRole('link', { name: targetName }).click();
await targetsPage.enableSessionRecording(storageBucketName);
// Create storage policy in org scope: keep session recordings forever
await page.getByRole('link', { name: 'Orgs', exact: true }).click();
await expect(page.getByRole('heading', { name: 'Orgs' })).toBeVisible();
await page.getByRole('link', { name: orgName }).click();
await expect(
page.getByRole('navigation', { name: 'breadcrumbs' }).getByText(orgName),
).toBeVisible();
const storagePoliciesPage = new StoragePoliciesPage(page);
policyName = await storagePoliciesPage.createStoragePolicy();
await orgsPage.attachStoragePolicy(policyName);
// Create org
const orgsPage = new OrgsPage(page);
const orgName = await orgsPage.createOrg();
// Establish connection to target and cancel it
orgId = await boundaryCli.getOrgIdFromName(orgName);
const projectId = await boundaryCli.getProjectIdFromName(
orgId,
projectName,
);
const targetId = await boundaryCli.getTargetIdFromName(
projectId,
targetName,
);
connect = await boundaryCli.connectSshToTarget(targetId);
await page.getByRole('link', { name: 'Projects', exact: true }).click();
await page.getByRole('link', { name: projectName }).click();
const sessionsPage = new SessionsPage(page);
await sessionsPage.waitForSessionToBeVisible(targetName);
await page
.getByRole('cell', { name: targetName })
.locator('..')
.getByRole('button', { name: 'Cancel' })
.click();
await expect(
page.getByRole('alert').getByText('Success', { exact: true }),
).toBeVisible();
await page.getByRole('button', { name: 'Dismiss', exact: true }).click();
await boundaryCli.waitForSessionRecording(storageBucket.id);
// Create project
const projectsPage = new ProjectsPage(page);
const projectName = await projectsPage.createProject();
// Play back session recording
await page.getByRole('link', { name: 'Orgs', exact: true }).click();
await page
.getByRole('navigation', { name: 'General' })
.getByRole('link', { name: 'Session Recordings', exact: true })
.click();
await page
.getByRole('row', { name: targetName })
.getByRole('link', { name: 'View' })
.click();
await page
.getByRole('cell', { name: 'Channel 1' })
.locator('..')
.getByRole('link', { name: 'Play' })
.click();
await page.locator('div.session-recording-player').hover();
await page.locator('.ap-playback-button').click();
// Create storage bucket
await page.getByRole('link', { name: 'Orgs', exact: true }).click();
const storageBucketsPage = new StorageBucketsPage(page);
const storageBucketName =
await storageBucketsPage.createStorageBucketMinio(
orgName,
bucketEndpointUrl,
bucketName,
region,
bucketAccessKeyId,
bucketSecretAccessKey,
`"${workerTagEgress}" in "/tags/type"`,
);
const storageBuckets = JSON.parse(
execSync('boundary storage-buckets list --recursive -format json'),
);
storageBucket = storageBuckets.items.filter(
(obj) => obj.name == storageBucketName,
)[0];
// Try to delete session recording: expect failure
await page.getByRole('link', { name: 'Orgs', exact: true }).click();
await page
.getByRole('navigation', { name: 'General' })
.getByRole('link', { name: 'Session Recordings', exact: true })
.click();
await page
.getByRole('row', { name: targetName })
.getByRole('link', { name: 'View' })
.click();
await page.getByText('Manage').click();
await page.getByRole('button', { name: 'Delete recording' }).click();
await page.getByRole('button', { name: 'OK', exact: true }).click();
await expect(
page.getByRole('alert').getByText('Error', { exact: true }),
).toBeVisible();
await page.getByRole('button', { name: 'Dismiss' }).click();
// Create target
await page.getByRole('link', { name: 'Orgs', exact: true }).click();
await expect(page.getByRole('heading', { name: 'Orgs' })).toBeVisible();
await page.getByRole('link', { name: orgName }).click();
await page.getByRole('link', { name: projectName }).click();
const targetsPage = new TargetsPage(page);
const targetName = await targetsPage.createSshTargetWithAddressEnt(
targetAddress,
targetPort,
);
await targetsPage.addIngressWorkerFilterToTarget(
`"${workerTagEgress}" in "/tags/type"`,
);
await targetsPage.addEgressWorkerFilterToTarget(
`"${workerTagEgress}" in "/tags/type"`,
);
// Edit storage policy: do not protect from deletion
await page.getByRole('link', { name: 'Orgs', exact: true }).click();
await expect(page.getByRole('heading', { name: 'Orgs' })).toBeVisible();
await page.getByRole('link', { name: orgName }).click();
await expect(
page.getByRole('navigation', { name: 'breadcrumbs' }).getByText(orgName),
).toBeVisible();
await page
.getByRole('link', { name: 'Storage Policies', exact: true })
.click();
await page.getByRole('link', { name: policyName }).click();
await page.getByRole('button', { name: 'Edit form' }).click();
await page
.getByLabel('Retention Policy')
.selectOption({ label: 'Do not protect, allow deletion any time' });
await page.getByLabel('Deletion Policy').selectOption({ label: 'Custom' });
await page.getByRole('button', { name: 'Save' }).click();
await expect(
page.getByRole('alert').getByText('Success', { exact: true }),
).toBeVisible();
await page.getByRole('button', { name: 'Dismiss' }).click();
const credentialStoresPage = new CredentialStoresPage(page);
await credentialStoresPage.createStaticCredentialStore();
const credentialName =
await credentialStoresPage.createStaticCredentialKeyPair(
sshUser,
sshKeyPath,
);
await targetsPage.addInjectedCredentialsToTarget(
targetName,
credentialName,
);
await page.getByRole('link', { name: targetName }).click();
await targetsPage.enableSessionRecording(storageBucketName);
// BUG? After the error trying to delete the session recording, subsequent
// actions result in an error. Reloading the page fixes the issue. This is a
// temporary workaround.
await page.reload();
// Create storage policy in org scope: keep session recordings forever
await page.getByRole('link', { name: 'Orgs', exact: true }).click();
await expect(page.getByRole('heading', { name: 'Orgs' })).toBeVisible();
await page.getByRole('link', { name: orgName }).click();
await expect(
page
.getByRole('navigation', { name: 'breadcrumbs' })
.getByText(orgName),
).toBeVisible();
const storagePoliciesPage = new StoragePoliciesPage(page);
policyName = await storagePoliciesPage.createStoragePolicy();
await orgsPage.attachStoragePolicy(policyName);
// Re-apply storage policy to the session recording and delete
await page.getByRole('link', { name: 'Orgs', exact: true }).click();
await page
.getByRole('link', { name: 'Session Recordings', exact: true })
.click();
await page
.getByRole('row', { name: targetName })
.getByRole('link', { name: 'View' })
.click();
const sessionRecordingsPage = new SessionRecordingsPage(page);
await sessionRecordingsPage.reapplyStoragePolicy();
await sessionRecordingsPage.deleteResource();
// Detach storage bucket from target
await page.getByRole('link', { name: 'Orgs', exact: true }).click();
await expect(page.getByRole('heading', { name: 'Orgs' })).toBeVisible();
await page.getByRole('link', { name: orgName }).click();
await page.getByRole('link', { name: projectName }).click();
await page.getByRole('link', { name: 'Targets', exact: true }).click();
await page.getByRole('link', { name: targetName }).click();
await targetsPage.detachStorageBucket();
} finally {
// End `boundary connect` process
if (connect) {
connect.kill('SIGTERM');
}
if (policyName) {
const storagePolicyId = await boundaryCli.getPolicyIdFromName(
// Establish connection to target and cancel it
orgId = await boundaryCli.getOrgIdFromName(orgName);
const projectId = await boundaryCli.getProjectIdFromName(
orgId,
policyName,
projectName,
);
await boundaryCli.deletePolicy(storagePolicyId);
const targetId = await boundaryCli.getTargetIdFromName(
projectId,
targetName,
);
connect = await boundaryCli.connectSshToTarget(targetId);
await page.getByRole('link', { name: 'Projects', exact: true }).click();
await page.getByRole('link', { name: projectName }).click();
const sessionsPage = new SessionsPage(page);
await sessionsPage.waitForSessionToBeVisible(targetName);
await page
.getByRole('cell', { name: targetName })
.locator('..')
.getByRole('button', { name: 'Cancel' })
.click();
await expect(
page.getByRole('alert').getByText('Success', { exact: true }),
).toBeVisible();
await page.getByRole('button', { name: 'Dismiss', exact: true }).click();
await boundaryCli.waitForSessionRecording(storageBucket.id);
// Play back session recording
await page.getByRole('link', { name: 'Orgs', exact: true }).click();
await page
.getByRole('navigation', { name: 'General' })
.getByRole('link', { name: 'Session Recordings', exact: true })
.click();
await page
.getByRole('row', { name: targetName })
.getByRole('link', { name: 'View' })
.click();
await page
.getByRole('cell', { name: 'Channel 1' })
.locator('..')
.getByRole('link', { name: 'Play' })
.click();
await page.locator('div.session-recording-player').hover();
await page.locator('.ap-playback-button').click();
// Try to delete session recording: expect failure
await page.getByRole('link', { name: 'Orgs', exact: true }).click();
await page
.getByRole('navigation', { name: 'General' })
.getByRole('link', { name: 'Session Recordings', exact: true })
.click();
await page
.getByRole('row', { name: targetName })
.getByRole('link', { name: 'View' })
.click();
await page.getByText('Manage').click();
await page.getByRole('button', { name: 'Delete recording' }).click();
await page.getByRole('button', { name: 'OK', exact: true }).click();
await expect(
page.getByRole('alert').getByText('Error', { exact: true }),
).toBeVisible();
await page.getByRole('button', { name: 'Dismiss' }).click();
// Edit storage policy: do not protect from deletion
await page.getByRole('link', { name: 'Orgs', exact: true }).click();
await expect(page.getByRole('heading', { name: 'Orgs' })).toBeVisible();
await page.getByRole('link', { name: orgName }).click();
await expect(
page
.getByRole('navigation', { name: 'breadcrumbs' })
.getByText(orgName),
).toBeVisible();
await page
.getByRole('link', { name: 'Storage Policies', exact: true })
.click();
await page.getByRole('link', { name: policyName }).click();
await page.getByRole('button', { name: 'Edit form' }).click();
await page
.getByLabel('Retention Policy')
.selectOption({ label: 'Do not protect, allow deletion any time' });
await page
.getByLabel('Deletion Policy')
.selectOption({ label: 'Custom' });
await page.getByRole('button', { name: 'Save' }).click();
await expect(
page.getByRole('alert').getByText('Success', { exact: true }),
).toBeVisible();
await page.getByRole('button', { name: 'Dismiss' }).click();
// BUG? After the error trying to delete the session recording, subsequent
// actions result in an error. Reloading the page fixes the issue. This is a
// temporary workaround.
await page.reload();
// Re-apply storage policy to the session recording and delete
await page.getByRole('link', { name: 'Orgs', exact: true }).click();
await page
.getByRole('link', { name: 'Session Recordings', exact: true })
.click();
await page
.getByRole('row', { name: targetName })
.getByRole('link', { name: 'View' })
.click();
const sessionRecordingsPage = new SessionRecordingsPage(page);
await sessionRecordingsPage.reapplyStoragePolicy();
await sessionRecordingsPage.deleteResource();
// Detach storage bucket from target
await page.getByRole('link', { name: 'Orgs', exact: true }).click();
await expect(page.getByRole('heading', { name: 'Orgs' })).toBeVisible();
await page.getByRole('link', { name: orgName }).click();
await page.getByRole('link', { name: projectName }).click();
await page.getByRole('link', { name: 'Targets', exact: true }).click();
await page.getByRole('link', { name: targetName }).click();
await targetsPage.detachStorageBucket();
} finally {
// End `boundary connect` process
if (connect) {
connect.kill('SIGTERM');
}
if (policyName) {
const storagePolicyId = await boundaryCli.getPolicyIdFromName(
orgId,
policyName,
);
await boundaryCli.deletePolicy(storagePolicyId);
}
if (storageBucket) {
await boundaryCli.deleteStorageBucket(storageBucket.id);
}
if (orgId) {
await boundaryCli.deleteScope(orgId);
}
}
if (storageBucket) {
await boundaryCli.deleteStorageBucket(storageBucket.id);
}
if (orgId) {
await boundaryCli.deleteScope(orgId);
}
}
});
},
);
@@ -32,118 +32,122 @@ test.afterEach(async () => {
execSync(`vault policy delete ${boundaryPolicyName}`);
});
test('SSH Certificate Injection @ent @docker', async ({
page,
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
sshUser,
sshCaKey,
sshCaKeyPublic,
targetAddress,
targetPort,
vaultAddr,
}) => {
await page.goto('/');
let orgId;
let connect;
try {
// Set up vault
execSync(
`vault policy write ${boundaryPolicyName} ./admin/tests/fixtures/boundary-controller-policy.hcl`,
);
execSync(`vault secrets enable -path=${secretsPath} ssh`);
execSync(
`vault policy write ${sshPolicyName} ./admin/tests/fixtures/ssh-policy.hcl`,
);
execSync(
`vault write ${secretsPath}/roles/${secretName} @./admin/tests/fixtures/ssh-certificate-injection-role.json`,
);
const private_key = Buffer.from(sshCaKey, 'base64');
const public_key = Buffer.from(sshCaKeyPublic, 'base64');
execSync(
`vault write ${secretsPath}/config/ca` +
` private_key="${private_key}"` +
` public_key="${public_key}"` +
` generate_signing_key=false`,
` format=json`,
);
const vaultToken = JSON.parse(
test(
'SSH Certificate Injection',
{ tag: ['@ent', '@docker'] },
async ({
page,
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
sshUser,
sshCaKey,
sshCaKeyPublic,
targetAddress,
targetPort,
vaultAddr,
}) => {
await page.goto('/');
let orgId;
let connect;
try {
// Set up vault
execSync(
`vault token create` +
` -no-default-policy=true` +
` -policy=${boundaryPolicyName}` +
` -policy=${sshPolicyName}` +
` -orphan=true` +
` -period=20m` +
` -renewable=true` +
` -format=json`,
),
);
const clientToken = vaultToken.auth.client_token;
// Create org
const orgsPage = new OrgsPage(page);
const orgName = await orgsPage.createOrg();
// Create project
const projectsPage = new ProjectsPage(page);
const projectName = await projectsPage.createProject();
// Create target
const targetsPage = new TargetsPage(page);
const targetName = await targetsPage.createSshTargetWithAddressEnt(
targetAddress,
targetPort,
);
// Create credentials
const credentialStoresPage = new CredentialStoresPage(page);
await credentialStoresPage.createVaultCredentialStore(
vaultAddr,
clientToken,
);
const credentialLibraryName =
await credentialStoresPage.createVaultSshCertificateCredentialLibraryEnt(
`${secretsPath}/issue/${secretName}`,
sshUser,
`vault policy write ${boundaryPolicyName} ./admin/tests/fixtures/boundary-controller-policy.hcl`,
);
execSync(`vault secrets enable -path=${secretsPath} ssh`);
execSync(
`vault policy write ${sshPolicyName} ./admin/tests/fixtures/ssh-policy.hcl`,
);
execSync(
`vault write ${secretsPath}/roles/${secretName} @./admin/tests/fixtures/ssh-certificate-injection-role.json`,
);
await targetsPage.addInjectedCredentialsToTarget(
targetName,
credentialLibraryName,
);
// Connect to target
await boundaryCli.authenticateBoundary(
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
);
orgId = await boundaryCli.getOrgIdFromName(orgName);
const projectId = await boundaryCli.getProjectIdFromName(
orgId,
projectName,
);
const targetId = await boundaryCli.getTargetIdFromName(
projectId,
targetName,
);
connect = await boundaryCli.connectSshToTarget(targetId);
const sessionsPage = new SessionsPage(page);
await sessionsPage.waitForSessionToBeVisible(targetName);
} finally {
// End `boundary connect` process
if (connect) {
connect.kill('SIGTERM');
}
const private_key = Buffer.from(sshCaKey, 'base64');
const public_key = Buffer.from(sshCaKeyPublic, 'base64');
if (orgId) {
await boundaryCli.deleteScope(orgId);
execSync(
`vault write ${secretsPath}/config/ca` +
` private_key="${private_key}"` +
` public_key="${public_key}"` +
` generate_signing_key=false`,
` format=json`,
);
const vaultToken = JSON.parse(
execSync(
`vault token create` +
` -no-default-policy=true` +
` -policy=${boundaryPolicyName}` +
` -policy=${sshPolicyName}` +
` -orphan=true` +
` -period=20m` +
` -renewable=true` +
` -format=json`,
),
);
const clientToken = vaultToken.auth.client_token;
// Create org
const orgsPage = new OrgsPage(page);
const orgName = await orgsPage.createOrg();
// Create project
const projectsPage = new ProjectsPage(page);
const projectName = await projectsPage.createProject();
// Create target
const targetsPage = new TargetsPage(page);
const targetName = await targetsPage.createSshTargetWithAddressEnt(
targetAddress,
targetPort,
);
// Create credentials
const credentialStoresPage = new CredentialStoresPage(page);
await credentialStoresPage.createVaultCredentialStore(
vaultAddr,
clientToken,
);
const credentialLibraryName =
await credentialStoresPage.createVaultSshCertificateCredentialLibraryEnt(
`${secretsPath}/issue/${secretName}`,
sshUser,
);
await targetsPage.addInjectedCredentialsToTarget(
targetName,
credentialLibraryName,
);
// Connect to target
await boundaryCli.authenticateBoundary(
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
);
orgId = await boundaryCli.getOrgIdFromName(orgName);
const projectId = await boundaryCli.getProjectIdFromName(
orgId,
projectName,
);
const targetId = await boundaryCli.getTargetIdFromName(
projectId,
targetName,
);
connect = await boundaryCli.connectSshToTarget(targetId);
const sessionsPage = new SessionsPage(page);
await sessionsPage.waitForSessionToBeVisible(targetName);
} finally {
// End `boundary connect` process
if (connect) {
connect.kill('SIGTERM');
}
if (orgId) {
await boundaryCli.deleteScope(orgId);
}
}
}
});
},
);
@@ -34,106 +34,110 @@ test.afterEach(() => {
execSync(`vault secrets disable ${secretsPath}`);
});
test('SSH Credential Injection (Vault User & Key Pair) @ent @docker', async ({
page,
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
sshUser,
sshKeyPath,
targetAddress,
targetPort,
vaultAddr,
}) => {
let orgId;
let connect;
try {
// Set up vault
execSync(
`vault policy write ${boundaryPolicyName} ./admin/tests/fixtures/boundary-controller-policy.hcl`,
);
execSync(`vault secrets enable -path=${secretsPath} kv-v2`);
execSync(
`vault kv put -mount ${secretsPath} ${secretName} ` +
` username=${sshUser}` +
` private_key=@${sshKeyPath}`,
);
execSync(
`vault policy write ${secretPolicyName} ./admin/tests/fixtures/kv-policy.hcl`,
);
const vaultToken = JSON.parse(
test(
'SSH Credential Injection (Vault User & Key Pair)',
{ tag: ['@ent', '@docker'] },
async ({
page,
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
sshUser,
sshKeyPath,
targetAddress,
targetPort,
vaultAddr,
}) => {
let orgId;
let connect;
try {
// Set up vault
execSync(
`vault token create` +
` -no-default-policy=true` +
` -policy=${boundaryPolicyName}` +
` -policy=${secretPolicyName}` +
` -orphan=true` +
` -period=20m` +
` -renewable=true` +
` -format=json`,
),
);
const clientToken = vaultToken.auth.client_token;
// Create org
const orgsPage = new OrgsPage(page);
const orgName = await orgsPage.createOrg();
// Create project
const projectsPage = new ProjectsPage(page);
const projectName = await projectsPage.createProject();
// Create target
const targetsPage = new TargetsPage(page);
const targetName = await targetsPage.createSshTargetWithAddressEnt(
targetAddress,
targetPort,
);
// Create credentials
const credentialStoresPage = new CredentialStoresPage(page);
await credentialStoresPage.createVaultCredentialStore(
vaultAddr,
clientToken,
);
const credentialLibraryName =
await credentialStoresPage.createVaultGenericCredentialLibraryEnt(
`${secretsPath}/data/${secretName}`,
'SSH Private Key',
`vault policy write ${boundaryPolicyName} ./admin/tests/fixtures/boundary-controller-policy.hcl`,
);
await targetsPage.addInjectedCredentialsToTarget(
targetName,
credentialLibraryName,
);
execSync(`vault secrets enable -path=${secretsPath} kv-v2`);
execSync(
`vault kv put -mount ${secretsPath} ${secretName} ` +
` username=${sshUser}` +
` private_key=@${sshKeyPath}`,
);
execSync(
`vault policy write ${secretPolicyName} ./admin/tests/fixtures/kv-policy.hcl`,
);
const vaultToken = JSON.parse(
execSync(
`vault token create` +
` -no-default-policy=true` +
` -policy=${boundaryPolicyName}` +
` -policy=${secretPolicyName}` +
` -orphan=true` +
` -period=20m` +
` -renewable=true` +
` -format=json`,
),
);
const clientToken = vaultToken.auth.client_token;
// Connect to target
await boundaryCli.authenticateBoundary(
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
);
orgId = await boundaryCli.getOrgIdFromName(orgName);
const projectId = await boundaryCli.getProjectIdFromName(
orgId,
projectName,
);
const targetId = await boundaryCli.getTargetIdFromName(
projectId,
targetName,
);
connect = await boundaryCli.connectSshToTarget(targetId);
const sessionsPage = new SessionsPage(page);
await sessionsPage.waitForSessionToBeVisible(targetName);
} finally {
// End `boundary connect` process
if (connect) {
connect.kill('SIGTERM');
}
// Create org
const orgsPage = new OrgsPage(page);
const orgName = await orgsPage.createOrg();
if (orgId) {
await boundaryCli.deleteScope(orgId);
// Create project
const projectsPage = new ProjectsPage(page);
const projectName = await projectsPage.createProject();
// Create target
const targetsPage = new TargetsPage(page);
const targetName = await targetsPage.createSshTargetWithAddressEnt(
targetAddress,
targetPort,
);
// Create credentials
const credentialStoresPage = new CredentialStoresPage(page);
await credentialStoresPage.createVaultCredentialStore(
vaultAddr,
clientToken,
);
const credentialLibraryName =
await credentialStoresPage.createVaultGenericCredentialLibraryEnt(
`${secretsPath}/data/${secretName}`,
'SSH Private Key',
);
await targetsPage.addInjectedCredentialsToTarget(
targetName,
credentialLibraryName,
);
// Connect to target
await boundaryCli.authenticateBoundary(
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
);
orgId = await boundaryCli.getOrgIdFromName(orgName);
const projectId = await boundaryCli.getProjectIdFromName(
orgId,
projectName,
);
const targetId = await boundaryCli.getTargetIdFromName(
projectId,
targetName,
);
connect = await boundaryCli.connectSshToTarget(targetId);
const sessionsPage = new SessionsPage(page);
await sessionsPage.waitForSessionToBeVisible(targetName);
} finally {
// End `boundary connect` process
if (connect) {
connect.kill('SIGTERM');
}
if (orgId) {
await boundaryCli.deleteScope(orgId);
}
}
}
});
},
);
+236 -220
View File
@@ -18,233 +18,249 @@ test.beforeAll(async () => {
await boundaryCli.checkBoundaryCli();
});
test('Verify session created for TCP target @ent @aws @docker', async ({
page,
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
sshUser,
sshKeyPath,
targetAddress,
targetPort,
}) => {
await page.goto('/');
let orgId;
let connect;
try {
const orgsPage = new OrgsPage(page);
const orgName = await orgsPage.createOrg();
const projectsPage = new ProjectsPage(page);
const projectName = await projectsPage.createProject();
const targetsPage = new TargetsPage(page);
const targetName = await targetsPage.createTcpTargetWithAddressEnt(
targetAddress,
targetPort,
);
test(
'Verify session created for TCP target',
{ tag: ['@ent', '@aws', '@docker'] },
async ({
page,
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
sshUser,
sshKeyPath,
targetAddress,
targetPort,
}) => {
await page.goto('/');
let orgId;
let connect;
try {
const orgsPage = new OrgsPage(page);
const orgName = await orgsPage.createOrg();
const projectsPage = new ProjectsPage(page);
const projectName = await projectsPage.createProject();
const targetsPage = new TargetsPage(page);
const targetName = await targetsPage.createTcpTargetWithAddressEnt(
targetAddress,
targetPort,
);
await boundaryCli.authenticateBoundary(
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
);
orgId = await boundaryCli.getOrgIdFromName(orgName);
const projectId = await boundaryCli.getProjectIdFromName(
orgId,
projectName,
);
const targetId = await boundaryCli.getTargetIdFromName(
projectId,
targetName,
);
connect = await boundaryCli.connectToTarget(targetId, sshUser, sshKeyPath);
const sessionsPage = new SessionsPage(page);
await sessionsPage.waitForSessionToBeVisible(targetName);
await page
.getByRole('cell', { name: targetName })
.locator('..')
.getByRole('button', { name: 'Cancel' })
.click();
} finally {
if (orgId) {
await boundaryCli.deleteScope(orgId);
}
// End `boundary connect` process
if (connect) {
connect.kill('SIGTERM');
}
}
});
test('Verify session created for SSH target @ent @aws @docker', async ({
page,
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
sshUser,
sshKeyPath,
targetAddress,
targetPort,
}) => {
await page.goto('/');
let orgId;
let connect;
try {
const orgsPage = new OrgsPage(page);
const orgName = await orgsPage.createOrg();
const projectsPage = new ProjectsPage(page);
const projectName = await projectsPage.createProject();
const targetsPage = new TargetsPage(page);
const targetName = await targetsPage.createSshTargetWithAddressEnt(
targetAddress,
targetPort,
);
const credentialStoresPage = new CredentialStoresPage(page);
await credentialStoresPage.createStaticCredentialStore();
const credentialName =
await credentialStoresPage.createStaticCredentialKeyPair(
await boundaryCli.authenticateBoundary(
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
);
orgId = await boundaryCli.getOrgIdFromName(orgName);
const projectId = await boundaryCli.getProjectIdFromName(
orgId,
projectName,
);
const targetId = await boundaryCli.getTargetIdFromName(
projectId,
targetName,
);
connect = await boundaryCli.connectToTarget(
targetId,
sshUser,
sshKeyPath,
);
await targetsPage.addInjectedCredentialsToTarget(
targetName,
credentialName,
);
await boundaryCli.authenticateBoundary(
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
);
orgId = await boundaryCli.getOrgIdFromName(orgName);
const projectId = await boundaryCli.getProjectIdFromName(
orgId,
projectName,
);
const targetId = await boundaryCli.getTargetIdFromName(
projectId,
targetName,
);
connect = await boundaryCli.connectSshToTarget(targetId);
const sessionsPage = new SessionsPage(page);
await sessionsPage.waitForSessionToBeVisible(targetName);
await page
.getByRole('cell', { name: targetName })
.locator('..')
.getByRole('button', { name: 'Cancel' })
.click();
} finally {
if (orgId) {
await boundaryCli.deleteScope(orgId);
const sessionsPage = new SessionsPage(page);
await sessionsPage.waitForSessionToBeVisible(targetName);
await page
.getByRole('cell', { name: targetName })
.locator('..')
.getByRole('button', { name: 'Cancel' })
.click();
} finally {
if (orgId) {
await boundaryCli.deleteScope(orgId);
}
// End `boundary connect` process
if (connect) {
connect.kill('SIGTERM');
}
}
// End `boundary connect` process
if (connect) {
connect.kill('SIGTERM');
}
}
});
},
);
test('SSH target with host sources @ent @aws @docker', async ({
page,
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
sshUser,
sshKeyPath,
targetAddress,
targetPort,
}) => {
await page.goto('/');
let orgId;
let connect;
try {
const orgsPage = new OrgsPage(page);
const orgName = await orgsPage.createOrg();
const projectsPage = new ProjectsPage(page);
const projectName = await projectsPage.createProject();
// Create host set
const hostCatalogsPage = new HostCatalogsPage(page);
const hostCatalogName = await hostCatalogsPage.createHostCatalog();
const hostSetName = await hostCatalogsPage.createHostSet();
await hostCatalogsPage.createHostInHostSet(targetAddress);
// Create another host set
await page
.getByRole('navigation', { name: 'Resources' })
.getByRole('link', { name: 'Host Catalogs' })
.click();
await page.getByRole('link', { name: hostCatalogName }).click();
const hostSetName2 = await hostCatalogsPage.createHostSet();
// Create target
const targetsPage = new TargetsPage(page);
const targetName = await targetsPage.createSshTargetEnt(targetPort);
await targetsPage.addHostSourceToTarget(hostSetName);
// Add/Remove another host source
await targetsPage.addHostSourceToTarget(hostSetName2);
await page
.getByRole('link', { name: hostSetName2 })
.locator('..')
.locator('..')
.getByRole('button', { name: 'Manage' })
.click();
await page.getByRole('button', { name: 'Remove' }).click();
await page.getByRole('button', { name: 'OK', exact: true }).click();
await expect(
page.getByRole('alert').getByText('Success', { exact: true }),
).toBeVisible();
await page.getByRole('button', { name: 'Dismiss' }).click();
// Create credentials and attach to target
const credentialStoresPage = new CredentialStoresPage(page);
await credentialStoresPage.createStaticCredentialStore();
const credentialName =
await credentialStoresPage.createStaticCredentialKeyPair(
sshUser,
sshKeyPath,
test(
'Verify session created for SSH target',
{ tag: ['@ent', '@aws', '@docker'] },
async ({
page,
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
sshUser,
sshKeyPath,
targetAddress,
targetPort,
}) => {
await page.goto('/');
let orgId;
let connect;
try {
const orgsPage = new OrgsPage(page);
const orgName = await orgsPage.createOrg();
const projectsPage = new ProjectsPage(page);
const projectName = await projectsPage.createProject();
const targetsPage = new TargetsPage(page);
const targetName = await targetsPage.createSshTargetWithAddressEnt(
targetAddress,
targetPort,
);
const credentialStoresPage = new CredentialStoresPage(page);
await credentialStoresPage.createStaticCredentialStore();
const credentialName =
await credentialStoresPage.createStaticCredentialKeyPair(
sshUser,
sshKeyPath,
);
await targetsPage.addInjectedCredentialsToTarget(
targetName,
credentialName,
);
await targetsPage.addInjectedCredentialsToTarget(
targetName,
credentialName,
);
// Connect to target
await boundaryCli.authenticateBoundary(
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
);
orgId = await boundaryCli.getOrgIdFromName(orgName);
const projectId = await boundaryCli.getProjectIdFromName(
orgId,
projectName,
);
const targetId = await boundaryCli.getTargetIdFromName(
projectId,
targetName,
);
connect = await boundaryCli.connectSshToTarget(targetId);
const sessionsPage = new SessionsPage(page);
await sessionsPage.waitForSessionToBeVisible(targetName);
await page
.getByRole('cell', { name: targetName })
.locator('..')
.getByRole('button', { name: 'Cancel' })
.click();
} finally {
if (orgId) {
await boundaryCli.deleteScope(orgId);
await boundaryCli.authenticateBoundary(
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
);
orgId = await boundaryCli.getOrgIdFromName(orgName);
const projectId = await boundaryCli.getProjectIdFromName(
orgId,
projectName,
);
const targetId = await boundaryCli.getTargetIdFromName(
projectId,
targetName,
);
connect = await boundaryCli.connectSshToTarget(targetId);
const sessionsPage = new SessionsPage(page);
await sessionsPage.waitForSessionToBeVisible(targetName);
await page
.getByRole('cell', { name: targetName })
.locator('..')
.getByRole('button', { name: 'Cancel' })
.click();
} finally {
if (orgId) {
await boundaryCli.deleteScope(orgId);
}
// End `boundary connect` process
if (connect) {
connect.kill('SIGTERM');
}
}
// End `boundary connect` process
if (connect) {
connect.kill('SIGTERM');
},
);
test(
'SSH target with host sources',
{ tag: ['@ent', '@aws', '@docker'] },
async ({
page,
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
sshUser,
sshKeyPath,
targetAddress,
targetPort,
}) => {
await page.goto('/');
let orgId;
let connect;
try {
const orgsPage = new OrgsPage(page);
const orgName = await orgsPage.createOrg();
const projectsPage = new ProjectsPage(page);
const projectName = await projectsPage.createProject();
// Create host set
const hostCatalogsPage = new HostCatalogsPage(page);
const hostCatalogName = await hostCatalogsPage.createHostCatalog();
const hostSetName = await hostCatalogsPage.createHostSet();
await hostCatalogsPage.createHostInHostSet(targetAddress);
// Create another host set
await page
.getByRole('navigation', { name: 'Resources' })
.getByRole('link', { name: 'Host Catalogs' })
.click();
await page.getByRole('link', { name: hostCatalogName }).click();
const hostSetName2 = await hostCatalogsPage.createHostSet();
// Create target
const targetsPage = new TargetsPage(page);
const targetName = await targetsPage.createSshTargetEnt(targetPort);
await targetsPage.addHostSourceToTarget(hostSetName);
// Add/Remove another host source
await targetsPage.addHostSourceToTarget(hostSetName2);
await page
.getByRole('link', { name: hostSetName2 })
.locator('..')
.locator('..')
.getByRole('button', { name: 'Manage' })
.click();
await page.getByRole('button', { name: 'Remove' }).click();
await page.getByRole('button', { name: 'OK', exact: true }).click();
await expect(
page.getByRole('alert').getByText('Success', { exact: true }),
).toBeVisible();
await page.getByRole('button', { name: 'Dismiss' }).click();
// Create credentials and attach to target
const credentialStoresPage = new CredentialStoresPage(page);
await credentialStoresPage.createStaticCredentialStore();
const credentialName =
await credentialStoresPage.createStaticCredentialKeyPair(
sshUser,
sshKeyPath,
);
await targetsPage.addInjectedCredentialsToTarget(
targetName,
credentialName,
);
// Connect to target
await boundaryCli.authenticateBoundary(
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
);
orgId = await boundaryCli.getOrgIdFromName(orgName);
const projectId = await boundaryCli.getProjectIdFromName(
orgId,
projectName,
);
const targetId = await boundaryCli.getTargetIdFromName(
projectId,
targetName,
);
connect = await boundaryCli.connectSshToTarget(targetId);
const sessionsPage = new SessionsPage(page);
await sessionsPage.waitForSessionToBeVisible(targetName);
await page
.getByRole('cell', { name: targetName })
.locator('..')
.getByRole('button', { name: 'Cancel' })
.click();
} finally {
if (orgId) {
await boundaryCli.deleteScope(orgId);
}
// End `boundary connect` process
if (connect) {
connect.kill('SIGTERM');
}
}
}
});
},
);
+223 -203
View File
@@ -18,216 +18,236 @@ test.beforeAll(async () => {
await boundaryCli.checkBoundaryCli();
});
test('Verify session created to target with host, then cancel the session @ce @aws @docker', async ({
page,
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
sshUser,
sshKeyPath,
targetAddress,
targetPort,
}) => {
await page.goto('/');
let orgId;
let connect;
try {
const orgsPage = new OrgsPage(page);
const orgName = await orgsPage.createOrg();
const projectsPage = new ProjectsPage(page);
const projectName = await projectsPage.createProject();
test(
'Verify session created to target with host, then cancel the session',
{ tag: ['@ce', '@aws', '@docker'] },
async ({
page,
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
sshUser,
sshKeyPath,
targetAddress,
targetPort,
}) => {
await page.goto('/');
let orgId;
let connect;
try {
const orgsPage = new OrgsPage(page);
const orgName = await orgsPage.createOrg();
const projectsPage = new ProjectsPage(page);
const projectName = await projectsPage.createProject();
// Create host set
const hostCatalogsPage = new HostCatalogsPage(page);
const hostCatalogName = await hostCatalogsPage.createHostCatalog();
const hostSetName = await hostCatalogsPage.createHostSet();
await hostCatalogsPage.createHostInHostSet(targetAddress);
// Create host set
const hostCatalogsPage = new HostCatalogsPage(page);
const hostCatalogName = await hostCatalogsPage.createHostCatalog();
const hostSetName = await hostCatalogsPage.createHostSet();
await hostCatalogsPage.createHostInHostSet(targetAddress);
// Create another host set
await page
.getByRole('navigation', { name: 'Resources' })
.getByRole('link', { name: 'Host Catalogs' })
.click();
await page.getByRole('link', { name: hostCatalogName }).click();
const hostSetName2 = await hostCatalogsPage.createHostSet();
// Create another host set
await page
.getByRole('navigation', { name: 'Resources' })
.getByRole('link', { name: 'Host Catalogs' })
.click();
await page.getByRole('link', { name: hostCatalogName }).click();
const hostSetName2 = await hostCatalogsPage.createHostSet();
// Create target
const targetsPage = new TargetsPage(page);
const targetName = await targetsPage.createTarget(targetPort);
await targetsPage.addHostSourceToTarget(hostSetName);
// Create target
const targetsPage = new TargetsPage(page);
const targetName = await targetsPage.createTarget(targetPort);
await targetsPage.addHostSourceToTarget(hostSetName);
// Add/Remove another host source
await targetsPage.addHostSourceToTarget(hostSetName2);
await targetsPage.removeHostSourceFromTarget(hostSetName2);
// Add/Remove another host source
await targetsPage.addHostSourceToTarget(hostSetName2);
await targetsPage.removeHostSourceFromTarget(hostSetName2);
// Connect to target
await boundaryCli.authenticateBoundary(
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
);
orgId = await boundaryCli.getOrgIdFromName(orgName);
const projectId = await boundaryCli.getProjectIdFromName(
orgId,
projectName,
);
const targetId = await boundaryCli.getTargetIdFromName(
projectId,
targetName,
);
connect = await boundaryCli.connectToTarget(targetId, sshUser, sshKeyPath);
const sessionsPage = new SessionsPage(page);
await sessionsPage.waitForSessionToBeVisible(targetName);
await page
.getByRole('cell', { name: targetName })
.locator('..')
.getByRole('button', { name: 'Cancel' })
.click();
} finally {
if (orgId) {
await boundaryCli.deleteScope(orgId);
// Connect to target
await boundaryCli.authenticateBoundary(
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
);
orgId = await boundaryCli.getOrgIdFromName(orgName);
const projectId = await boundaryCli.getProjectIdFromName(
orgId,
projectName,
);
const targetId = await boundaryCli.getTargetIdFromName(
projectId,
targetName,
);
connect = await boundaryCli.connectToTarget(
targetId,
sshUser,
sshKeyPath,
);
const sessionsPage = new SessionsPage(page);
await sessionsPage.waitForSessionToBeVisible(targetName);
await page
.getByRole('cell', { name: targetName })
.locator('..')
.getByRole('button', { name: 'Cancel' })
.click();
} finally {
if (orgId) {
await boundaryCli.deleteScope(orgId);
}
// End `boundary connect` process
if (connect) {
connect.kill('SIGTERM');
}
}
// End `boundary connect` process
if (connect) {
connect.kill('SIGTERM');
},
);
test(
'Verify session created to target with address, then cancel the session',
{ tag: ['@ce', '@aws', '@docker'] },
async ({
page,
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
sshUser,
sshKeyPath,
targetAddress,
targetPort,
}) => {
await page.goto('/');
let orgId;
let connect;
try {
const orgsPage = new OrgsPage(page);
const orgName = await orgsPage.createOrg();
const projectsPage = new ProjectsPage(page);
const projectName = await projectsPage.createProject();
const targetsPage = new TargetsPage(page);
const targetName = await targetsPage.createTargetWithAddress(
targetAddress,
targetPort,
);
await boundaryCli.authenticateBoundary(
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
);
orgId = await boundaryCli.getOrgIdFromName(orgName);
const projectId = await boundaryCli.getProjectIdFromName(
orgId,
projectName,
);
const targetId = await boundaryCli.getTargetIdFromName(
projectId,
targetName,
);
connect = await boundaryCli.connectToTarget(
targetId,
sshUser,
sshKeyPath,
);
const sessionsPage = new SessionsPage(page);
await sessionsPage.waitForSessionToBeVisible(targetName);
await page
.getByRole('cell', { name: targetName })
.locator('..')
.getByRole('button', { name: 'Cancel' })
.click();
} finally {
if (orgId) {
await boundaryCli.deleteScope(orgId);
}
// End `boundary connect` process
if (connect) {
connect.kill('SIGTERM');
}
}
}
});
},
);
test('Verify session created to target with address, then cancel the session @ce @aws @docker', async ({
page,
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
sshUser,
sshKeyPath,
targetAddress,
targetPort,
}) => {
await page.goto('/');
let orgId;
let connect;
try {
const orgsPage = new OrgsPage(page);
const orgName = await orgsPage.createOrg();
const projectsPage = new ProjectsPage(page);
const projectName = await projectsPage.createProject();
const targetsPage = new TargetsPage(page);
const targetName = await targetsPage.createTargetWithAddress(
targetAddress,
targetPort,
);
test(
'Verify TCP target is updated',
{ tag: ['@ce', '@aws', '@docker'] },
async ({
page,
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
targetAddress,
targetPort,
}) => {
await page.goto('/');
let orgName;
try {
const orgsPage = new OrgsPage(page);
orgName = await orgsPage.createOrg();
const projectsPage = new ProjectsPage(page);
await projectsPage.createProject();
const targetsPage = new TargetsPage(page);
await targetsPage.createTargetWithAddress(targetAddress, targetPort);
await boundaryCli.authenticateBoundary(
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
);
orgId = await boundaryCli.getOrgIdFromName(orgName);
const projectId = await boundaryCli.getProjectIdFromName(
orgId,
projectName,
);
const targetId = await boundaryCli.getTargetIdFromName(
projectId,
targetName,
);
connect = await boundaryCli.connectToTarget(targetId, sshUser, sshKeyPath);
const sessionsPage = new SessionsPage(page);
await sessionsPage.waitForSessionToBeVisible(targetName);
await page
.getByRole('cell', { name: targetName })
.locator('..')
.getByRole('button', { name: 'Cancel' })
.click();
} finally {
if (orgId) {
await boundaryCli.deleteScope(orgId);
// Update target
await page.getByRole('button', { name: 'Edit Form' }).click();
await page.getByLabel('Name').fill('New target name');
await page.getByLabel('Description').fill('New description');
await page.getByLabel('Target Address').fill('127.0.0.1');
await page.getByLabel('Default Port').fill('10');
await page.getByLabel('Default Client Port').fill('10');
await page.getByLabel('Maximum Duration').fill('1000');
await page.getByLabel('Maximum Connections').fill('10');
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 targetsPage.addEgressWorkerFilterToTarget('"dev" in "/tags/type"');
// Edit a worker filter
await page.getByRole('link', { name: 'Workers', exact: true }).click();
await expect(
page
.getByRole('navigation', { name: 'breadcrumbs' })
.getByText('Workers'),
).toBeVisible();
await page
.getByText('Egress workers')
.locator('..')
.getByRole('link', { name: 'Edit worker filter' })
.click();
await expect(
page
.getByRole('navigation', { name: 'breadcrumbs' })
.getByText('Edit Egress Worker Filter'),
).toBeVisible();
await expect(page.getByText('"dev" in "/tags/type"')).toBeVisible();
await page.locator('textarea').click({ force: true });
await page.keyboard.press('Meta+A');
await page.keyboard.press('Backspace');
await page.locator('textarea').fill('"prod" in "/tags/type"');
await page.getByRole('button', { name: 'Save' }).click();
const basePage = new BasePage(page);
await basePage.dismissSuccessAlert();
} finally {
await boundaryCli.authenticateBoundary(
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
);
const orgId = await boundaryCli.getOrgIdFromName(orgName);
if (orgId) {
await boundaryCli.deleteScope(orgId);
}
}
// End `boundary connect` process
if (connect) {
connect.kill('SIGTERM');
}
}
});
test('Verify TCP target is updated @ce @aws @docker', async ({
page,
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
targetAddress,
targetPort,
}) => {
await page.goto('/');
let orgName;
try {
const orgsPage = new OrgsPage(page);
orgName = await orgsPage.createOrg();
const projectsPage = new ProjectsPage(page);
await projectsPage.createProject();
const targetsPage = new TargetsPage(page);
await targetsPage.createTargetWithAddress(targetAddress, targetPort);
// Update target
await page.getByRole('button', { name: 'Edit Form' }).click();
await page.getByLabel('Name').fill('New target name');
await page.getByLabel('Description').fill('New description');
await page.getByLabel('Target Address').fill('127.0.0.1');
await page.getByLabel('Default Port').fill('10');
await page.getByLabel('Default Client Port').fill('10');
await page.getByLabel('Maximum Duration').fill('1000');
await page.getByLabel('Maximum Connections').fill('10');
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 targetsPage.addEgressWorkerFilterToTarget('"dev" in "/tags/type"');
// Edit a worker filter
await page.getByRole('link', { name: 'Workers', exact: true }).click();
await expect(
page
.getByRole('navigation', { name: 'breadcrumbs' })
.getByText('Workers'),
).toBeVisible();
await page
.getByText('Egress workers')
.locator('..')
.getByRole('link', { name: 'Edit worker filter' })
.click();
await expect(
page
.getByRole('navigation', { name: 'breadcrumbs' })
.getByText('Edit Egress Worker Filter'),
).toBeVisible();
await expect(page.getByText('"dev" in "/tags/type"')).toBeVisible();
await page.locator('textarea').click({ force: true });
await page.keyboard.press('Meta+A');
await page.keyboard.press('Backspace');
await page.locator('textarea').fill('"prod" in "/tags/type"');
await page.getByRole('button', { name: 'Save' }).click();
const basePage = new BasePage(page);
await basePage.dismissSuccessAlert();
} finally {
await boundaryCli.authenticateBoundary(
baseURL,
adminAuthMethodId,
adminLoginName,
adminPassword,
);
const orgId = await boundaryCli.getOrgIdFromName(orgName);
if (orgId) {
await boundaryCli.deleteScope(orgId);
}
}
});
},
);
+81 -76
View File
@@ -6,85 +6,90 @@
import { test } from '../../global-setup.js';
import { expect } from '@playwright/test';
test('Create a worker (enterprise) @ent @docker @aws', async ({
page,
browserName,
}) => {
test.skip(browserName === 'webkit', 'Bug in worker form on Safari');
test(
'Create a worker (enterprise)',
{ tag: ['@ent', '@aws', '@docker'] },
async ({ page, browserName }) => {
test.skip(browserName === 'webkit', 'Bug in worker form on Safari');
await page.goto('/');
await page
.getByRole('navigation', { name: 'General' })
.getByRole('link', { name: 'Workers' })
.click();
await page.getByRole('link', { name: 'New', exact: true }).click();
await page.goto('/');
await page
.getByRole('navigation', { name: 'General' })
.getByRole('link', { name: 'Workers' })
.click();
await page.getByRole('link', { name: 'New', exact: true }).click();
// Populate config fields
await page.getByLabel('Worker public address').fill('worker1.example.com');
await page.getByLabel('Config file path').fill('/home/ubuntu/boundary');
await page.getByLabel('Initial upstreams').fill('10.0.0.1, 10.0.0.2');
await page
.getByRole('group', { name: 'Worker Tags' })
.getByLabel('Key')
.fill('type');
await page
.getByRole('group', { name: 'Worker Tags' })
.getByLabel('Value')
.fill('downstream, pki');
await page
.getByRole('group', { name: 'Worker Tags' })
.getByRole('button', { name: 'Add' })
.click();
await page
.getByRole('group', { name: 'Worker Tags' })
.getByLabel('Key')
.last()
.fill('test');
await page
.getByRole('group', { name: 'Worker Tags' })
.getByLabel('Value')
.last()
.fill('example');
await page
.getByRole('group', { name: 'Worker Tags' })
.getByRole('button', { name: 'Add' })
.click();
// Populate config fields
await page.getByLabel('Worker public address').fill('worker1.example.com');
await page.getByLabel('Config file path').fill('/home/ubuntu/boundary');
await page.getByLabel('Initial upstreams').fill('10.0.0.1, 10.0.0.2');
await page
.getByRole('group', { name: 'Worker Tags' })
.getByLabel('Key')
.fill('type');
await page
.getByRole('group', { name: 'Worker Tags' })
.getByLabel('Value')
.fill('downstream, pki');
await page
.getByRole('group', { name: 'Worker Tags' })
.getByRole('button', { name: 'Add' })
.click();
await page
.getByRole('group', { name: 'Worker Tags' })
.getByLabel('Key')
.last()
.fill('test');
await page
.getByRole('group', { name: 'Worker Tags' })
.getByLabel('Value')
.last()
.fill('example');
await page
.getByRole('group', { name: 'Worker Tags' })
.getByRole('button', { name: 'Add' })
.click();
await page.getByRole('switch', { name: 'Enable Recording Storage' }).click();
await page.getByLabel('Recording Storage Path').fill('/tmp/recordings');
await page
.getByRole('switch', { name: 'Enable Recording Storage' })
.click();
await page.getByLabel('Recording Storage Path').fill('/tmp/recordings');
// Check auto-populated config
const dirLocator = '[data-test-worker-directory]';
await expect(page.locator(dirLocator)).toContainText(
'mkdir /home/ubuntu/boundary/ ;',
);
await expect(page.locator(dirLocator)).toContainText(
'touch /home/ubuntu/boundary/pki-worker.hcl',
);
// Check auto-populated config
const dirLocator = '[data-test-worker-directory]';
await expect(page.locator(dirLocator)).toContainText(
'mkdir /home/ubuntu/boundary/ ;',
);
await expect(page.locator(dirLocator)).toContainText(
'touch /home/ubuntu/boundary/pki-worker.hcl',
);
const configLocator = '[data-test-worker-config]';
await expect(page.locator(configLocator)).toContainText(
'public_addr = "worker1.example.com"',
);
await expect(page.locator(configLocator)).toContainText(
'auth_storage_path = "/home/ubuntu/boundary/worker1"',
);
await expect(page.locator(configLocator)).toContainText(
'initial_upstreams = ["10.0.0.1", "10.0.0.2"]',
);
await expect(page.locator(configLocator)).toContainText(
'type = ["downstream", "pki"]',
);
await expect(page.locator(configLocator)).toContainText('test = ["example"]');
await expect(page.locator(configLocator)).toContainText(
'recording_storage_path = "/tmp/recordings"',
);
const configLocator = '[data-test-worker-config]';
await expect(page.locator(configLocator)).toContainText(
'public_addr = "worker1.example.com"',
);
await expect(page.locator(configLocator)).toContainText(
'auth_storage_path = "/home/ubuntu/boundary/worker1"',
);
await expect(page.locator(configLocator)).toContainText(
'initial_upstreams = ["10.0.0.1", "10.0.0.2"]',
);
await expect(page.locator(configLocator)).toContainText(
'type = ["downstream", "pki"]',
);
await expect(page.locator(configLocator)).toContainText(
'test = ["example"]',
);
await expect(page.locator(configLocator)).toContainText(
'recording_storage_path = "/tmp/recordings"',
);
// Try using an invalid worker token. Expect an error
await page.getByLabel('Worker Auth Registration Request').fill('test');
await page.getByRole('button', { name: 'Register' }).click();
await expect(
page.getByRole('alert').getByText('Error', { exact: true }),
).toBeVisible();
await page.getByRole('button', { name: 'Dismiss' }).click();
});
// Try using an invalid worker token. Expect an error
await page.getByLabel('Worker Auth Registration Request').fill('test');
await page.getByRole('button', { name: 'Register' }).click();
await expect(
page.getByRole('alert').getByText('Error', { exact: true }),
).toBeVisible();
await page.getByRole('button', { name: 'Dismiss' }).click();
},
);
+160 -152
View File
@@ -9,177 +9,185 @@ import { customAlphabet } from 'nanoid';
import { WorkersPage } from '../pages/workers.js';
test('Worker Tags @ce @ent @aws @docker', async ({ page }) => {
const nanoid = customAlphabet('abcdefghijklmnopqrstuvwxyz', 10);
test(
'Worker Tags',
{ tag: ['@ce', '@ent', '@aws', '@docker'] },
async ({ page }) => {
const nanoid = customAlphabet('abcdefghijklmnopqrstuvwxyz', 10);
await page.goto('/');
await page
.getByRole('navigation', { name: 'General' })
.getByRole('link', { name: 'Workers' })
.click();
await expect(
page.getByRole('navigation', { name: 'breadcrumbs' }).getByText('Workers'),
).toBeVisible();
await page.goto('/');
await page
.getByRole('navigation', { name: 'General' })
.getByRole('link', { name: 'Workers' })
.click();
await expect(
page
.getByRole('navigation', { name: 'breadcrumbs' })
.getByText('Workers'),
).toBeVisible();
// View tags from worker list page
const workerListHeadersCount = await page
.getByRole('table')
.getByRole('columnheader')
.count();
let workerListWorkerIndex;
let workerListTagIndex;
for (let i = 0; i < workerListHeadersCount; i++) {
const header = await page
// View tags from worker list page
const workerListHeadersCount = await page
.getByRole('table')
.getByRole('columnheader')
.nth(i)
.innerText();
if (header === 'Worker') {
workerListWorkerIndex = i;
} else if (header === 'Tags') {
workerListTagIndex = i;
.count();
let workerListWorkerIndex;
let workerListTagIndex;
for (let i = 0; i < workerListHeadersCount; i++) {
const header = await page
.getByRole('table')
.getByRole('columnheader')
.nth(i)
.innerText();
if (header === 'Worker') {
workerListWorkerIndex = i;
} else if (header === 'Tags') {
workerListTagIndex = i;
}
}
}
await page
.getByRole('table')
.getByRole('row')
.nth(1)
.getByRole('cell')
.nth(workerListTagIndex)
.getByRole('button')
.click();
// Check that dialog shows a config tag
const dialogHeadersCount = await page
.getByRole('dialog')
.getByRole('table')
.getByRole('columnheader')
.count();
let dialogTypeIndex;
for (let i = 0; i < dialogHeadersCount; i++) {
const header = await page
.getByRole('dialog')
.getByRole('table')
.getByRole('columnheader')
.nth(i)
.innerText();
if (header === 'Type') {
dialogTypeIndex = i;
}
}
await expect(
page
.getByRole('dialog')
await page
.getByRole('table')
.getByRole('row')
.nth(1)
.getByRole('cell')
.nth(dialogTypeIndex),
).toHaveText('config');
await page
.getByRole('dialog')
.getByRole('button', { name: 'Dismiss' })
.click();
.nth(workerListTagIndex)
.getByRole('button')
.click();
// Go to worker details and create a new tag
await page
.getByRole('table')
.getByRole('row')
.nth(1)
.getByRole('cell')
.nth(workerListWorkerIndex)
.getByRole('link')
.click();
const workersPage = new WorkersPage(page);
const tagKey = nanoid();
const tagValue = nanoid();
await workersPage.createNewTag(tagKey, tagValue);
// Check tag in worker dialog
await page
.getByRole('navigation', { name: 'General' })
.getByRole('link', { name: 'Workers' })
.click();
await expect(
page.getByRole('navigation', { name: 'breadcrumbs' }).getByText('Workers'),
).toBeVisible();
await page
.getByRole('table')
.getByRole('row')
.nth(1)
.getByRole('cell')
.nth(workerListTagIndex)
.getByRole('button')
.click();
await expect(
page
// Check that dialog shows a config tag
const dialogHeadersCount = await page
.getByRole('dialog')
.getByRole('table')
.getByRole('cell', { name: tagKey + ' = ' + tagValue }),
).toBeVisible();
await page
.getByRole('dialog')
.getByRole('button', { name: 'Dismiss' })
.click();
// Go to worker details page
await page
.getByRole('table')
.getByRole('row')
.nth(1)
.getByRole('cell')
.nth(workerListWorkerIndex)
.getByRole('link')
.click();
await page.getByRole('link', { name: 'Tags' }).click();
const workerDetailsHeadersCount = await page
.getByRole('table')
.getByRole('columnheader')
.count();
let workerDetailsTypeIndex;
for (let i = 0; i < workerDetailsHeadersCount; i++) {
const header = await page
.getByRole('table')
.getByRole('columnheader')
.nth(i)
.innerText();
if (header === 'Type') {
workerDetailsTypeIndex = i;
.count();
let dialogTypeIndex;
for (let i = 0; i < dialogHeadersCount; i++) {
const header = await page
.getByRole('dialog')
.getByRole('table')
.getByRole('columnheader')
.nth(i)
.innerText();
if (header === 'Type') {
dialogTypeIndex = i;
}
}
}
await expect(
page
.getByRole('dialog')
.getByRole('table')
.getByRole('row')
.nth(1)
.getByRole('cell')
.nth(dialogTypeIndex),
).toHaveText('config');
await page
.getByRole('dialog')
.getByRole('button', { name: 'Dismiss' })
.click();
// Check tags in the worker details page
await expect(
page
// Go to worker details and create a new tag
await page
.getByRole('table')
.getByRole('row')
.nth(1)
.getByRole('cell')
.nth(workerDetailsTypeIndex),
).toHaveText('config');
await expect(
page
.getByRole('table')
.getByRole('cell', { name: tagKey })
.locator('..')
.getByRole('cell', { name: tagValue }),
).toBeVisible();
.nth(workerListWorkerIndex)
.getByRole('link')
.click();
const workersPage = new WorkersPage(page);
const tagKey = nanoid();
const tagValue = nanoid();
await workersPage.createNewTag(tagKey, tagValue);
// Edit the tag
const newTagKey = nanoid();
const newTagValue = nanoid();
await workersPage.editTag(tagKey, newTagKey, newTagValue);
await expect(
page
// Check tag in worker dialog
await page
.getByRole('navigation', { name: 'General' })
.getByRole('link', { name: 'Workers' })
.click();
await expect(
page
.getByRole('navigation', { name: 'breadcrumbs' })
.getByText('Workers'),
).toBeVisible();
await page
.getByRole('table')
.getByRole('cell', { name: newTagKey })
.locator('..')
.getByRole('cell', { name: newTagValue }),
).toBeVisible();
.getByRole('row')
.nth(1)
.getByRole('cell')
.nth(workerListTagIndex)
.getByRole('button')
.click();
await expect(
page
.getByRole('dialog')
.getByRole('table')
.getByRole('cell', { name: tagKey + ' = ' + tagValue }),
).toBeVisible();
await page
.getByRole('dialog')
.getByRole('button', { name: 'Dismiss' })
.click();
// Delete the tag
await workersPage.removeTag(newTagKey);
await expect(
page.getByRole('table').getByRole('cell', { name: newTagKey }),
).toBeHidden();
});
// Go to worker details page
await page
.getByRole('table')
.getByRole('row')
.nth(1)
.getByRole('cell')
.nth(workerListWorkerIndex)
.getByRole('link')
.click();
await page.getByRole('link', { name: 'Tags' }).click();
const workerDetailsHeadersCount = await page
.getByRole('table')
.getByRole('columnheader')
.count();
let workerDetailsTypeIndex;
for (let i = 0; i < workerDetailsHeadersCount; i++) {
const header = await page
.getByRole('table')
.getByRole('columnheader')
.nth(i)
.innerText();
if (header === 'Type') {
workerDetailsTypeIndex = i;
}
}
// Check tags in the worker details page
await expect(
page
.getByRole('table')
.getByRole('row')
.nth(1)
.getByRole('cell')
.nth(workerDetailsTypeIndex),
).toHaveText('config');
await expect(
page
.getByRole('table')
.getByRole('cell', { name: tagKey })
.locator('..')
.getByRole('cell', { name: tagValue }),
).toBeVisible();
// Edit the tag
const newTagKey = nanoid();
const newTagValue = nanoid();
await workersPage.editTag(tagKey, newTagKey, newTagValue);
await expect(
page
.getByRole('table')
.getByRole('cell', { name: newTagKey })
.locator('..')
.getByRole('cell', { name: newTagValue }),
).toBeVisible();
// Delete the tag
await workersPage.removeTag(newTagKey);
await expect(
page.getByRole('table').getByRole('cell', { name: newTagKey }),
).toBeHidden();
},
);
+74 -68
View File
@@ -6,76 +6,82 @@
import { test } from '../../global-setup.js';
import { expect } from '@playwright/test';
test('Create a worker @ce @docker @aws', async ({ page, browserName }) => {
test.skip(browserName === 'webkit', 'Bug in worker form on Safari');
test(
'Create a worker',
{ tag: ['@ce', '@aws', '@docker'] },
async ({ page, browserName }) => {
test.skip(browserName === 'webkit', 'Bug in worker form on Safari');
await page.goto('/');
await page
.getByRole('navigation', { name: 'General' })
.getByRole('link', { name: 'Workers' })
.click();
await page.getByRole('link', { name: 'New', exact: true }).click();
await page.goto('/');
await page
.getByRole('navigation', { name: 'General' })
.getByRole('link', { name: 'Workers' })
.click();
await page.getByRole('link', { name: 'New', exact: true }).click();
// Populate config fields
await page.getByLabel('Worker public address').fill('worker1.example.com');
await page.getByLabel('Config file path').fill('/home/ubuntu/boundary');
await page.getByLabel('Initial upstreams').fill('10.0.0.1, 10.0.0.2');
await page
.getByRole('group', { name: 'Worker Tags' })
.getByLabel('Key')
.fill('type');
await page
.getByRole('group', { name: 'Worker Tags' })
.getByLabel('Value')
.fill('downstream, pki');
await page
.getByRole('group', { name: 'Worker Tags' })
.getByRole('button', { name: 'Add' })
.click();
await page
.getByRole('group', { name: 'Worker Tags' })
.getByLabel('Key')
.last()
.fill('test');
await page
.getByRole('group', { name: 'Worker Tags' })
.getByLabel('Value')
.last()
.fill('example');
await page
.getByRole('group', { name: 'Worker Tags' })
.getByRole('button', { name: 'Add' })
.click();
// Populate config fields
await page.getByLabel('Worker public address').fill('worker1.example.com');
await page.getByLabel('Config file path').fill('/home/ubuntu/boundary');
await page.getByLabel('Initial upstreams').fill('10.0.0.1, 10.0.0.2');
await page
.getByRole('group', { name: 'Worker Tags' })
.getByLabel('Key')
.fill('type');
await page
.getByRole('group', { name: 'Worker Tags' })
.getByLabel('Value')
.fill('downstream, pki');
await page
.getByRole('group', { name: 'Worker Tags' })
.getByRole('button', { name: 'Add' })
.click();
await page
.getByRole('group', { name: 'Worker Tags' })
.getByLabel('Key')
.last()
.fill('test');
await page
.getByRole('group', { name: 'Worker Tags' })
.getByLabel('Value')
.last()
.fill('example');
await page
.getByRole('group', { name: 'Worker Tags' })
.getByRole('button', { name: 'Add' })
.click();
// Check auto-populated configs
const dirLocator = '[data-test-worker-directory]';
await expect(page.locator(dirLocator)).toContainText(
'mkdir /home/ubuntu/boundary/ ;',
);
await expect(page.locator(dirLocator)).toContainText(
'touch /home/ubuntu/boundary/pki-worker.hcl',
);
// Check auto-populated configs
const dirLocator = '[data-test-worker-directory]';
await expect(page.locator(dirLocator)).toContainText(
'mkdir /home/ubuntu/boundary/ ;',
);
await expect(page.locator(dirLocator)).toContainText(
'touch /home/ubuntu/boundary/pki-worker.hcl',
);
const configLocator = '[data-test-worker-config]';
await expect(page.locator(configLocator)).toContainText(
'public_addr = "worker1.example.com"',
);
await expect(page.locator(configLocator)).toContainText(
'auth_storage_path = "/home/ubuntu/boundary/worker1"',
);
await expect(page.locator(configLocator)).toContainText(
'initial_upstreams = ["10.0.0.1", "10.0.0.2"]',
);
await expect(page.locator(configLocator)).toContainText(
'type = ["downstream", "pki"]',
);
await expect(page.locator(configLocator)).toContainText('test = ["example"]');
const configLocator = '[data-test-worker-config]';
await expect(page.locator(configLocator)).toContainText(
'public_addr = "worker1.example.com"',
);
await expect(page.locator(configLocator)).toContainText(
'auth_storage_path = "/home/ubuntu/boundary/worker1"',
);
await expect(page.locator(configLocator)).toContainText(
'initial_upstreams = ["10.0.0.1", "10.0.0.2"]',
);
await expect(page.locator(configLocator)).toContainText(
'type = ["downstream", "pki"]',
);
await expect(page.locator(configLocator)).toContainText(
'test = ["example"]',
);
// Try using an invalid worker token. Expect an error
await page.getByLabel('Worker Auth Registration Request').fill('test');
await page.getByRole('button', { name: 'Register' }).click();
await expect(
page.getByRole('alert').getByText('Error', { exact: true }),
).toBeVisible();
await page.getByRole('button', { name: 'Dismiss' }).click();
});
// Try using an invalid worker token. Expect an error
await page.getByLabel('Worker Auth Registration Request').fill('test');
await page.getByRole('button', { name: 'Register' }).click();
await expect(
page.getByRole('alert').getByText('Error', { exact: true }),
).toBeVisible();
await page.getByRole('button', { name: 'Dismiss' }).click();
},
);