Skip to content

Commit 8c5b846

Browse files
committed
server,ui: prevent non-user templates for External hypervisor
Signed-off-by: Abhishek Kumar <[email protected]>
1 parent adee8d0 commit 8c5b846

File tree

7 files changed

+47
-34
lines changed

7 files changed

+47
-34
lines changed

engine/components-api/src/main/java/com/cloud/template/TemplateManager.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import com.cloud.deploy.DeployDestination;
3030
import com.cloud.exception.ResourceAllocationException;
3131
import com.cloud.exception.StorageUnavailableException;
32+
import com.cloud.hypervisor.Hypervisor;
3233
import com.cloud.storage.DataStoreRole;
3334
import com.cloud.storage.Storage.TemplateType;
3435
import com.cloud.storage.StoragePool;
@@ -141,7 +142,7 @@ public interface TemplateManager {
141142
public static final String MESSAGE_REGISTER_PUBLIC_TEMPLATE_EVENT = "Message.RegisterPublicTemplate.Event";
142143
public static final String MESSAGE_RESET_TEMPLATE_PERMISSION_EVENT = "Message.ResetTemplatePermission.Event";
143144

144-
TemplateType validateTemplateType(BaseCmd cmd, boolean isAdmin, boolean isCrossZones);
145+
TemplateType validateTemplateType(BaseCmd cmd, boolean isAdmin, boolean isCrossZones, Hypervisor.HypervisorType hypervisorType);
145146

146147
List<DatadiskTO> getTemplateDisksOnImageStore(VirtualMachineTemplate template, DataStoreRole role, String configurationId);
147148

plugins/hypervisors/external/src/main/java/org/apache/cloudstack/agent/manager/ExternalTemplateAdapter.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ public TemplateProfile prepare(RegisterTemplateCmd cmd) throws ResourceAllocatio
6969
Account owner = _accountMgr.getAccount(cmd.getEntityOwnerId());
7070
_accountMgr.checkAccess(caller, null, true, owner);
7171
Storage.TemplateType templateType = templateMgr.validateTemplateType(cmd, _accountMgr.isAdmin(caller.getAccountId()),
72-
CollectionUtils.isEmpty(cmd.getZoneIds()));
72+
CollectionUtils.isEmpty(cmd.getZoneIds()), Hypervisor.HypervisorType.External);
7373

7474
List<Long> zoneId = cmd.getZoneIds();
7575
// ignore passed zoneId if we are using region wide image store

plugins/hypervisors/external/src/test/java/org/apache/cloudstack/agent/manager/ExternalTemplateAdapterTest.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
import com.cloud.cpu.CPU;
4747
import com.cloud.exception.InvalidParameterValueException;
4848
import com.cloud.exception.ResourceAllocationException;
49+
import com.cloud.hypervisor.Hypervisor;
4950
import com.cloud.storage.TemplateProfile;
5051
import com.cloud.storage.dao.VMTemplateDao;
5152
import com.cloud.template.TemplateManager;
@@ -118,7 +119,7 @@ public void prepare_WhenRegionImageStoresExist_ZoneIdsAreIgnored() throws Resour
118119
when(cmd.getExternalDetails()).thenReturn(Collections.emptyMap());
119120
when(_accountMgr.getAccount(anyLong())).thenReturn(mock(com.cloud.user.Account.class));
120121
when(_accountMgr.isAdmin(anyLong())).thenReturn(true);
121-
when(templateMgr.validateTemplateType(any(), anyBoolean(), anyBoolean())).thenReturn(com.cloud.storage.Storage.TemplateType.USER);
122+
when(templateMgr.validateTemplateType(any(), anyBoolean(), anyBoolean(), Hypervisor.HypervisorType.External)).thenReturn(com.cloud.storage.Storage.TemplateType.USER);
122123
when(_userDao.findById(any())).thenReturn(mock(UserVO.class));
123124
when(cmd.getEntityOwnerId()).thenReturn(1L);
124125
when(cmd.getTemplateName()).thenReturn("t");

