"retries": 1,
"env": {
"LOGIN_USER": "admin",
- "LOGIN_PWD": "admin"
- }
+ "LOGIN_PWD": "admin",
+ "CEPH2_URL": "http://localhost:4202/"
+ },
+ "experimentalSessionAndOrigin": true,
+ "chromeWebSecurity": false
}
mirroring.getTabText(2).should('eq', 'Ready (0)');
});
+ describe('rbd mirroring bootstrap', () => {
+ const poolName = 'rbd-mirror';
+
+ beforeEach(() => {
+ cy.login();
+ Cypress.Cookies.preserveOnce('token');
+ pools.navigateTo('create');
+ pools.create(poolName, 8, 'rbd');
+ pools.navigateTo();
+ pools.existTableCell(poolName, true);
+ mirroring.navigateTo();
+ });
+
+ it('should generate and import the bootstrap token between clusters', () => {
+ const url: string = Cypress.env('CEPH2_URL');
+ mirroring.navigateTo();
+ mirroring.generateToken(poolName);
+ cy.get('@token').then((bootstrapToken) => {
+ // pass the token to the origin as an arg
+ const args = { name: poolName, token: String(bootstrapToken) };
+
+ // login to the second ceph cluster
+ cy.ceph2Login();
+
+ // can't use any imports or functions inside the origin
+ // so writing the code to copy the token inside the origin manually
+ // rather than using a function call
+ // @ts-ignore
+ cy.origin(url, { args }, ({ name, token }: any) => {
+ // Create an rbd pool in the second cluster
+ cy.visit('#/pool/create').wait(100);
+ cy.get('input[name=name]').clear().type(name);
+ cy.get(`select[name=poolType]`).select('replicated');
+ cy.get(`select[name=poolType] option:checked`).contains('replicated');
+ cy.get('.float-left.mr-2.select-menu-edit').click();
+ cy.get('.popover-body').should('be.visible');
+ // Choose rbd as the application label
+ cy.get('.select-menu-item-content').contains('rbd').click();
+ cy.get('cd-submit-button').click();
+ cy.get('cd-pool-list').should('exist');
+
+ cy.visit('#/block/mirroring').wait(1000);
+ cy.get('.table-actions button.dropdown-toggle').first().click();
+ cy.get('[aria-label="Import Bootstrap Token"]').click();
+ cy.get('cd-bootstrap-import-modal').within(() => {
+ cy.get(`label[for=${name}]`).click();
+ cy.get('textarea[id=token]').wait(100).type(token);
+ cy.get('button[type=submit]').click();
+ });
+ });
+ });
+
+ // login again since origin removes all the cookies
+ // sessions, localStorage items etc..
+ cy.login();
+ Cypress.Cookies.preserveOnce('token');
+ mirroring.navigateTo();
+ mirroring.checkPoolHealthStatus(poolName, 'OK');
+ });
+ });
+
describe('checks that edit mode functionality shows in the pools table', () => {
const poolName = 'mirroring_test';
export class MirroringPageHelper extends PageHelper {
pages = pages;
+ poolsColumnIndex = {
+ name: 1,
+ health: 6
+ };
+
/**
* Goes to the mirroring page and edits a pool in the Pool table. Clicks on the
* pool and chooses an option (either pool, image, or disabled)
// unselect the pool in the table
this.getFirstTableCell(name).click();
}
+
+ @PageHelper.restrictTo(pages.index.url)
+ generateToken(poolName: string) {
+ cy.get('[aria-label="Create Bootstrap Token"]').first().click();
+ cy.get('cd-bootstrap-create-modal').within(() => {
+ cy.get(`label[for=${poolName}]`).click();
+ cy.get('button[type=submit]').click();
+ cy.get('textarea[id=token]').wait(200).invoke('val').as('token');
+ cy.get('[aria-label="Back"]').click();
+ });
+ }
+
+ @PageHelper.restrictTo(pages.index.url)
+ checkPoolHealthStatus(poolName: string, status: string) {
+ cy.get('cd-mirroring-pools').within(() => {
+ this.getTableCell(this.poolsColumnIndex.name, poolName)
+ .parent()
+ .find(`datatable-body-cell:nth-child(${this.poolsColumnIndex.health}) .badge`)
+ .should(($ele) => {
+ const newLabels = $ele.toArray().map((v) => v.innerText);
+ expect(newLabels).to.include(status);
+ });
+ });
+ }
}
declare global {
namespace Cypress {
interface Chainable<Subject> {
- login(): void;
+ login(username?: string, password?: string): void;
logToConsole(message: string, optional?: any): void;
text(): Chainable<string>;
+ ceph2Login(username?: string, password?: string): Chainable<any>;
}
}
}
window.localStorage.setItem('sso', auth.sso);
};
-Cypress.Commands.add('login', () => {
- const username = Cypress.env('LOGIN_USER');
- const password = Cypress.env('LOGIN_PWD');
-
- if (auth === undefined) {
- cy.request({
- method: 'POST',
- url: 'api/auth',
- headers: { Accept: CdHelperClass.cdVersionHeader('1', '0') },
- body: { username: username, password: password }
- }).then((resp) => {
- auth = resp.body;
- auth.permissions = JSON.stringify(new Permissions(auth.permissions));
- auth.pwdExpirationDate = String(auth.pwdExpirationDate);
- auth.pwdUpdateRequired = String(auth.pwdUpdateRequired);
- auth.sso = String(auth.sso);
- fillAuth();
- });
- } else {
+Cypress.Commands.add('login', (username, password) => {
+ requestAuth(username, password).then((resp) => {
+ auth = resp.body;
+ auth.permissions = JSON.stringify(new Permissions(auth.permissions));
+ auth.pwdExpirationDate = String(auth.pwdExpirationDate);
+ auth.pwdUpdateRequired = String(auth.pwdUpdateRequired);
+ auth.sso = String(auth.sso);
fillAuth();
- }
+ });
+});
+
+Cypress.Commands.add('ceph2Login', (username, password) => {
+ const url: string = Cypress.env('CEPH2_URL');
+ requestAuth(username, password, url).then((resp) => {
+ auth = resp.body;
+ auth.permissions = JSON.stringify(new Permissions(auth.permissions));
+ auth.pwdExpirationDate = String(auth.pwdExpirationDate);
+ auth.pwdUpdateRequired = String(auth.pwdUpdateRequired);
+ auth.sso = String(auth.sso);
+ const args = {
+ username: auth.username,
+ permissions: auth.permissions,
+ pwdExpirationDate: auth.pwdExpirationDate,
+ pwdUpdateRequired: auth.pwdUpdateRequired,
+ sso: auth.sso
+ };
+ // @ts-ignore
+ cy.origin(
+ url,
+ { args },
+ ({ uname, permissions, pwdExpirationDate, pwdUpdateRequired, sso }: any) => {
+ window.localStorage.setItem('dashboard_username', uname);
+ window.localStorage.setItem('dashboard_permissions', permissions);
+ window.localStorage.setItem('user_pwd_expiration_date', pwdExpirationDate);
+ window.localStorage.setItem('user_pwd_update_required', pwdUpdateRequired);
+ window.localStorage.setItem('sso', sso);
+ }
+ );
+ });
});
+function requestAuth(username: string, password: string, url = '') {
+ username = username ? username : Cypress.env('LOGIN_USER');
+ password = password ? password : Cypress.env('LOGIN_PWD');
+ return cy.request({
+ method: 'POST',
+ url: !url ? 'api/auth' : `${url}api/auth`,
+ headers: { Accept: CdHelperClass.cdVersionHeader('1', '0') },
+ body: { username: username, password: password }
+ });
+}
+
// @ts-ignore
Cypress.Commands.add('text', { prevSubject: true }, (subject: any) => {
return subject.text();
<button class="btn btn-light tc_backButton"
+ aria-label="Back"
(click)="back()"
type="button">
{{ name }}
ceph_all dashboard set-rgw-api-ssl-verify False
CYPRESS_BASE_URL=$(ceph mgr services | jq -r .dashboard)
- CEPH2_DASHBOARD_URL=$(ceph2 mgr services | jq -r .dashboard)
+ CYPRESS_CEPH2_URL=$(ceph2 mgr services | jq -r .dashboard)
+
+ # start rbd-mirror daemon in the cluster
+ KEY=$(ceph auth get client.admin --format=json | jq -r .[0].key)
+ MON_CLUSTER_1=$(grep "mon host" ${FULL_PATH_BUILD_DIR}/run/1/ceph.conf | awk '{print $4}')
+ ${FULL_PATH_BUILD_DIR}/bin/rbd-mirror --mon_host $MON_CLUSTER_1 --key $KEY -c ${FULL_PATH_BUILD_DIR}/run/1/ceph.conf &
set +x
}
}
: ${CYPRESS_BASE_URL:=''}
-: ${CEPH2_DASHBOARD_URL:=''}
+: ${CYPRESS_CEPH2_URL:=''}
: ${CYPRESS_LOGIN_PWD:=''}
: ${CYPRESS_LOGIN_USER:=''}
: ${DEVICE:="chrome"}
: ${CYPRESS_CACHE_FOLDER:="${FULL_PATH_BUILD_DIR}/src/pybind/mgr/dashboard/cypress"}
-export CYPRESS_BASE_URL CYPRESS_CACHE_FOLDER CYPRESS_LOGIN_USER CYPRESS_LOGIN_PWD NO_COLOR CEPH2_DASHBOARD_URL
+export CYPRESS_BASE_URL CYPRESS_CACHE_FOLDER CYPRESS_LOGIN_USER CYPRESS_LOGIN_PWD NO_COLOR CYPRESS_CEPH2_URL
check_device_available
--env CYPRESS_BASE_URL \
--env CYPRESS_LOGIN_USER \
--env CYPRESS_LOGIN_PWD \
- --env CEPH2_DASHBOARD_URL \
+ --env CYPRESS_CEPH2_URL \
--name=e2e \
--network=host \
cypress/included:${CYPRESS_VERSION} || failed=1