Skip to content

Commit

Permalink
Refactor VM Configs
Browse files Browse the repository at this point in the history
  • Loading branch information
Radim Hrazdil committed Jul 10, 2020
1 parent 138b518 commit 2babadf
Show file tree
Hide file tree
Showing 69 changed files with 1,625 additions and 1,173 deletions.
6 changes: 6 additions & 0 deletions frontend/packages/console-shared/src/test-utils/utils.ts
Expand Up @@ -149,13 +149,19 @@ export const waitForCount = (elementArrayFinder: any, targetCount: number) => {

export const waitForStringInElement = (elem: any, needle: string) => {
return async () => {
if (!(await elem.isPresent())) {
return false;
}
const content = await elem.getText();
return content.includes(needle);
};
};

export const waitForStringNotInElement = (elem: any, needle: string) => {
return async () => {
if (!(await elem.isPresent())) {
return false;
}
const content = await elem.getText();
return !content.includes(needle);
};
Expand Down
@@ -1,33 +1,41 @@
import { browser, ExpectedConditions as until } from 'protractor';
import { click, fillInput } from '@console/shared/src/test-utils/utils';
import { selectOptionByText } from '../utils/utils';
import { PAGE_LOAD_TIMEOUT_SECS } from '../utils/consts';
import * as cloneDialogView from '../../views/dialogs/cloneVirtualMachineDialog.view';
import { PAGE_LOAD_TIMEOUT_SECS, SEC } from '../utils/constants/common';
import * as view from '../../views/dialogs/cloneVirtualMachineDialog.view';

export class CloneVirtualMachineDialog {
async close() {
await click(cloneDialogView.cancelButton);
await browser.wait(until.invisibilityOf(cloneDialogView.modalDialog), PAGE_LOAD_TIMEOUT_SECS);
await click(view.cancelButton);
await browser.wait(until.invisibilityOf(view.modalDialog), PAGE_LOAD_TIMEOUT_SECS);
}

async fillName(name: string) {
await fillInput(cloneDialogView.nameInput, name);
await fillInput(view.nameInput, name);
}

async fillDescription(description: string) {
await fillInput(cloneDialogView.descriptionInput, description);
await fillInput(view.descriptionInput, description);
}

async selectNamespace(namespace: string) {
await selectOptionByText(cloneDialogView.namespaceSelector, namespace);
await selectOptionByText(view.namespaceSelector, namespace);
}

async startOnCreation() {
await click(cloneDialogView.startOnCreationCheckBox);
await click(view.startOnCreationCheckBox);
}

async clone() {
await click(cloneDialogView.confirmButton);
await browser.wait(until.invisibilityOf(cloneDialogView.modalDialog), PAGE_LOAD_TIMEOUT_SECS);
try {
await browser.wait(until.presenceOf(view.errorHelper), 1 * SEC);
} catch (e) {
// error wasn't displayed, everything is OK
await click(view.confirmButton);
await browser.wait(until.invisibilityOf(view.modalDialog), PAGE_LOAD_TIMEOUT_SECS);
return;
}
// An error is displayed
throw new Error(await view.errorHelper.getText());
}
}
Expand Up @@ -2,8 +2,8 @@ import { click, fillInput } from '@console/shared/src/test-utils/utils';
import { selectOptionByText, getSelectedOptionText, getSelectOptions } from '../utils/utils';
import * as view from '../../views/dialogs/diskDialog.view';
import { modalSubmitButton, saveButton } from '../../views/kubevirtUIResource.view';
import { StorageResource, DiskSourceConfig } from '../utils/types';
import { diskAccessMode, DISK_SOURCE } from '../utils/consts';
import { Disk, DiskSourceConfig } from '../types/types';
import { diskAccessMode, DISK_SOURCE } from '../utils/constants/vm';
import { waitForNoLoaders, modalCancelButton } from '../../views/wizard.view';
import { browser, ExpectedConditions as until, $ } from 'protractor';

Expand Down Expand Up @@ -95,7 +95,7 @@ export class DiskDialog {
return getSelectOptions(view.diskInterface);
}

async create(disk: StorageResource) {
async create(disk: Disk) {
await waitForNoLoaders();
await selectOptionByText(view.diskSource, disk.source || DISK_SOURCE.Blank);
if (this.sourceMethods[disk.source] !== undefined) {
Expand All @@ -114,7 +114,7 @@ export class DiskDialog {
await waitForNoLoaders();
}

async edit(disk: StorageResource) {
async edit(disk: Disk) {
await this.fillName(disk.name);
await this.selectInterface(disk.interface);
await this.selectStorageClass(disk.storageClass);
Expand Down
@@ -1,7 +1,7 @@
import { click, fillInput } from '@console/shared/src/test-utils/utils';
import * as view from '../../views/dialogs/networkInterface.view';
import { selectOptionByText, getSelectOptions } from '../utils/utils';
import { NetworkResource } from '../utils/types';
import { Network } from '../types/types';
import { modalSubmitButton, saveButton } from '../../views/kubevirtUIResource.view';
import { waitForNoLoaders } from '../../views/wizard.view';

Expand Down Expand Up @@ -30,7 +30,7 @@ export class NetworkInterfaceDialog {
return getSelectOptions(view.nicNetwork);
}

async create(NIC: NetworkResource) {
async create(NIC: Network) {
await waitForNoLoaders();
await this.fillName(NIC.name);
await this.selectModel(NIC.model);
Expand Down
@@ -1,8 +1,8 @@
import { browser } from 'protractor';
import { isLoaded } from '@console/internal-integration-tests/views/crud.view';
import { appHost, testName } from '@console/internal-integration-tests/protractor.conf';
import { isLoaded } from '@console/internal-integration-tests/views/crud.view';

// This is an dummy test - for development only.
// This is a dummy test - for development only.
describe('Successful example test', () => {
it('Navigate to virtualization page', async () => {
await browser.get(`${appHost}/k8s/ns/${testName}/virtualization`);
Expand Down
@@ -1,20 +1,51 @@
import { testName } from '@console/internal-integration-tests/protractor.conf';
import { CloudInitConfig, BaseVMConfig, StorageResource } from './types';
import { ConfigMapKind, SecretKind, ServiceAccountKind } from '@console/internal/module/k8s';
import { CloudInitConfig, Disk } from '../types/types';
import {
STORAGE_CLASS,
commonTemplateVersion,
NIC_MODEL,
NIC_TYPE,
DISK_INTERFACE,
KUBEVIRT_STORAGE_CLASS_DEFAULTS,
KUBEVIRT_PROJECT_NAME,
COMMON_TEMPLATES_NAMESPACE,
COMMON_TEMPLATES_REVISION,
} from '../utils/constants/common';
import {
getRandomMacAddress,
getResourceObject,
resolveStorageDataAttribute,
deepFreeze,
} from '../utils/utils';
import { Flavor, ProvisionSource } from '../utils/constants/wizard';
import {
NIC_MODEL,
NIC_TYPE,
DISK_INTERFACE,
DISK_SOURCE,
} from './consts';
import { getRandomMacAddress, getResourceObject, resolveStorageDataAttribute } from './utils';
import { Flavor, OperatingSystem, WorkloadProfile } from './constants/wizard';
import { ConfigMapKind, SecretKind, ServiceAccountKind } from '@console/internal/module/k8s/types';
DISK_DRIVE,
} from '../utils/constants/vm';

export const provisionSources = {
[ProvisionSource.URL]: {
method: ProvisionSource.URL,
source: 'https://download.cirros-cloud.net/0.4.0/cirros-0.4.0-x86_64-disk.img',
},
[ProvisionSource.CONTAINER]: {
method: ProvisionSource.CONTAINER,
source: 'kubevirt/fedora-cloud-registry-disk-demo:latest',
},
[ProvisionSource.PXE]: { method: ProvisionSource.PXE },
[ProvisionSource.DISK]: { method: ProvisionSource.DISK },
};
deepFreeze(provisionSources);

export const flavorConfigs = {
[Flavor.TINY]: { flavor: Flavor.TINY },
[Flavor.SMALL]: { flavor: Flavor.SMALL },
[Flavor.MEDIUM]: { flavor: Flavor.MEDIUM },
[Flavor.LARGE]: { flavor: Flavor.LARGE },
[Flavor.CUSTOM]: { flavor: Flavor.CUSTOM, cpu: '2', memory: '2Gi' },
};
deepFreeze(flavorConfigs);

export const multusNAD = {
apiVersion: 'k8s.cni.cncf.io/v1',
Expand All @@ -28,6 +59,7 @@ export const multusNAD = {
config: '{ "cniVersion": "0.3.1", "type": "cnv-bridge", "bridge": "testbridge", "ipam": {} }',
},
};
deepFreeze(multusNAD);

export const dataVolumeManifest = ({ name, namespace, sourceURL, accessMode, volumeMode }) => {
return {
Expand All @@ -40,7 +72,7 @@ export const dataVolumeManifest = ({ name, namespace, sourceURL, accessMode, vol
spec: {
pvc: {
accessModes: [accessMode],
dataSource: null,
dataSource: {},
resources: {
requests: {
storage: '1Gi',
Expand All @@ -58,17 +90,39 @@ export const dataVolumeManifest = ({ name, namespace, sourceURL, accessMode, vol
};
};

export const basicVMConfig: BaseVMConfig = {
operatingSystem: OperatingSystem.RHEL7,
flavorConfig: { flavor: Flavor.TINY },
workloadProfile: WorkloadProfile.DESKTOP,
sourceURL:
'http://cnv-qe-server.rhevdev.lab.eng.rdu2.redhat.com/files/files-https/cirros/cirros-qcow2.img',
sourceContainer: 'kubevirt/cirros-registry-disk-demo',
cloudInitScript: `#cloud-config\nuser: cloud-user\npassword: atomic\nchpasswd: {expire: False}\nhostname: vm-${testName}`,
export const kubevirtStorage = getResourceObject(
KUBEVIRT_STORAGE_CLASS_DEFAULTS,
KUBEVIRT_PROJECT_NAME,
'configMap',
);

export const getTestDataVolume = () =>
dataVolumeManifest({
name: `testdv-${testName}`,
namespace: testName,
sourceURL: provisionSources.URL.source,
accessMode: resolveStorageDataAttribute(kubevirtStorage, 'accessMode'),
volumeMode: resolveStorageDataAttribute(kubevirtStorage, 'volumeMode'),
});

export const getDiskToCloneFrom = (): Disk => {
const testDV = getTestDataVolume();
return {
name: testDV.metadata.name,
size: testDV.spec.pvc.resources.requests.storage.slice(0, -2),
drive: DISK_DRIVE.Disk,
interface: DISK_INTERFACE.VirtIO,
bootable: true,
storageClass: testDV.spec.pvc.storageClassName,
sourceConfig: {
PVCName: testDV.metadata.name,
PVCNamespace: testName,
},
source: DISK_SOURCE.AttachClonedDisk,
};
};
Object.freeze(basicVMConfig.flavorConfig);
Object.freeze(basicVMConfig);

export const cloudInitScript = `#cloud-config\nuser: cloud-user\npassword: atomic\nchpasswd: {expire: False}\nhostname: vm-${testName}`;

export const defaultWizardPodNetworkingInterface = {
name: 'nic-0',
Expand All @@ -77,6 +131,7 @@ export const defaultWizardPodNetworkingInterface = {
type: NIC_TYPE.masquerade,
network: 'Pod Networking',
};
deepFreeze(defaultWizardPodNetworkingInterface);

export const defaultYAMLPodNetworkingInterface = {
name: 'default',
Expand All @@ -85,17 +140,7 @@ export const defaultYAMLPodNetworkingInterface = {
type: NIC_TYPE.masquerade,
network: 'Pod Networking',
};

// Fake windows machine, still cirros in the heart
export const windowsVMConfig: BaseVMConfig = {
operatingSystem: OperatingSystem.WINDOWS_10,
flavorConfig: { flavor: Flavor.MEDIUM },
workloadProfile: WorkloadProfile.DESKTOP,
sourceURL:
'http://cnv-qe-server.rhevdev.lab.eng.rdu2.redhat.com/files/files-https/cirros/cirros-qcow2.img',
sourceContainer: 'kubevirt/cirros-registry-disk-demo',
cloudInitScript: `#cloud-config\nuser: cloud-user\npassword: atomic\nchpasswd: {expire: False}\nhostname: vm-${testName}`, // reusing cirros
};
deepFreeze(defaultYAMLPodNetworkingInterface);

export const multusNetworkInterface = {
name: `nic1-${testName.slice(-5)}`,
Expand All @@ -104,35 +149,51 @@ export const multusNetworkInterface = {
type: NIC_TYPE.bridge,
network: multusNAD.metadata.name,
};
deepFreeze(multusNetworkInterface);

export const rootDisk: StorageResource = {
export const rootDisk: Disk = {
name: 'rootdisk',
size: '1',
drive: DISK_DRIVE.Disk,
bootable: true,
interface: DISK_INTERFACE.VirtIO,
storageClass: `${STORAGE_CLASS}`,
};
deepFreeze(rootDisk);

export const cdGuestTools: StorageResource = {
export const containerRootDisk: Disk = {
name: 'rootdisk',
drive: DISK_DRIVE.Disk,
bootable: true,
interface: DISK_INTERFACE.VirtIO,
};
deepFreeze(containerRootDisk);

export const cdGuestTools: Disk = {
source: DISK_SOURCE.Container,
interface: DISK_INTERFACE.sata,
drive: DISK_DRIVE.CDROM,
storageClass: `${STORAGE_CLASS}`,
sourceConfig: {
container: 'kubevirt/virtio-container-disk',
},
};
deepFreeze(cdGuestTools);

export const hddDisk: StorageResource = {
export const hddDisk: Disk = {
name: `disk-${testName.slice(-5)}`,
size: '1',
drive: DISK_DRIVE.Disk,
interface: DISK_INTERFACE.VirtIO,
storageClass: `${STORAGE_CLASS}`,
};
deepFreeze(hddDisk);

export const cloudInitCustomScriptConfig: CloudInitConfig = {
useCloudInit: true,
useCustomScript: true,
customScript: basicVMConfig.cloudInitScript,
customScript: cloudInitScript,
};
deepFreeze(cloudInitCustomScriptConfig);

export const getConfigMap = (namespace: string, name: string): ConfigMapKind => {
return {
Expand Down Expand Up @@ -197,7 +258,7 @@ function getMetadata(
app: vmName,
'flavor.template.kubevirt.io/tiny': 'true',
'os.template.kubevirt.io/rhel7.8': 'true',
'vm.kubevirt.io/template': `rhel7-desktop-${basicVMConfig.flavorConfig.flavor.toLowerCase()}-${commonTemplateVersion()}`,
'vm.kubevirt.io/template': `rhel7-desktop-${Flavor.TINY.toLowerCase()}-${commonTemplateVersion()}`,
'vm.kubevirt.io/template.namespace': COMMON_TEMPLATES_NAMESPACE,
'vm.kubevirt.io/template.revision': COMMON_TEMPLATES_REVISION,
'vm.kubevirt.io/template.version': commonTemplateVersion(),
Expand All @@ -206,23 +267,18 @@ function getMetadata(
};
const urlSource = {
http: {
url: basicVMConfig.sourceURL,
url: provisionSources.URL.source,
},
};
const kubevirtStorage = getResourceObject(
KUBEVIRT_STORAGE_CLASS_DEFAULTS,
KUBEVIRT_PROJECT_NAME,
'configMap',
);
const dataVolumeTemplate = {
apiVersion: 'cdi.kubevirt.io/v1alpha1',
metadata: {
name: `${metadata.name}-rootdisk`,
},
spec: {
pvc: {
accessModes: [resolveStorageDataAttribute(kubevirtStorage, 'accessMode')],
volumeMode: resolveStorageDataAttribute(kubevirtStorage, 'volumeMode'),
dataSource: null,
resources: {
requests: {
storage: '1Gi',
Expand All @@ -241,7 +297,7 @@ function getMetadata(
};
const containerDisk = {
containerDisk: {
image: basicVMConfig.sourceContainer,
image: provisionSources.Container.source,
},
name: 'rootdisk',
};
Expand Down Expand Up @@ -387,7 +443,7 @@ export function getVMManifest(
metadata: {
labels: {
'kubevirt.io/domain': metadata.name,
'kubevirt.io/size': basicVMConfig.flavorConfig.flavor,
'kubevirt.io/size': Flavor.TINY,
'vm.kubevirt.io/name': metadata.name,
},
},
Expand All @@ -413,3 +469,4 @@ export const datavolumeClonerClusterRole = {
},
],
};
deepFreeze(datavolumeClonerClusterRole);

0 comments on commit 2babadf

Please sign in to comment.