Skip to content

Commit

Permalink
add encrypt image and decrypt image actions
Browse files Browse the repository at this point in the history
Signed-off-by: andy.lee <andy.lee@suse.com>
  • Loading branch information
a110605 committed Sep 24, 2024
1 parent f50a27f commit cef84ef
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 10 deletions.
58 changes: 54 additions & 4 deletions pkg/harvester/detail/harvesterhci.io.virtualmachineimage/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
import CopyToClipboardText from '@shell/components/CopyToClipboardText';
import LabelValue from '@shell/components/LabelValue';
import { DESCRIPTION } from '@shell/config/labels-annotations';
import { HCI } from '@pkg/harvester/config/labels-annotations';
import { HCI as HCI_ANNOTATIONS } from '@pkg/harvester/config/labels-annotations';
import { HCI } from '../../types';
import Tabbed from '@shell/components/Tabbed';
import Tab from '@shell/components/Tabbed/Tab';
import { findBy } from '@shell/utils/array';
Expand Down Expand Up @@ -31,10 +32,14 @@ export default {
const inStore = this.$store.getters['currentProduct'].inStore;
this.secrets = await this.$store.dispatch(`${ inStore }/findAll`, { type: SECRET });
this.images = await this.$store.dispatch(`${ inStore }/findAll`, { type: HCI.IMAGE });
},
data() {
return { secrets: [] };
return {
secrets: [],
images: []
};
},
computed: {
Expand Down Expand Up @@ -64,6 +69,34 @@ export default {
return this.value?.spec?.sourceType === 'upload';
},
sourceImage() {
const { sourceImageName, sourceImageNamespace } = this.value?.spec?.securityParameters || {};
if (sourceImageNamespace && sourceImageName) {
const imageId = `${ sourceImageNamespace }/${ sourceImageName }`;
return this.images.find(image => image.id === imageId);
}
return null;
},
sourceImageLink() {
return this.sourceImage?.detailLocation;
},
sourceImageId() {
if (this.sourceImage) {
return `${ this.sourceImage.namespace }/${ this.sourceImage.displayName }`;
}
return '';
},
isEncryptedOrDecrypted() {
return ['encrypt', 'decrypt'].includes(this.value?.spec?.securityParameters?.cryptoOperation);
},
encryptionSecret() {
if (!this.value.isEncrypted) {
return '-';
Expand All @@ -80,7 +113,7 @@ export default {
},
imageName() {
return this.value?.metadata?.annotations?.[HCI.IMAGE_NAME] || '-';
return this.value?.metadata?.annotations?.[HCI_ANNOTATIONS.IMAGE_NAME] || '-';
},
}
};
Expand Down Expand Up @@ -144,7 +177,7 @@ export default {
</div>
</div>
<div v-if="value.isEncrypted" class="row">
<div v-if="value.isEncrypted" class="row mb-20">
<div class="col span-12">
<div class="text-label">
{{ t('harvester.image.encryptionSecret') }}
Expand All @@ -161,6 +194,23 @@ export default {
</div>
</div>
<div v-if="isEncryptedOrDecrypted" class="row mb-20">
<div class="col span-12">
<div class="text-label">
{{ t('harvester.image.sourceImage') }}
</div>
<n-link v-if="sourceImageId && sourceImageLink" :to="sourceImageLink">
{{ sourceImageId }}
</n-link>
<span v-else-if="sourceImageId">
{{ sourceImageId }}
</span>
<span v-else class="text-muted">
&mdash;
</span>
</div>
</div>
<div v-if="errorMessage !== '-'" class="row">
<div class="col span-12">
<div>
Expand Down
23 changes: 19 additions & 4 deletions pkg/harvester/edit/harvesterhci.io.virtualmachineimage.vue
Original file line number Diff line number Diff line change
Expand Up @@ -60,20 +60,35 @@ export default {
this.$set(this, 'storageClassName', this.storageClassName || defaultStorage?.metadata?.name || 'longhorn');
this.images = this.$store.getters[`${ inStore }/all`](HCI.IMAGE);
this.selectedImage = this.images.find(i => i.name === this.value.name) || null;
// edit and view mode should show the selected image
if (this.value.name) {
this.selectedImage = this.images.find(i => i.name === this.value.name);
}
},
data() {
// pass from Encrypt Image / Decrypt Image actions
const { image, sourceType, cryptoOperation } = this.$route.query || {};
if ( !this.value.spec ) {
this.$set(this.value, 'spec', { sourceType: DOWNLOAD });
this.$set(this.value, 'spec', { sourceType: sourceType || DOWNLOAD });
}
if (image && cryptoOperation) {
this.$set(this.value.spec, 'securityParameters', {
cryptoOperation,
sourceImageName: image.metadata.name,
sourceImageNamespace: image.metadata.namespace
});
}
if (!this.value.metadata.name) {
this.value.metadata.generateName = 'image-';
}
return {
selectedImage: null,
selectedImage: image || null,
images: [],
url: this.value.spec.url,
files: [],
Expand Down Expand Up @@ -160,7 +175,7 @@ export default {
sourceType: {
get() {
if (this.value.spec.sourceType === CLONE) {
return this.value.spec.securityParameters.cryptoOperation;
return this.value.spec?.securityParameters?.cryptoOperation;
} else {
return this.value.spec.sourceType;
}
Expand Down
6 changes: 4 additions & 2 deletions pkg/harvester/l10n/en-us.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ harvester:
warning: Warning
error: Error
action:
createVM: Create a Virtual Machine
createVM: Create Virtual Machine
start: Start
restart: Restart
softreboot: Soft Reboot
Expand All @@ -135,6 +135,8 @@ harvester:
deepClone: Clone
shallowClone: Clone Template
unpause: Unpause
encryptImage: Encrypt Image
decryptImage: Decrypt Image
ejectCDROM: Eject CD-ROM
editVMQuota: Edit VM Quota
launchFormTemplate: Launch instance from template
Expand Down Expand Up @@ -734,7 +736,7 @@ harvester:
urlTip: 'Supports the <code>raw</code> and <code>qcow2</code> image formats which are supported by <a href="https://www.qemu.org/docs/master/system/images.html#disk-image-file-formats" target="_blank">qemu</a>. Bootable ISO images can also be used and are treated like <code>raw</code> images.'
fileName: File Name
uploadFile: Upload File
source: Source
source: Source Type
sourceType:
download: URL
upload: File
Expand Down
44 changes: 44 additions & 0 deletions pkg/harvester/models/harvesterhci.io.virtualmachineimage.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,20 @@ export default class HciVmImage extends HarvesterResource {
label: this.t('harvester.action.createVM'),
disabled: !this.isReady,
},
{
action: 'encryptImage',
enabled: !this.isEncrypted,
icon: 'icon icon-lock',
label: this.t('harvester.action.encryptImage'),
disabled: !this.isReady,
},
{
action: 'decryptImage',
enabled: this.isEncrypted,
icon: 'icon icon-unlock',
label: this.t('harvester.action.decryptImage'),
disabled: !this.isReady,
},
{
action: 'download',
enabled: this.links?.download,
Expand All @@ -68,6 +82,36 @@ export default class HciVmImage extends HarvesterResource {
];
}

encryptImage() {
const router = this.currentRouter();

router.push({
name: `${ HARVESTER_PRODUCT }-c-cluster-resource-create`,
params: { resource: HCI.IMAGE },
query: {
image: this,
fromPage: HCI.IMAGE,
sourceType: 'clone',
cryptoOperation: 'encrypt'
}
});
}

decryptImage() {
const router = this.currentRouter();

router.push({
name: `${ HARVESTER_PRODUCT }-c-cluster-resource-create`,
params: { resource: HCI.IMAGE },
query: {
image: this,
fromPage: HCI.IMAGE,
sourceType: 'clone',
cryptoOperation: 'decrypt'
}
});
}

applyDefaults(resources = this, realMode) {
if (realMode !== _CLONE) {
Vue.set(this.metadata, 'labels', { [HCI_ANNOTATIONS.OS_TYPE]: '', [HCI_ANNOTATIONS.IMAGE_SUFFIX]: '' });
Expand Down

0 comments on commit cef84ef

Please sign in to comment.