server/src/main/java/com/cloud/template/TemplateAdapterBase.java

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -419,8 +419,16 @@ public TemplateProfile prepare(RegisterTemplateCmd cmd) throws ResourceAllocatio
419419
Account owner = _accountMgr.getAccount(cmd.getEntityOwnerId());
420420
_accountMgr.checkAccess(caller, null, true, owner);
421421

422+
HypervisorType hypervisorType = HypervisorType.getType(cmd.getHypervisor());
423+
if(hypervisorType == HypervisorType.None) {
424+
throw new InvalidParameterValueException(String.format(
425+
"Hypervisor Type: %s is invalid. Supported Hypervisor types are: %s",
426+
cmd.getHypervisor(),
427+
StringUtils.join(Arrays.stream(HypervisorType.values()).filter(h -> h != HypervisorType.None).map(HypervisorType::name).toArray(), ", ")));
428+
}
429+
422430
TemplateType templateType = templateMgr.validateTemplateType(cmd, _accountMgr.isAdmin(caller.getAccountId()),
423-
CollectionUtils.isEmpty(cmd.getZoneIds()));
431+
CollectionUtils.isEmpty(cmd.getZoneIds()), hypervisorType);
424432

425433
List<Long> zoneId = cmd.getZoneIds();
426434
// ignore passed zoneId if we are using region wide image store
@@ -429,14 +437,6 @@ public TemplateProfile prepare(RegisterTemplateCmd cmd) throws ResourceAllocatio
429437
zoneId = null;
430438
}
431439

