Skip to content

Commit

Permalink
kubevirt: introduce init function to K8sWrappers
Browse files Browse the repository at this point in the history
- add k8sWrapperCreate method to EnhancedK8sMethods
  • Loading branch information
suomiy committed Mar 10, 2020
1 parent 1e00af0 commit 314004c
Show file tree
Hide file tree
Showing 15 changed files with 158 additions and 52 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ const CreateVMTemplateYAMLConnected = connectToPlural(
.catch(() => {
setDefaultTemplate(
new VMTemplateWrapper(safeLoad(VMTemplateYAMLTemplates.getIn(['vm-template'])))
.setModel(TemplateModel)
.init()
.setNamespace(match.params.ns || 'default')
.asResource(),
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ const VMCreateYAMLLConnected = connectToPlural(
.catch(() => {
setDefaultVM(
new VMWrapper(safeLoad(VirtualMachineYAMLTemplates.getIn(['default'])))
.setModel(VirtualMachineModel)
.init()
.setNamespace(match.params.ns || 'default')
.asResource(),
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,14 +62,14 @@ const expectHistory = (history, expectedHistory) => {

describe('enhancedK8sMethods.js', () => {
const testVM = new VMWrapper()
.setModel(VirtualMachineModel)
.init()
.setName('testVM')
.setNamespace('default')
.setMemory('5', 'Gi')
.asResource();

const otherTestVM = new VMWrapper()
.setModel(VirtualMachineModel)
.init()
.setName('otherVM')
.setNamespace('kube')
.setMemory('1', 'Mi')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import {
K8sPatchError,
} from './errors';
import { HistoryItem, HistoryType } from './types';
import { Wrapper } from '../wrapper/common/wrapper';
import { K8sResourceKindMethods } from '../wrapper/types/types';

export type EnhancedOpts = {
disableHistory: boolean;
Expand Down Expand Up @@ -56,6 +58,15 @@ export class EnhancedK8sMethods {
}
};

k8sWrapperCreate = async <
U extends K8sResourceKind,
T extends Wrapper<U, T> & K8sResourceKindMethods
>(
wrapper: T,
opts?,
enhancedOpts?: EnhancedOpts,
) => this.k8sCreate(wrapper.getModel(), wrapper.asResource(), opts, enhancedOpts);

k8sCreate = async (kind: K8sKind, data: K8sResourceKind, opts?, enhancedOpts?: EnhancedOpts) => {
try {
this.registerKind(kind);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { TemplateModel } from '@console/internal/models';
import { VMSettingsField } from '../../../../components/create-vm-wizard/types';
import { getStorageClassConfigMap } from '../../config-map/storage-class';
import { asSimpleSettings } from '../../../../components/create-vm-wizard/selectors/vm-settings';
Expand All @@ -9,17 +8,16 @@ import {
TEMPLATE_TYPE_LABEL,
TEMPLATE_TYPE_VM,
} from '../../../../constants/vm';
import { DataVolumeModel, VirtualMachineModel } from '../../../../models';
import { DataVolumeWrapper } from '../../../wrapper/vm/data-volume-wrapper';
import { buildOwnerReference } from '../../../../utils';
import { VMWrapper } from '../../../wrapper/vm/vm-wrapper';
import { ProcessedTemplatesModel } from '../../../../models/models';
import { toShallowJS } from '../../../../utils/immutable';
import { iGetRelevantTemplate } from '../../../../selectors/immutable/template/combined';
import { CreateVMEnhancedParams, CreateVMParams } from './types';
import { initializeVM } from './initialize-vm';
import { getOS, initializeCommonMetadata, initializeCommonVMMetadata } from './common';
import { selectVM } from '../../../../selectors/vm-template/basic';
import { ProcessedTemplatesModel } from '../../../../models/models';

export const getInitializedVMTemplate = (params: CreateVMEnhancedParams) => {
const { vmSettings, iCommonTemplates, iUserTemplates } = params;
Expand All @@ -38,9 +36,9 @@ export const getInitializedVMTemplate = (params: CreateVMEnhancedParams) => {
return {};
}

const template = new VMTemplateWrapper(temp, true);

template.setModel(TemplateModel); // make sure api version is correct
const template = new VMTemplateWrapper(temp, true)
.init() // make sure api version is correct
.clearRuntimeMetadata();

const { storages } = initializeVM(params, template.getVM());

Expand All @@ -49,7 +47,7 @@ export const getInitializedVMTemplate = (params: CreateVMEnhancedParams) => {

export const createVMTemplate = async (params: CreateVMParams) => {
const { enhancedK8sMethods, namespace, vmSettings } = params;
const { k8sGet, k8sCreate, getActualState } = enhancedK8sMethods;
const { k8sGet, k8sWrapperCreate, getActualState } = enhancedK8sMethods;

const storageClassConfigMap = await getStorageClassConfigMap({ k8sGet });

Expand Down Expand Up @@ -84,18 +82,15 @@ export const createVMTemplate = async (params: CreateVMParams) => {

initializeCommonMetadata(combinedSimpleSettings, finalTemplate, template.asResource());

const templateResult = await k8sCreate(TemplateModel, finalTemplate.asResource());
const templateResult = await k8sWrapperCreate(finalTemplate);

if (templateResult && storages) {
for (const storage of storages.filter((s) => s.dataVolumeToCreate)) {
// eslint-disable-next-line no-await-in-loop
await enhancedK8sMethods.k8sCreate(
DataVolumeModel,
new DataVolumeWrapper(storage.dataVolumeToCreate, true)
.addOwnerReferences(
buildOwnerReference(templateResult, { blockOwnerDeletion: true, controller: true }),
)
.asResource(),
await k8sWrapperCreate(
new DataVolumeWrapper(storage.dataVolumeToCreate, true).addOwnerReferences(
buildOwnerReference(templateResult, { blockOwnerDeletion: true, controller: true }),
),
);
}
}
Expand All @@ -104,7 +99,7 @@ export const createVMTemplate = async (params: CreateVMParams) => {

export const createVM = async (params: CreateVMParams) => {
const { enhancedK8sMethods, namespace, vmSettings, openshiftFlag } = params;
const { k8sGet, k8sCreate, getActualState } = enhancedK8sMethods;
const { k8sGet, k8sCreate, k8sWrapperCreate, getActualState } = enhancedK8sMethods;

const storageClassConfigMap = await getStorageClassConfigMap({ k8sGet });
const enhancedParams = {
Expand All @@ -118,7 +113,7 @@ export const createVM = async (params: CreateVMParams) => {
};

// TODO add VMWARE import
let vm: VMWrapper;
let vmWrapper: VMWrapper;

if (openshiftFlag) {
const { template } = getInitializedVMTemplate(enhancedParams);
Expand All @@ -144,19 +139,18 @@ export const createVM = async (params: CreateVMParams) => {
{ disableHistory: true },
); // temporary

vm = new VMWrapper(selectVM(processedTemplate));
vm.setNamespace(namespace);
initializeCommonMetadata(combinedSimpleSettings, vm, template.asResource());
vmWrapper = new VMWrapper(selectVM(processedTemplate)).setNamespace(namespace);
initializeCommonMetadata(combinedSimpleSettings, vmWrapper, template.asResource());
} else {
vm = new VMWrapper()
.setModel(VirtualMachineModel)
.setNamespace(namespace)
vmWrapper = new VMWrapper()
.init({ namespace })
.setName(combinedSimpleSettings[VMSettingsField.NAME]);
initializeCommonMetadata(combinedSimpleSettings, vm);
initializeVM(enhancedParams, vm);
initializeCommonMetadata(combinedSimpleSettings, vmWrapper);
initializeVM(enhancedParams, vmWrapper);
}
initializeCommonVMMetadata(combinedSimpleSettings, vm);
await k8sCreate(VirtualMachineModel, vm.asResource());
initializeCommonVMMetadata(combinedSimpleSettings, vmWrapper);

await k8sWrapperCreate(vmWrapper);

return getActualState();
};
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
/* eslint-disable lines-between-class-members */
import { getName, hasLabel, getLabels } from '@console/shared/src';
import { apiVersionForModel, K8sKind, K8sResourceKind } from '@console/internal/module/k8s';
import { K8sKind, K8sResourceKind } from '@console/internal/module/k8s';
import { K8sResourceKindMethods } from '../types/types';
import { ObjectWithTypePropertyWrapper } from './object-with-type-property-wrapper';
import { ObjectEnum } from '../../../constants';
import { clearRuntimeMetadata, initK8sObject, K8sInitAddon } from './util/k8s-mixin';

export abstract class K8sResourceObjectWithTypePropertyWrapper<
RESOURCE extends K8sResourceKind,
Expand All @@ -12,16 +13,37 @@ export abstract class K8sResourceObjectWithTypePropertyWrapper<
SELF extends K8sResourceObjectWithTypePropertyWrapper<RESOURCE, TYPE, COMBINED_TYPE_DATA, SELF>
> extends ObjectWithTypePropertyWrapper<RESOURCE, TYPE, COMBINED_TYPE_DATA, SELF>
implements K8sResourceKindMethods {
private readonly model: K8sKind;

protected constructor(
model: K8sKind,
data?: RESOURCE | SELF,
copy = false,
typeClass: { getAll: () => TYPE[] | Readonly<TYPE[]> } = undefined,
typeDataPath: string[] = [],
) {
super(data, copy, typeClass, typeDataPath);
this.model = model;
if (!this.model) {
throw new Error('model must be defined');
}
}

init(data: K8sInitAddon = {}) {
initK8sObject(this.data, this.model, data);
return (this as any) as SELF;
}

clearRuntimeMetadata() {
clearRuntimeMetadata(this.data);
return (this as any) as SELF;
}

getModel = () => this.model;
getName = () => getName(this.data);
getLabels = (defaultValue = {}) => getLabels(this.data, defaultValue);
hasLabel = (label: string) => hasLabel(this.data, label);

setModel = (model: K8sKind) => {
this.data.kind = model.kind;
this.data.apiVersion = apiVersionForModel(model);
return (this as any) as SELF;
};

setName = (name: string) => {
this.ensurePath('metadata');
this.data.metadata.name = name;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,39 @@
/* eslint-disable lines-between-class-members */
import { getName, hasLabel, getLabels } from '@console/shared/src';
import { apiVersionForModel, K8sKind, K8sResourceKind } from '@console/internal/module/k8s';
import { K8sKind, K8sResourceKind } from '@console/internal/module/k8s';
import { Wrapper } from './wrapper';
import { K8sResourceKindMethods } from '../types/types';
import { clearRuntimeMetadata, initK8sObject, K8sInitAddon } from './util/k8s-mixin';

export abstract class K8sResourceWrapper<
RESOURCE extends K8sResourceKind,
SELF extends K8sResourceWrapper<RESOURCE, SELF>
> extends Wrapper<RESOURCE, SELF> implements K8sResourceKindMethods {
private readonly model: K8sKind;

protected constructor(model: K8sKind, data?: RESOURCE | SELF, copy = false) {
super(data, copy);
this.model = model;
if (!this.model) {
throw new Error('model must be defined');
}
}

init(data: K8sInitAddon = {}) {
initK8sObject(this.data, this.model, data);
return (this as any) as SELF;
}

clearRuntimeMetadata() {
clearRuntimeMetadata(this.data);
return (this as any) as SELF;
}

getModel = () => this.model;
getName = () => getName(this.data);
getLabels = (defaultValue = {}) => getLabels(this.data, defaultValue);
hasLabel = (label: string) => hasLabel(this.data, label);

setModel = (model: K8sKind) => {
this.data.kind = model.kind;
this.data.apiVersion = apiVersionForModel(model);
return (this as any) as SELF;
};

setName = (name: string) => {
this.ensurePath('metadata');
this.data.metadata.name = name;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { apiVersionForModel, K8sKind, K8sResourceCommon } from '@console/internal/module/k8s';
import { ensurePath } from '../../utils/utils';
import { omitEmpty } from '../../../../utils/common';

export type K8sInitAddon = {
name?: string;
generateName?: string;
namespace?: string;
labels?: { [k: string]: string };
annotations?: { [k: string]: string };
};
export const initK8sObject = (
base: K8sResourceCommon,
model: K8sKind,
{ name, generateName, namespace, labels, annotations }: K8sInitAddon = {},
) => {
if (base && model) {
base.kind = model.kind;
base.apiVersion = apiVersionForModel(model);

ensurePath(base, 'metadata');
const { metadata } = base;
if (name) {
metadata.name = name;
metadata.generateName = undefined;
} else if (generateName) {
metadata.name = undefined;
metadata.generateName = generateName;
}
metadata.namespace = namespace || metadata.namespace;
metadata.labels = labels || metadata.labels;
metadata.annotations = annotations || metadata.annotations;
omitEmpty(metadata, true);
}
};

export const clearRuntimeMetadata = (base: K8sResourceCommon) => {
if (base && base.metadata) {
const { metadata } = base;
delete metadata.selfLink;
delete metadata.resourceVersion;
delete metadata.uid;
delete metadata.creationTimestamp;
delete metadata.deletionTimestamp;
delete metadata.generation;
}
};
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ export abstract class Wrapper<RESOURCE extends {}, SELF extends Wrapper<RESOURCE
return (this as any) as SELF;
}

omitEmpty = (path?: string[] | string, justUndefined = true) => {
omitEmpty(path ? this.getIn(path) : this.data, justUndefined);
return (this as any) as SELF;
};

protected get = (key: string) => (this.data && key ? this.data[key] : null);

protected getIn = (path: string[] | string) =>
Expand All @@ -42,9 +47,4 @@ export abstract class Wrapper<RESOURCE extends {}, SELF extends Wrapper<RESOURCE
}
return (this as any) as SELF;
};

protected omitEmpty = (path?: string[] | string, justUndefined = true) => {
omitEmpty(path ? this.getIn(path) : this.data, justUndefined);
return (this as any) as SELF;
};
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { K8sResourceKind } from '@console/internal/module/k8s';
import { K8sKind, K8sResourceKind } from '@console/internal/module/k8s';

export interface K8sResourceKindMethods {
getModel: () => K8sKind;
getName: () => string;
getLabels: (
defaultValue: K8sResourceKind['metadata']['labels'],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ export class DataVolumeWrapper extends K8sResourceObjectWithTypePropertyWrapper<
};

constructor(dataVolumeTemplate?: V1alpha1DataVolume | DataVolumeWrapper, copy = false) {
super(dataVolumeTemplate, copy, DataVolumeSourceType, ['spec', 'source']);
super(DataVolumeModel, dataVolumeTemplate, copy, DataVolumeSourceType, ['spec', 'source']);
}

getStorageClassName = () => getDataVolumeStorageClassName(this.data as any);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export class DiskWrapper extends ObjectWithTypePropertyWrapper<
CombinedTypeData,
DiskWrapper
> {
// TODO deprecate all initializeFromSimpleData in favor of init
static initializeFromSimpleData = ({
name,
type,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ export class VMTemplateWrapper extends K8sResourceWrapper<TemplateKind, VMTempla
});
};

constructor(template?: TemplateKind | VMTemplateWrapper | any, copy = false) {
super(TemplateModel, template, copy);
}

getOperatingSystem = () => findKeySuffixValue(this.getLabels(), TEMPLATE_OS_LABEL);
getWorkloadProfile = () => findKeySuffixValue(this.getLabels(), TEMPLATE_WORKLOAD_LABEL);
getFlavor = () => findKeySuffixValue(this.getLabels(), TEMPLATE_FLAVOR_LABEL);
Expand Down

0 comments on commit 314004c

Please sign in to comment.