Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

e2e test that creates GKE cluster with default settings #12934

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion cypress.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,8 @@ export default defineConfig({
azureClientId: process.env.AZURE_CLIENT_ID,
azureClientSecret: process.env.AZURE_CLIENT_SECRET,
customNodeIp: process.env.CUSTOM_NODE_IP,
customNodeKey: process.env.CUSTOM_NODE_KEY
customNodeKey: process.env.CUSTOM_NODE_KEY,
gkeServiceAccount: process.env.GKE_SERVICE_ACCOUNT,
},
e2e: {
fixturesFolder: 'cypress/e2e/blueprints',
Expand Down
12 changes: 12 additions & 0 deletions cypress/e2e/po/components/button-file-selector.po.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import ComponentPo from '@/cypress/e2e/po/components/component.po';

export default class ButtonFileSelectorPo extends ComponentPo {
/**
* Returns a file-selector button
* @param id
* @returns
*/
static readFromFileButton(): Cypress.Chainable {
return cy.getId('file-selector__uploader-button');
}
}
18 changes: 18 additions & 0 deletions cypress/e2e/po/edit/cloud-credentials-gke.po.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import LabeledInputPo from '@/cypress/e2e/po/components/labeled-input.po';
import ButtonFileSelectorPo from '@/cypress/e2e/po/components/button-file-selector.po';
import BaseCloudCredentialsPo from '@/cypress/e2e/po/edit/base-cloud-credentials.po';
import AsyncButtonPo from '@/cypress/e2e/po/components/async-button.po';

export default class GKECloudCredentialsCreateEditPo extends BaseCloudCredentialsPo {
serviceAccount(): LabeledInputPo {
return LabeledInputPo.byLabel(this.self(), 'Service Account');
}

readFromFile(): Cypress.Chainable {
return ButtonFileSelectorPo.readFromFileButton().click();
}

authenticateButton() {
return new AsyncButtonPo('[data-testid="action-button-async-button"]', this.self());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import PagePo from '@/cypress/e2e/po/pages/page.po';
import ClusterManagerCreatePagePo from '@/cypress/e2e/po/edit/provisioning.cattle.io.cluster/create/cluster-create.po';
import LabeledInputPo from '@/cypress/e2e/po/components/labeled-input.po';
import LabeledSelectPo from '@/cypress/e2e/po/components/labeled-select.po';
import GKECloudCredentialsCreateEditPo from '@/cypress/e2e/po/edit/cloud-credentials-gke.po';
import AsyncButtonPo from '@/cypress/e2e/po/components/async-button.po';

/**
* Create page for a GKE cluster
*/
export default class ClusterManagerCreateGKEPagePo extends ClusterManagerCreatePagePo {
static url(clusterId: string) {
return `${ ClusterManagerCreatePagePo.url(clusterId) }/create?type=googlegke`;
}

static goTo(clusterId: string): Cypress.Chainable<Cypress.AUTWindow> {
return PagePo.goTo(ClusterManagerCreateGKEPagePo.url(clusterId));
}

goToGKEClusterCreation(clusterId: string): Cypress.Chainable<Cypress.AUTWindow> {
return PagePo.goTo(`${ ClusterManagerCreatePagePo.url(clusterId) }?type=googlegke`);
}

cloudCredentialsForm(): GKECloudCredentialsCreateEditPo {
return new GKECloudCredentialsCreateEditPo();
}

authProjectId(): LabeledInputPo {
return LabeledInputPo.byLabel(this.self(), 'Google Project ID');
}

saveCreateGkeCluster(): AsyncButtonPo {
return new AsyncButtonPo('[data-testid="form-save"]', this.self());
}

static getGkeVersionSelect() {
return new LabeledSelectPo('[data-testid="gke-version-select"]');
}

static getGkeZoneSelect() {
return new LabeledSelectPo('[data-testid="gke-zone-select"]');
}

getClusterName() {
return new LabeledInputPo('[data-testid="gke-cluster-name"]');
}

getClusterDescription() {
return new LabeledInputPo('[data-testid="gke-cluster-description"]');
}
}
139 changes: 139 additions & 0 deletions cypress/e2e/tests/pages/manager/gke-cluster-provisioning.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
import HomePagePo from '@/cypress/e2e/po/pages/home.po';
import ClusterManagerListPagePo from '@/cypress/e2e/po/pages/cluster-manager/cluster-manager-list.po';
import LoadingPo from '@/cypress/e2e/po/components/loading.po';
import ClusterManagerCreateGKEPagePo from '@/cypress/e2e/po/edit/provisioning.cattle.io.cluster/create/cluster-create-gke.po';
import { DEFAULT_GCP_ZONE } from '@/pkg/gke/util/gcp';

/******
* Running this test will delete all GKE cloud credentials from the target cluster
******/

// will only run this in jenkins pipeline where cloud credentials are stored
describe('Deploy GKE cluster with default settings', { tags: ['@manager', '@adminUser', '@standardUser', '@jenkins'] }, () => {
const clusterList = new ClusterManagerListPagePo();
const loadingPo = new LoadingPo('.loading-indicator');

let cloudcredentialId = '';
const gkeDefaultZone = 'us-central1-c';
let gkeVersion = '';
let clusterId = '';
let clusterDescription = '';
const gkeProjectId = JSON.parse(Cypress.env('gkeServiceAccount')).project_id;

before(() => {
cy.login();
HomePagePo.goTo();

// clean up GKE cloud credentials
cy.getRancherResource('v3', 'cloudcredentials', null, null).then((resp: Cypress.Response<any>) => {
const body = resp.body;

if (body.pagination['total'] > 0) {
body.data.forEach((item: any) => {
if (item.googlecredentialConfig) {
const id = item.id;

cy.deleteRancherResource('v3', 'cloudcredentials', id);
IsaSih marked this conversation as resolved.
Show resolved Hide resolved
} else {
cy.log('There are no existing GKE cloud credentials to delete');
}
});
}
});
});

beforeEach(() => {
cy.createE2EResourceName('gkecluster').as('gkeClusterName');
cy.createE2EResourceName('gkecloudcredential').as('gkeCloudCredentialName');
});

it('Successfully create GKE cluster with default settings', function() {
const createGKEClusterPage = new ClusterManagerCreateGKEPagePo();
const cloudCredForm = createGKEClusterPage.cloudCredentialsForm();

// Select GKE and create GKE cluster page
ClusterManagerListPagePo.navTo();
clusterList.waitForPage();
clusterList.createCluster();
createGKEClusterPage.selectKubeProvider(2);
loadingPo.checkNotExists();
createGKEClusterPage.rke2PageTitle().should('include', 'Create Google GKE');
createGKEClusterPage.waitForPage('type=googlegke&rkeType=rke2');

// create GKE cloud credential
cloudCredForm.saveButton().expectToBeDisabled();
cloudCredForm.nameNsDescription().name().set(this.gkeCloudCredentialName);
cloudCredForm.serviceAccount().set(Cypress.env('gkeServiceAccount'));
cloudCredForm.saveButton().expectToBeEnabled();
cy.intercept('GET', '/v1/management.cattle.io.users?exclude=metadata.managedFields').as('pageLoad');
cloudCredForm.saveCreateForm().cruResource().saveAndWaitForRequests('POST', '/v3/cloudcredentials').then((req) => {
expect(req.response?.statusCode).to.equal(201);
cloudcredentialId = req.response?.body.id.replace(':', '%3A');
IsaSih marked this conversation as resolved.
Show resolved Hide resolved

// Authenticate GKE credential by providing the Project ID
createGKEClusterPage.waitForPage('type=googlegke&rkeType=rke2');
createGKEClusterPage.authProjectId().set( gkeProjectId );
cy.intercept('POST', `/meta/gkeVersions?cloudCredentialId=${ cloudcredentialId }&projectId=${ gkeProjectId }&zone=${ gkeDefaultZone }`).as('getGKEVersions');
cloudCredForm.authenticateButton().click();
cy.wait('@pageLoad').its('response.statusCode').should('eq', 200);
loadingPo.checkNotExists();

// Verify that gke-zone-select dropdown is set to the default zone
createGKEClusterPage.waitForPage('type=googlegke&rkeType=rke2');
ClusterManagerCreateGKEPagePo.getGkeZoneSelect().checkOptionSelected(DEFAULT_GCP_ZONE);

// Get latest GKE kubernetes version and verify that gke-version-select dropdown is set to the default version as defined by versionOptions(); in Config.vue
cy.wait('@getGKEVersions').then(({ response }) => {
expect(response.statusCode).to.eq(200);
gkeVersion = response.body.validMasterVersions[0];
cy.wrap(gkeVersion).as('gkeVersion');
ClusterManagerCreateGKEPagePo.getGkeVersionSelect().checkOptionSelected(gkeVersion);
});

// Set the cluster name and description in the Create GKE Page
createGKEClusterPage.getClusterName().set(this.gkeClusterName);
clusterDescription = `${ this.gkeClusterName }-description`;
createGKEClusterPage.getClusterDescription().set(clusterDescription);
});

// Create GKE Cluster and verify that the properties posted to the server match the expected settings
cy.intercept('POST', 'v3/clusters').as('createGKECluster');

createGKEClusterPage.saveCreateGkeCluster().click();
cy.wait('@createGKECluster').then(({ response }) => {
expect(response?.statusCode).to.eq(201);
expect(response?.body).to.have.property('baseType', 'cluster');
expect(response?.body.gkeConfig).to.have.property('clusterName', this.gkeClusterName);
expect(response?.body).to.have.property('description', clusterDescription);
expect(response?.body.gkeConfig).to.have.property('kubernetesVersion').contains(gkeVersion);
clusterId = response?.body.id;
});

// Verify that the GKE created cluster is listed in the clusters list and has the Provisioning status
clusterList.waitForPage();
clusterList.list().state(this.gkeClusterName).should('contain.text', 'Provisioning');
});

after('clean up', () => {
// delete cluster
cy.deleteRancherResource('v1', 'provisioning.cattle.io.clusters', `fleet-default/${ clusterId }`, false);

// clean up GKE cloud credentials
cy.getRancherResource('v3', 'cloudcredentials', null, null).then((resp: Cypress.Response<any>) => {
const body = resp.body;

if (body.pagination['total'] > 0) {
body.data.forEach((item: any) => {
if (item.googlecredentialConfig) {
const id = item.id;

cy.deleteRancherResource('v3', 'cloudcredentials', id);
} else {
cy.log('There are no existing GKE cloud credentials to delete');
}
});
}
});
}
);
});
8 changes: 6 additions & 2 deletions pkg/gke/components/CruGKE.vue
Original file line number Diff line number Diff line change
Expand Up @@ -697,7 +697,9 @@ export default defineComponent({
<div
class="row mb-10"
>
<div class="col span-6">
<div
class="col span-6"
>
<LabeledInput
:value="normanCluster.name"
:mode="mode"
Expand All @@ -708,7 +710,9 @@ export default defineComponent({
@update:value="setClusterName"
/>
</div>
<div class="col span-6">
<div
class="col span-6"
>
<LabeledInput
:value="normanCluster.description"
:mode="mode"
Expand Down
Loading