432-
HypervisorType hypervisorType = HypervisorType.getType(cmd.getHypervisor());
433-
if(hypervisorType == HypervisorType.None) {
434-
throw new InvalidParameterValueException(String.format(
435-
"Hypervisor Type: %s is invalid. Supported Hypervisor types are: %s",
436-
cmd.getHypervisor(),
437-
StringUtils.join(Arrays.stream(HypervisorType.values()).filter(h -> h != HypervisorType.None).map(HypervisorType::name).toArray(), ", ")));
438-
}
439-
440440
Map details = cmd.getDetails();
441441
if (cmd.isDeployAsIs()) {
442442
if (MapUtils.isNotEmpty(details)) {

server/src/main/java/com/cloud/template/TemplateManagerImpl.java

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,6 @@
3434
import javax.inject.Inject;
3535
import javax.naming.ConfigurationException;
3636

37-
import com.cloud.cpu.CPU;
38-
import com.cloud.vm.VirtualMachine;
39-
import com.cloud.storage.snapshot.SnapshotManager;
4037
import org.apache.cloudstack.acl.SecurityChecker.AccessType;
4138
import org.apache.cloudstack.api.ApiConstants;
4239
import org.apache.cloudstack.api.BaseCmd;
@@ -129,6 +126,7 @@
129126
import com.cloud.api.query.vo.UserVmJoinVO;
130127
import com.cloud.configuration.Config;
131128
import com.cloud.configuration.Resource.ResourceType;
129+
import com.cloud.cpu.CPU;
132130
import com.cloud.dc.DataCenter;
133131
import com.cloud.dc.DataCenterVO;
134132
import com.cloud.dc.dao.DataCenterDao;
@@ -184,6 +182,7 @@
184182
import com.cloud.storage.dao.VMTemplatePoolDao;
185183
import com.cloud.storage.dao.VMTemplateZoneDao;
186184
import com.cloud.storage.dao.VolumeDao;
185+
import com.cloud.storage.snapshot.SnapshotManager;
187186
import com.cloud.template.TemplateAdapter.TemplateAdapterType;
188187
import com.cloud.template.VirtualMachineTemplate.BootloaderType;
189188
import com.cloud.user.Account;
@@ -213,6 +212,7 @@
213212
import com.cloud.vm.UserVmManager;
214213
import com.cloud.vm.UserVmVO;
215214
import com.cloud.vm.VMInstanceVO;
215+
import com.cloud.vm.VirtualMachine;
216216
import com.cloud.vm.VirtualMachine.State;
217217
import com.cloud.vm.VirtualMachineProfile;
218218
import com.cloud.vm.VirtualMachineProfileImpl;
@@ -2173,7 +2173,7 @@ private VMTemplateVO updateTemplateOrIso(BaseUpdateTemplateOrIsoCmd cmd) {
21732173
String templateTag = null;
21742174
if (cmd instanceof UpdateTemplateCmd) {
21752175
boolean isAdmin = _accountMgr.isAdmin(account.getId());
2176-
templateType = validateTemplateType(cmd, isAdmin, template.isCrossZones());
2176+
templateType = validateTemplateType(cmd, isAdmin, template.isCrossZones(), template.getHypervisorType());
21772177
if (cmd instanceof UpdateVnfTemplateCmd) {
21782178
VnfTemplateUtils.validateApiCommandParams(cmd, template);
21792179
vnfTemplateManager.updateVnfTemplate(template.getId(), (UpdateVnfTemplateCmd) cmd);
@@ -2311,7 +2311,7 @@ else if (details != null && !details.isEmpty()) {
23112311
}
23122312

23132313
@Override
2314-
public TemplateType validateTemplateType(BaseCmd cmd, boolean isAdmin, boolean isCrossZones) {
2314+
public TemplateType validateTemplateType(BaseCmd cmd, boolean isAdmin, boolean isCrossZones, HypervisorType hypervisorType) {
23152315
if (!(cmd instanceof UpdateTemplateCmd) && !(cmd instanceof RegisterTemplateCmd)) {
23162316
return null;
23172317
}
@@ -2345,6 +2345,7 @@ public TemplateType validateTemplateType(BaseCmd cmd, boolean isAdmin, boolean i
23452345
boolean isRouting = Boolean.TRUE.equals(isRoutingType);
23462346
templateType = (cmd instanceof RegisterVnfTemplateCmd) ? TemplateType.VNF : (isRouting ? TemplateType.ROUTING : TemplateType.USER);
23472347
}
2348+
validateExternalHypervisorTemplateType(hypervisorType, templateType);
23482349
if (templateType != null && !isAdmin && !Arrays.asList(TemplateType.USER, TemplateType.VNF).contains(templateType)) {
23492350
if (cmd instanceof RegisterTemplateCmd) {
23502351
throw new InvalidParameterValueException(String.format("Users can not register template with template type %s.", templateType));
@@ -2355,6 +2356,15 @@ public TemplateType validateTemplateType(BaseCmd cmd, boolean isAdmin, boolean i
23552356
return templateType;
23562357
}
23572358

2359+
protected void validateExternalHypervisorTemplateType(HypervisorType hypervisorType, TemplateType templateType) {
2360+
if (!HypervisorType.External.equals(hypervisorType) ||
2361+
templateType == null || templateType == TemplateType.USER) {
2362+
return;
2363+
}
2364+
throw new InvalidParameterValueException(String.format("Only %s templates supported for %s hypervisor type",
2365+
TemplateType.USER, HypervisorType.External));
2366+
}
2367+
23582368
void validateDetails(VMTemplateVO template, Map<String, String> details) {
23592369
if (MapUtils.isEmpty(details)) {
23602370
return;

server/src/test/java/com/cloud/template/TemplateManagerImplTest.java

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -651,102 +651,102 @@ public void getImageStoreTestStoreUuidIsNullAndThereIsActiveHeuristicRulesShould
651651
public void testRegisterTemplateWithTemplateType() {
652652
RegisterTemplateCmd cmd = Mockito.mock(RegisterTemplateCmd.class);
653653
when(cmd.getTemplateType()).thenReturn(Storage.TemplateType.SYSTEM.toString());
654-
Storage.TemplateType type = templateManager.validateTemplateType(cmd, true, true);
654+
Storage.TemplateType type = templateManager.validateTemplateType(cmd, true, true, Hypervisor.HypervisorType.KVM);
655655
Assert.assertEquals(Storage.TemplateType.SYSTEM, type);
656656
}
657657

658658
@Test
659659
public void testRegisterTemplateWithoutTemplateType() {
660660
RegisterTemplateCmd cmd = Mockito.mock(RegisterTemplateCmd.class);
661-
Storage.TemplateType type = templateManager.validateTemplateType(cmd, true, true);
661+
Storage.TemplateType type = templateManager.validateTemplateType(cmd, true, true, Hypervisor.HypervisorType.KVM);
662662
Assert.assertEquals(Storage.TemplateType.USER, type);
663663
}
664664

665665
@Test(expected = InvalidParameterValueException.class)
666666
public void testRegisterTemplateWithSystemTemplateTypeByUser() {
667667
RegisterVnfTemplateCmd cmd = Mockito.mock(RegisterVnfTemplateCmd.class);
668668
when(cmd.getTemplateType()).thenReturn(Storage.TemplateType.SYSTEM.toString());
669-
Storage.TemplateType type = templateManager.validateTemplateType(cmd, false, true);
669+
Storage.TemplateType type = templateManager.validateTemplateType(cmd, false, true, Hypervisor.HypervisorType.KVM);
670670
}
671671

672672
@Test(expected = InvalidParameterValueException.class)
673673
public void testRegisterVnfTemplateWithTemplateType() {
674674
RegisterVnfTemplateCmd cmd = Mockito.mock(RegisterVnfTemplateCmd.class);
675675
when(cmd.getTemplateType()).thenReturn(Storage.TemplateType.SYSTEM.toString());
676-
Storage.TemplateType type = templateManager.validateTemplateType(cmd, false, true);
676+
Storage.TemplateType type = templateManager.validateTemplateType(cmd, false, true, Hypervisor.HypervisorType.KVM);
677677
Assert.assertEquals(Storage.TemplateType.VNF, type);
678678
}
679679

680680
@Test
681681
public void testRegisterVnfTemplateWithoutTemplateType() {
682682
RegisterVnfTemplateCmd cmd = Mockito.mock(RegisterVnfTemplateCmd.class);
683-
Storage.TemplateType type = templateManager.validateTemplateType(cmd, false, true);
683+
Storage.TemplateType type = templateManager.validateTemplateType(cmd, false, true, Hypervisor.HypervisorType.KVM);
684684
Assert.assertEquals(Storage.TemplateType.VNF, type);
685685
}
686686

687687
@Test
688688
public void testUpdateTemplateWithTemplateType() {
689689
UpdateTemplateCmd cmd = Mockito.mock(UpdateTemplateCmd.class);
690690
when(cmd.getTemplateType()).thenReturn(Storage.TemplateType.SYSTEM.toString());
691-
Storage.TemplateType type = templateManager.validateTemplateType(cmd, true, true);
691+
Storage.TemplateType type = templateManager.validateTemplateType(cmd, true, true, Hypervisor.HypervisorType.XenServer);
692692
Assert.assertEquals(Storage.TemplateType.SYSTEM, type);
693693
}
694694

695695
@Test
696696
public void testUpdateTemplateWithoutTemplateType() {
697697
UpdateTemplateCmd cmd = Mockito.mock(UpdateTemplateCmd.class);
698-
Storage.TemplateType type = templateManager.validateTemplateType(cmd, true, true);
698+
Storage.TemplateType type = templateManager.validateTemplateType(cmd, true, true, Hypervisor.HypervisorType.KVM);
699699
Assert.assertNull(type);
700700
}
701701

702702
@Test(expected = InvalidParameterValueException.class)
703703
public void testUpdateTemplateWithInvalidTemplateType() {
704704
UpdateTemplateCmd cmd = Mockito.mock(UpdateTemplateCmd.class);
705705
when(cmd.getTemplateType()).thenReturn("invalidtype");
706-
Storage.TemplateType type = templateManager.validateTemplateType(cmd, true, true);
706+
Storage.TemplateType type = templateManager.validateTemplateType(cmd, true, true, Hypervisor.HypervisorType.VMware);
707707
}
708708

709709
@Test(expected = InvalidParameterValueException.class)
710710
public void testUpdateTemplateWithInvalidTemplateTypeForRouting() {
711711
UpdateTemplateCmd cmd = Mockito.mock(UpdateTemplateCmd.class);
712712
when(cmd.getTemplateType()).thenReturn(Storage.TemplateType.USER.toString());
713713
when(cmd.isRoutingType()).thenReturn(true);
714-
Storage.TemplateType type = templateManager.validateTemplateType(cmd, true, true);
714+
Storage.TemplateType type = templateManager.validateTemplateType(cmd, true, true, Hypervisor.HypervisorType.KVM);
715715
}
716716

717717
@Test(expected = InvalidParameterValueException.class)
718718
public void testUpdateTemplateWithInvalidCrossZonesForSystem() {
719719
UpdateTemplateCmd cmd = Mockito.mock(UpdateTemplateCmd.class);
720720
when(cmd.getTemplateType()).thenReturn(Storage.TemplateType.SYSTEM.toString());
721-
Storage.TemplateType type = templateManager.validateTemplateType(cmd, true, false);
721+
Storage.TemplateType type = templateManager.validateTemplateType(cmd, true, false, Hypervisor.HypervisorType.KVM);
722722
}
723723

724724
@Test(expected = InvalidParameterValueException.class)
725725
public void testUpdateTemplateWithSystemTemplateTypeByUser() {
726726
UpdateVnfTemplateCmd cmd = Mockito.mock(UpdateVnfTemplateCmd.class);
727727
when(cmd.getTemplateType()).thenReturn(Storage.TemplateType.SYSTEM.toString());
728-
Storage.TemplateType type = templateManager.validateTemplateType(cmd, false, true);
728+
Storage.TemplateType type = templateManager.validateTemplateType(cmd, false, true, Hypervisor.HypervisorType.XenServer);
729729
}
730730

731731
@Test(expected = InvalidParameterValueException.class)
732732
public void testUpdateVnfTemplateWithTemplateType() {
733733
UpdateVnfTemplateCmd cmd = Mockito.mock(UpdateVnfTemplateCmd.class);
734734
when(cmd.getTemplateType()).thenReturn(Storage.TemplateType.SYSTEM.toString());
735-
Storage.TemplateType type = templateManager.validateTemplateType(cmd, false, true);
735+
Storage.TemplateType type = templateManager.validateTemplateType(cmd, false, true, Hypervisor.HypervisorType.KVM);
736736
Assert.assertEquals(Storage.TemplateType.VNF, type);
737737
}
738738

739739
@Test
740740
public void testUpdateVnfTemplateWithoutTemplateType() {
741741
UpdateVnfTemplateCmd cmd = Mockito.mock(UpdateVnfTemplateCmd.class);
742-
Storage.TemplateType type = templateManager.validateTemplateType(cmd, false, true);
742+
Storage.TemplateType type = templateManager.validateTemplateType(cmd, false, true, Hypervisor.HypervisorType.KVM);
743743
Assert.assertNull(type);
744744
}
745745

746746
@Test
747747
public void testDeleteTemplateWithTemplateType() {
748748
DeleteTemplateCmd cmd = new DeleteTemplateCmd();
749-
Storage.TemplateType type = templateManager.validateTemplateType(cmd, true, true);
749+
Storage.TemplateType type = templateManager.validateTemplateType(cmd, true, true, Hypervisor.HypervisorType.VMware);
750750
Assert.assertNull(type);
751751
}
752752

ui/src/views/image/UpdateTemplate.vue

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -178,8 +178,8 @@
178178
v-model:value="form.templatetype"
179179
:placeholder="apiParams.templatetype.description"
180180
@change="val => { selectedTemplateType = val }">
181-
<a-select-option v-for="opt in templatetypes" :key="opt">
182-
{{ opt }}
181+
<a-select-option v-for="opt in templatetypes" :key="opt.id">
182+
{{ opt.name || opt.description }}
183183
</a-select-option>
184184
</a-select>
185185
</a-form-item>
@@ -239,7 +239,7 @@ export default {
239239
},
240240
data () {
241241
return {
242-
templatetypes: ['BUILTIN', 'USER', 'SYSTEM', 'ROUTING', 'VNF'],
242+
templatetypes: [],
243243
emptyAllowedFields: ['templatetag'],
244244
rootDisk: {},
245245
nicAdapterType: {},
@@ -261,6 +261,7 @@ export default {
261261
},
262262
created () {
263263
this.initForm()
264+
this.templatetypes = this.$fetchTemplateTypes(this.resource.hypervisor)
264265
this.rootDisk.loading = false
265266
this.rootDisk.opts = []
266267
this.nicAdapterType.loading = false

0 commit comments

Comments
 (0)