This is an automated email from the ASF dual-hosted git repository. dahn pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/cloudstack.git
commit ea832bce1367be400ab11f27e88e9b8bda6b0d0a Merge: 0bd7462c54a db0e7a65afb Author: Daan Hoogland <[email protected]> AuthorDate: Tue Aug 22 11:44:45 2023 +0200 Merge branch '4.18' .../com/cloud/network/as/AutoScaleVmProfile.java | 4 + .../java/org/apache/cloudstack/api/BaseCmd.java | 17 ++ .../admin/internallb/StopInternalLBVMCmd.java | 2 +- .../api/command/admin/router/StopRouterCmd.java | 2 +- .../command/admin/systemvm/StopSystemVmCmd.java | 2 +- .../autoscale/CreateAutoScaleVmProfileCmd.java | 15 ++ .../autoscale/UpdateAutoScaleVmProfileCmd.java | 17 ++ .../api/command/user/network/CreateNetworkCmd.java | 4 +- .../command/user/snapshot/CreateSnapshotCmd.java | 2 +- .../api/command/user/vm/DeployVMCmd.java | 28 +-- .../api/command/user/vm/ResetVMUserDataCmd.java | 16 +- .../cloudstack/api/command/user/vm/ScaleVMCmd.java | 15 +- .../cloudstack/api/command/user/vm/StopVMCmd.java | 3 +- .../api/command/user/vm/UpdateVMCmd.java | 14 +- .../api/command/user/vm/UpgradeVMCmd.java | 15 +- .../api/command/user/volume/CreateVolumeCmd.java | 3 +- .../api/command/user/volume/UploadVolumeCmd.java | 2 +- .../api/response/AutoScaleVmProfileResponse.java | 48 ++++ .../cloudstack/api/response/UserVmResponse.java | 2 +- .../engine/orchestration/VolumeOrchestrator.java | 18 +- .../dao/HypervisorCapabilitiesDaoImpl.java | 7 + .../com/cloud/network/as/AutoScaleVmProfileVO.java | 24 ++ .../main/java/com/cloud/upgrade/GuestOsMapper.java | 16 ++ .../com/cloud/upgrade/dao/Upgrade41800to41810.java | 119 ++++++++++ .../resources/META-INF/db/schema-41800to41810.sql | 7 + .../cloud/network/as/AutoScaleVmProfileVOTest.java | 31 +++ packaging/centos8/cloud.spec | 2 +- .../acl/StaticRoleBasedAPIAccessChecker.java | 10 +- .../command/admin/ratelimit/ResetApiLimitCmd.java | 2 +- .../cloud/hypervisor/guru/VmwareVmImplementer.java | 16 +- .../hypervisor/vmware/resource/VmwareResource.java | 21 +- .../hypervisor/guru/VmwareVmImplementerTest.java | 46 ++++ .../com/cloud/api/commands/StopNetScalerVMCmd.java | 2 +- .../api/command/ListTungstenFabricTagCmd.java | 2 +- .../util/ListElastistorVolumeResponse.java | 2 +- .../api/response/LdapConfigurationResponse.java | 2 +- .../api/response/LinkAccountToLdapResponse.java | 2 +- .../api/response/LinkDomainToLdapResponse.java | 2 +- .../java/com/cloud/api/ApiAsyncJobDispatcher.java | 6 + .../main/java/com/cloud/api/ApiResponseHelper.java | 14 ++ server/src/main/java/com/cloud/api/ApiServer.java | 3 + .../api/auth/DefaultLoginAPIAuthenticatorCmd.java | 2 +- .../java/com/cloud/api/query/QueryManagerImpl.java | 8 +- .../com/cloud/api/query/ViewResponseHelper.java | 29 ++- .../com/cloud/network/as/AutoScaleManagerImpl.java | 53 ++++- .../network/security/SecurityGroupManagerImpl.java | 2 +- .../security/SecurityGroupManagerImpl2.java | 2 +- .../com/cloud/template/TemplateManagerImpl.java | 2 +- .../java/com/cloud/user/AccountManagerImpl.java | 7 +- .../src/main/java/com/cloud/vm/UserVmManager.java | 4 + .../main/java/com/cloud/vm/UserVmManagerImpl.java | 53 ++++- .../java/com/cloud/api/ApiResponseHelperTest.java | 72 ++++++ .../cloud/network/as/AutoScaleManagerImplTest.java | 75 +++++- .../com/cloud/user/AccountManagerImplTest.java | 13 +- .../consoleproxy/ConsoleProxyNoVncClient.java | 12 +- test/integration/smoke/test_internal_lb.py | 7 +- test/integration/smoke/test_vm_autoscaling.py | 69 ++++++ tools/apidoc/build-apidoc.sh | 8 +- ui/public/locales/en.json | 1 + ui/src/config/section/image.js | 2 +- ui/src/views/compute/AutoScaleVmProfile.vue | 92 ++++++-- ui/src/views/compute/CreateAutoScaleVmGroup.vue | 257 +++++++++++++++++++-- ui/src/views/compute/ResetUserData.vue | 10 +- ui/src/views/image/RegisterOrUploadIso.vue | 60 +++-- ui/src/views/image/RegisterOrUploadTemplate.vue | 60 +++-- ui/src/views/image/TemplateZones.vue | 17 ++ ui/src/views/infra/zone/ZoneWizardLaunchZone.vue | 5 +- .../apache/cloudstack/utils/CloudStackVersion.java | 17 ++ .../cloudstack/utils/CloudStackVersionTest.java | 20 ++ 69 files changed, 1295 insertions(+), 229 deletions(-) diff --cc plugins/hypervisors/vmware/src/test/java/com/cloud/hypervisor/guru/VmwareVmImplementerTest.java index 80f73d61916,f1647808c94..c958fa70485 --- a/plugins/hypervisors/vmware/src/test/java/com/cloud/hypervisor/guru/VmwareVmImplementerTest.java +++ b/plugins/hypervisors/vmware/src/test/java/com/cloud/hypervisor/guru/VmwareVmImplementerTest.java @@@ -23,7 -23,7 +23,8 @@@ import static org.mockito.Mockito.verif import java.util.HashMap; import java.util.Map; +import org.junit.After; + import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@@ -32,15 -32,15 +33,18 @@@ import org.mockito.Mock import org.mockito.Mockito; import org.mockito.MockitoAnnotations; import org.mockito.Spy; -import org.powermock.modules.junit4.PowerMockRunner; +import org.mockito.junit.MockitoJUnitRunner; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.support.AnnotationConfigContextLoader; import com.cloud.agent.api.to.VirtualMachineTO; + import com.cloud.storage.GuestOSHypervisorVO; + import com.cloud.storage.GuestOSVO; + import com.cloud.storage.dao.GuestOSHypervisorDao; import com.cloud.vm.VmDetailConstants; -@RunWith(PowerMockRunner.class) +@RunWith(MockitoJUnitRunner.class) +@ContextConfiguration(loader = AnnotationConfigContextLoader.class) public class VmwareVmImplementerTest { @Spy @@@ -50,18 -50,14 +54,21 @@@ @Mock VirtualMachineTO vmTO; + @Mock + GuestOSHypervisorDao guestOsHypervisorDao; + private Map<String,String> vmDetails = new HashMap<String, String>(); + AutoCloseable closeable; + @Before public void testSetUp() throws Exception { - MockitoAnnotations.initMocks(this); + closeable = MockitoAnnotations.openMocks(this); + } + + @After + public void tearDown() throws Exception { + closeable.close(); } private void setConfigValues(Boolean globalNV, Boolean globalNVPVM, String localNV){ diff --cc server/src/main/java/com/cloud/api/ApiResponseHelper.java index 8cd80dd9a52,55f00a609e9..9c46839ce8f --- a/server/src/main/java/com/cloud/api/ApiResponseHelper.java +++ b/server/src/main/java/com/cloud/api/ApiResponseHelper.java @@@ -463,7 -457,7 +464,9 @@@ public class ApiResponseHelper implemen @Inject NetworkServiceMapDao ntwkSrvcDao; @Inject + FirewallRulesDao firewallRulesDao; ++ @Inject + UserDataDao userDataDao; @Override public UserResponse createUserResponse(User user) { diff --cc ui/src/views/compute/AutoScaleVmProfile.vue index 705bfb59d10,12081dfad72..208fa6a881e --- a/ui/src/views/compute/AutoScaleVmProfile.vue +++ b/ui/src/views/compute/AutoScaleVmProfile.vue @@@ -275,9 -318,10 +330,10 @@@ export default }, data () { return { - filterColumns: ['Action'], + filterColumns: ['Actions'], loading: true, editProfileModalVisible: false, + showUpdateUserDataForm: false, profileid: null, autoscaleuserid: null, expungevmgraceperiod: null, diff --cc ui/src/views/image/RegisterOrUploadIso.vue index 6c34ec8972a,aa127a3d405..1a461ee6bf6 --- a/ui/src/views/image/RegisterOrUploadIso.vue +++ b/ui/src/views/image/RegisterOrUploadIso.vue @@@ -97,49 -111,10 +111,52 @@@ </a-select> </a-form-item> + <a-form-item name="domainid" ref="domainid" v-if="'listDomains' in $store.getters.apis"> + <template #label> + <tooltip-label :title="$t('label.domainid')" :tooltip="apiParams.domainid.description"/> + </template> + <a-select + v-model:value="form.domainid" + showSearch + optionFilterProp="label" + :filterOption="(input, option) => { + return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0 + }" + :loading="domainLoading" + :placeholder="apiParams.domainid.description" + @change="val => { handleDomainChange(val) }"> + <a-select-option v-for="(opt, optIndex) in this.domains" :key="optIndex" :label="opt.path || opt.name || opt.description" :value="opt.id"> + <span> + <resource-icon v-if="opt && opt.icon" :image="opt.icon.base64image" size="1x" style="margin-right: 5px"/> + <block-outlined v-else style="margin-right: 5px" /> + {{ opt.path || opt.name || opt.description }} + </span> + </a-select-option> + </a-select> + </a-form-item> + <a-form-item name="account" ref="account" v-if="domainid"> + <template #label> + <tooltip-label :title="$t('label.account')" :tooltip="apiParams.account.description"/> + </template> + <a-select + v-model:value="form.account" + showSearch + optionFilterProp="label" + :filterOption="(input, option) => { + return option.value.toLowerCase().indexOf(input.toLowerCase()) >= 0 + }" + :placeholder="apiParams.account.description" + @change="val => { handleAccountChange(val) }"> + <a-select-option v-for="(acc, index) in accounts" :value="acc.name" :key="index"> + {{ acc.name }} + </a-select-option> + </a-select> + </a-form-item> + - <a-form-item ref="bootable" name="bootable" :label="$t('label.bootable')"> + <a-form-item ref="bootable" name="bootable"> + <template #label> + <tooltip-label :title="$t('label.bootable')" :tooltip="apiParams.bootable.description"/> + </template> <a-switch v-model:checked="form.bootable" /> </a-form-item> @@@ -187,10 -167,9 +209,10 @@@ <a-col :md="24" :lg="12"> <a-form-item ref="userdatapolicy" name="userdatapolicy"> <template #label> - <tooltip-label :title="$t('label.userdatapolicy')" :tooltip="$t('label.userdatapolicy.tooltip')"/> + <tooltip-label :title="$t('label.userdatapolicy')" :tooltip="linkUserDataParams.userdatapolicy.description"/> </template> <a-select + showSearch v-model:value="userdatapolicy" :placeholder="linkUserDataParams.userdatapolicy.description" optionFilterProp="label" diff --cc ui/src/views/image/RegisterOrUploadTemplate.vue index f9578d4714d,c8e7ad3510e..6add11ab0ba --- a/ui/src/views/image/RegisterOrUploadTemplate.vue +++ b/ui/src/views/image/RegisterOrUploadTemplate.vue @@@ -117,50 -130,12 +130,53 @@@ </a-select> </a-form-item> </div> + <a-form-item name="domainid" ref="domainid" v-if="'listDomains' in $store.getters.apis"> + <template #label> + <tooltip-label :title="$t('label.domainid')" :tooltip="apiParams.domainid.description"/> + </template> + <a-select + v-model:value="form.domainid" + showSearch + optionFilterProp="label" + :filterOption="(input, option) => { + return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0 + }" + :loading="domainLoading" + :placeholder="apiParams.domainid.description" + @change="val => { handleDomainChange(val) }"> + <a-select-option v-for="(opt, optIndex) in this.domains" :key="optIndex" :label="opt.path || opt.name || opt.description" :value="opt.id"> + <span> + <resource-icon v-if="opt && opt.icon" :image="opt.icon.base64image" size="1x" style="margin-right: 5px"/> + <block-outlined v-else style="margin-right: 5px" /> + {{ opt.path || opt.name || opt.description }} + </span> + </a-select-option> + </a-select> + </a-form-item> + <a-form-item name="account" ref="account" v-if="domainid"> + <template #label> + <tooltip-label :title="$t('label.account')" :tooltip="apiParams.account.description"/> + </template> + <a-select + v-model:value="form.account" + showSearch + optionFilterProp="label" + :filterOption="(input, option) => { + return option.value.toLowerCase().indexOf(input.toLowerCase()) >= 0 + }" + :placeholder="apiParams.account.description" + @change="val => { handleAccountChange(val) }"> + <a-select-option v-for="(acc, index) in accounts" :value="acc.name" :key="index"> + {{ acc.name }} + </a-select-option> + </a-select> + </a-form-item> <a-row :gutter="12"> <a-col :md="24" :lg="12"> - <a-form-item ref="hypervisor" name="hypervisor" :label="$t('label.hypervisor')"> + <a-form-item ref="hypervisor" name="hypervisor"> + <template #label> + <tooltip-label :title="$t('label.hypervisor')" :tooltip="apiParams.hypervisor.description"/> + </template> <a-select v-model:value="form.hypervisor" :loading="hyperVisor.loading" @@@ -195,9 -173,12 +214,12 @@@ </a-form-item> </a-col> </a-row> - <a-row :gutter="12" v-if="allowed && hyperKVMShow && currentForm !== 'Upload'"> + <a-row :gutter="12" v-if="allowed && (hyperKVMShow || hyperCustomShow) && currentForm !== 'Upload'"> <a-col :md="24" :lg="12"> - <a-form-item ref="directdownload" name="directdownload" :label="$t('label.directdownload')"> + <a-form-item ref="directdownload" name="directdownload"> + <template #label> + <tooltip-label :title="$t('label.directdownload')" :tooltip="apiParams.directdownload.description"/> + </template> <a-switch v-model:checked="form.directdownload" @change="handleChangeDirect" /> </a-form-item> </a-col> @@@ -318,10 -309,9 +350,10 @@@ <a-col :md="24" :lg="12"> <a-form-item ref="userdatapolicy" name="userdatapolicy"> <template #label> - <tooltip-label :title="$t('label.userdatapolicy')" :tooltip="$t('label.userdatapolicy.tooltip')"/> + <tooltip-label :title="$t('label.userdatapolicy')" :tooltip="linkUserDataParams.userdatapolicy.description"/> </template> <a-select + showSearch v-model:value="userdatapolicy" :placeholder="linkUserDataParams.userdatapolicy.description" optionFilterProp="label"
