mirror of
				https://github.com/apache/cloudstack.git
				synced 2025-10-26 08:42:29 +01:00 
			
		
		
		
	enable update tags on disk offerings (#4194)
This commit is contained in:
		
							parent
							
								
									d676ffa0a0
								
							
						
					
					
						commit
						c222d0bf60
					
				| @ -19,6 +19,7 @@ package org.apache.cloudstack.api.command.admin.offering; | |||||||
| import java.util.ArrayList; | import java.util.ArrayList; | ||||||
| import java.util.List; | import java.util.List; | ||||||
| 
 | 
 | ||||||
|  | import org.apache.cloudstack.acl.RoleType; | ||||||
| import org.apache.cloudstack.api.APICommand; | import org.apache.cloudstack.api.APICommand; | ||||||
| import org.apache.cloudstack.api.ApiConstants; | import org.apache.cloudstack.api.ApiConstants; | ||||||
| import org.apache.cloudstack.api.ApiErrorCode; | import org.apache.cloudstack.api.ApiErrorCode; | ||||||
| @ -77,6 +78,14 @@ public class UpdateDiskOfferingCmd extends BaseCmd { | |||||||
|             since = "4.13") |             since = "4.13") | ||||||
|     private String zoneIds; |     private String zoneIds; | ||||||
| 
 | 
 | ||||||
|  |     @Parameter(name = ApiConstants.TAGS, | ||||||
|  |             type = CommandType.STRING, | ||||||
|  |             description = "comma-separated list of tags for the disk offering, tags should match with existing storage pool tags", | ||||||
|  |             authorized = {RoleType.Admin}, | ||||||
|  |             since = "4.15") | ||||||
|  |     private String tags; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|     ///////////////////////////////////////////////////// |     ///////////////////////////////////////////////////// | ||||||
|     /////////////////// Accessors /////////////////////// |     /////////////////// Accessors /////////////////////// | ||||||
|     ///////////////////////////////////////////////////// |     ///////////////////////////////////////////////////// | ||||||
| @ -161,6 +170,10 @@ public class UpdateDiskOfferingCmd extends BaseCmd { | |||||||
|         return validZoneIds; |         return validZoneIds; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     public String getTags() { | ||||||
|  |         return tags; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
| ///////////////////////////////////////////////////// | ///////////////////////////////////////////////////// | ||||||
|     /////////////// API Implementation/////////////////// |     /////////////// API Implementation/////////////////// | ||||||
|     ///////////////////////////////////////////////////// |     ///////////////////////////////////////////////////// | ||||||
|  | |||||||
| @ -364,7 +364,7 @@ public class DiskOfferingVO implements DiskOffering { | |||||||
|         return created; |         return created; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     protected void setTags(String tags) { |     public void setTags(String tags) { | ||||||
|         this.tags = tags; |         this.tags = tags; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -39,6 +39,7 @@ import java.util.UUID; | |||||||
| import javax.inject.Inject; | import javax.inject.Inject; | ||||||
| import javax.naming.ConfigurationException; | import javax.naming.ConfigurationException; | ||||||
| 
 | 
 | ||||||
|  | import com.cloud.utils.StringUtils; | ||||||
| import org.apache.cloudstack.acl.SecurityChecker; | import org.apache.cloudstack.acl.SecurityChecker; | ||||||
| import org.apache.cloudstack.affinity.AffinityGroup; | import org.apache.cloudstack.affinity.AffinityGroup; | ||||||
| import org.apache.cloudstack.affinity.AffinityGroupService; | import org.apache.cloudstack.affinity.AffinityGroupService; | ||||||
| @ -222,7 +223,6 @@ import com.cloud.user.dao.AccountDao; | |||||||
| import com.cloud.user.dao.UserDao; | import com.cloud.user.dao.UserDao; | ||||||
| import com.cloud.utils.NumbersUtil; | import com.cloud.utils.NumbersUtil; | ||||||
| import com.cloud.utils.Pair; | import com.cloud.utils.Pair; | ||||||
| import com.cloud.utils.StringUtils; |  | ||||||
| import com.cloud.utils.UriUtils; | import com.cloud.utils.UriUtils; | ||||||
| import com.cloud.utils.component.ManagerBase; | import com.cloud.utils.component.ManagerBase; | ||||||
| import com.cloud.utils.db.DB; | import com.cloud.utils.db.DB; | ||||||
| @ -3109,6 +3109,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati | |||||||
|         final Boolean displayDiskOffering = cmd.getDisplayOffering(); |         final Boolean displayDiskOffering = cmd.getDisplayOffering(); | ||||||
|         final List<Long> domainIds = cmd.getDomainIds(); |         final List<Long> domainIds = cmd.getDomainIds(); | ||||||
|         final List<Long> zoneIds = cmd.getZoneIds(); |         final List<Long> zoneIds = cmd.getZoneIds(); | ||||||
|  |         final String tags = cmd.getTags(); | ||||||
| 
 | 
 | ||||||
|         // Check if diskOffering exists |         // Check if diskOffering exists | ||||||
|         final DiskOffering diskOfferingHandle = _entityMgr.findById(DiskOffering.class, diskOfferingId); |         final DiskOffering diskOfferingHandle = _entityMgr.findById(DiskOffering.class, diskOfferingId); | ||||||
| @ -3190,7 +3191,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati | |||||||
|             throw new InvalidParameterValueException(String.format("Unable to update disk offering: %s by id user: %s because it is not root-admin or domain-admin", diskOfferingHandle.getUuid(), user.getUuid())); |             throw new InvalidParameterValueException(String.format("Unable to update disk offering: %s by id user: %s because it is not root-admin or domain-admin", diskOfferingHandle.getUuid(), user.getUuid())); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         final boolean updateNeeded = name != null || displayText != null || sortKey != null || displayDiskOffering != null; |         final boolean updateNeeded = shouldUpdateDiskOffering(name, displayText, sortKey, displayDiskOffering, tags); | ||||||
|         final boolean detailsUpdateNeeded = !filteredDomainIds.equals(existingDomainIds) || !filteredZoneIds.equals(existingZoneIds); |         final boolean detailsUpdateNeeded = !filteredDomainIds.equals(existingDomainIds) || !filteredZoneIds.equals(existingZoneIds); | ||||||
|         if (!updateNeeded && !detailsUpdateNeeded) { |         if (!updateNeeded && !detailsUpdateNeeded) { | ||||||
|             return _diskOfferingDao.findById(diskOfferingId); |             return _diskOfferingDao.findById(diskOfferingId); | ||||||
| @ -3214,30 +3215,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati | |||||||
|             diskOffering.setDisplayOffering(displayDiskOffering); |             diskOffering.setDisplayOffering(displayDiskOffering); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         // Note: tag editing commented out for now;keeping the code intact, |         updateDiskOfferingTagsIfIsNotNull(tags, diskOffering); | ||||||
|         // might need to re-enable in next releases |  | ||||||
|         // if (tags != null) |  | ||||||
|         // { |  | ||||||
|         // if (tags.trim().isEmpty() && diskOfferingHandle.getTags() == null) |  | ||||||
|         // { |  | ||||||
|         // //no new tags; no existing tags |  | ||||||
|         // diskOffering.setTagsArray(csvTagsToList(null)); |  | ||||||
|         // } |  | ||||||
|         // else if (!tags.trim().isEmpty() && diskOfferingHandle.getTags() != |  | ||||||
|         // null) |  | ||||||
|         // { |  | ||||||
|         // //new tags + existing tags |  | ||||||
|         // List<String> oldTags = csvTagsToList(diskOfferingHandle.getTags()); |  | ||||||
|         // List<String> newTags = csvTagsToList(tags); |  | ||||||
|         // oldTags.addAll(newTags); |  | ||||||
|         // diskOffering.setTagsArray(oldTags); |  | ||||||
|         // } |  | ||||||
|         // else if(!tags.trim().isEmpty()) |  | ||||||
|         // { |  | ||||||
|         // //new tags; NO existing tags |  | ||||||
|         // diskOffering.setTagsArray(csvTagsToList(tags)); |  | ||||||
|         // } |  | ||||||
|         // } |  | ||||||
| 
 | 
 | ||||||
|         if (updateNeeded && !_diskOfferingDao.update(diskOfferingId, diskOffering)) { |         if (updateNeeded && !_diskOfferingDao.update(diskOfferingId, diskOffering)) { | ||||||
|             return null; |             return null; | ||||||
| @ -3274,6 +3252,31 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati | |||||||
|         return _diskOfferingDao.findById(diskOfferingId); |         return _diskOfferingDao.findById(diskOfferingId); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     /** | ||||||
|  |      * Check the tags parameters to the diskOffering | ||||||
|  |      * <ul> | ||||||
|  |      *     <li>If tags is null, do nothing and return.</li> | ||||||
|  |      *     <li>If tags is not null, set tag to the diskOffering.</li> | ||||||
|  |      *     <li>If tags is an blank string, set null on diskOffering tag.</li> | ||||||
|  |      * </ul> | ||||||
|  |      */ | ||||||
|  |     protected void updateDiskOfferingTagsIfIsNotNull(String tags, DiskOfferingVO diskOffering) { | ||||||
|  |         if (tags == null) { return; } | ||||||
|  |         if (StringUtils.isNotBlank(tags)) { | ||||||
|  |             diskOffering.setTags(tags); | ||||||
|  |         } else { | ||||||
|  |             diskOffering.setTags(null); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Check if it needs to update any parameter when updateDiskoffering is called | ||||||
|  |      * Verify if name or displayText are not blank, tags is not null, sortkey and displayDiskOffering is not null | ||||||
|  |      */ | ||||||
|  |     protected boolean shouldUpdateDiskOffering(String name, String displayText, Integer sortKey, Boolean displayDiskOffering, String tags) { | ||||||
|  |         return StringUtils.isNotBlank(name) || StringUtils.isNotBlank(displayText) || tags != null || sortKey != null || displayDiskOffering != null; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     @Override |     @Override | ||||||
|     @ActionEvent(eventType = EventTypes.EVENT_DISK_OFFERING_DELETE, eventDescription = "deleting disk offering") |     @ActionEvent(eventType = EventTypes.EVENT_DISK_OFFERING_DELETE, eventDescription = "deleting disk offering") | ||||||
|     public boolean deleteDiskOffering(final DeleteDiskOfferingCmd cmd) { |     public boolean deleteDiskOffering(final DeleteDiskOfferingCmd cmd) { | ||||||
|  | |||||||
| @ -24,6 +24,7 @@ import static org.mockito.ArgumentMatchers.anyBoolean; | |||||||
| import static org.mockito.ArgumentMatchers.anyInt; | import static org.mockito.ArgumentMatchers.anyInt; | ||||||
| import static org.mockito.ArgumentMatchers.anyLong; | import static org.mockito.ArgumentMatchers.anyLong; | ||||||
| import static org.mockito.ArgumentMatchers.anyString; | import static org.mockito.ArgumentMatchers.anyString; | ||||||
|  | import static org.mockito.ArgumentMatchers.nullable; | ||||||
| import static org.mockito.Mockito.doNothing; | import static org.mockito.Mockito.doNothing; | ||||||
| import static org.mockito.Mockito.doThrow; | import static org.mockito.Mockito.doThrow; | ||||||
| import static org.mockito.Mockito.mock; | import static org.mockito.Mockito.mock; | ||||||
| @ -56,6 +57,7 @@ import org.mockito.InjectMocks; | |||||||
| import org.mockito.Mock; | import org.mockito.Mock; | ||||||
| import org.mockito.Mockito; | import org.mockito.Mockito; | ||||||
| import org.mockito.MockitoAnnotations; | import org.mockito.MockitoAnnotations; | ||||||
|  | import org.mockito.Spy; | ||||||
| 
 | 
 | ||||||
| import com.cloud.api.query.dao.NetworkOfferingJoinDao; | import com.cloud.api.query.dao.NetworkOfferingJoinDao; | ||||||
| import com.cloud.api.query.vo.NetworkOfferingJoinVO; | import com.cloud.api.query.vo.NetworkOfferingJoinVO; | ||||||
| @ -87,6 +89,7 @@ import com.cloud.network.dao.IPAddressVO; | |||||||
| import com.cloud.network.dao.PhysicalNetworkDao; | import com.cloud.network.dao.PhysicalNetworkDao; | ||||||
| import com.cloud.network.dao.PhysicalNetworkVO; | import com.cloud.network.dao.PhysicalNetworkVO; | ||||||
| import com.cloud.projects.ProjectManager; | import com.cloud.projects.ProjectManager; | ||||||
|  | import com.cloud.storage.DiskOfferingVO; | ||||||
| import com.cloud.storage.VolumeVO; | import com.cloud.storage.VolumeVO; | ||||||
| import com.cloud.storage.dao.VolumeDao; | import com.cloud.storage.dao.VolumeDao; | ||||||
| import com.cloud.user.Account; | import com.cloud.user.Account; | ||||||
| @ -108,6 +111,7 @@ public class ConfigurationManagerTest { | |||||||
| 
 | 
 | ||||||
|     private static final Logger s_logger = Logger.getLogger(ConfigurationManagerTest.class); |     private static final Logger s_logger = Logger.getLogger(ConfigurationManagerTest.class); | ||||||
| 
 | 
 | ||||||
|  |     @Spy | ||||||
|     @InjectMocks |     @InjectMocks | ||||||
|     ConfigurationManagerImpl configurationMgr = new ConfigurationManagerImpl(); |     ConfigurationManagerImpl configurationMgr = new ConfigurationManagerImpl(); | ||||||
| 
 | 
 | ||||||
| @ -163,11 +167,12 @@ public class ConfigurationManagerTest { | |||||||
|     ImageStoreDao _imageStoreDao; |     ImageStoreDao _imageStoreDao; | ||||||
|     @Mock |     @Mock | ||||||
|     ConfigurationDao _configDao; |     ConfigurationDao _configDao; | ||||||
|  |     @Mock | ||||||
|  |     DiskOfferingVO diskOfferingVOMock; | ||||||
| 
 | 
 | ||||||
|     VlanVO vlan = new VlanVO(Vlan.VlanType.VirtualNetwork, "vlantag", "vlangateway", "vlannetmask", 1L, "iprange", 1L, 1L, null, null, null); |     VlanVO vlan = new VlanVO(Vlan.VlanType.VirtualNetwork, "vlantag", "vlangateway", "vlannetmask", 1L, "iprange", 1L, 1L, null, null, null); | ||||||
| 
 | 
 | ||||||
|     private static final String MAXIMUM_DURATION_ALLOWED = "3600"; |     private static final String MAXIMUM_DURATION_ALLOWED = "3600"; | ||||||
| 
 |  | ||||||
|     @Mock |     @Mock | ||||||
|     Network network; |     Network network; | ||||||
|     @Mock |     @Mock | ||||||
| @ -938,4 +943,33 @@ public class ConfigurationManagerTest { | |||||||
|     public void validateMaximumIopsAndBytesLengthTestDefaultLengthConfigs() { |     public void validateMaximumIopsAndBytesLengthTestDefaultLengthConfigs() { | ||||||
|         configurationMgr.validateMaximumIopsAndBytesLength(36000l, 36000l, 36000l, 36000l); |         configurationMgr.validateMaximumIopsAndBytesLength(36000l, 36000l, 36000l, 36000l); | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void shouldUpdateDiskOfferingTests(){ | ||||||
|  |         Assert.assertTrue(configurationMgr.shouldUpdateDiskOffering(Mockito.anyString(), Mockito.anyString(), Mockito.anyInt(), Mockito.anyBoolean(), Mockito.anyString())); | ||||||
|  |         Assert.assertTrue(configurationMgr.shouldUpdateDiskOffering(Mockito.anyString(), nullable(String.class), nullable(Integer.class), nullable(Boolean.class), nullable(String.class))); | ||||||
|  |         Assert.assertTrue(configurationMgr.shouldUpdateDiskOffering(nullable(String.class), Mockito.anyString(), nullable(Integer.class), nullable(Boolean.class), nullable(String.class))); | ||||||
|  |         Assert.assertTrue(configurationMgr.shouldUpdateDiskOffering(nullable(String.class), nullable(String.class), Mockito.anyInt(), nullable(Boolean.class), nullable(String.class))); | ||||||
|  |         Assert.assertTrue(configurationMgr.shouldUpdateDiskOffering(nullable(String.class), nullable(String.class), nullable(int.class), Mockito.anyBoolean(), nullable(String.class))); | ||||||
|  |         Assert.assertTrue(configurationMgr.shouldUpdateDiskOffering(nullable(String.class), nullable(String.class), nullable(int.class), nullable(Boolean.class), Mockito.anyString())); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void shouldUpdateDiskOfferingTestFalse(){ | ||||||
|  |         Assert.assertFalse(configurationMgr.shouldUpdateDiskOffering(null, null, null, null, null)); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Test | ||||||
|  |     public void updateDiskOfferingTagsIfIsNotNullTestWhenTagsIsNull(){ | ||||||
|  |         Mockito.doNothing().when(configurationMgr).updateDiskOfferingTagsIfIsNotNull(null, diskOfferingVOMock); | ||||||
|  |         this.configurationMgr.updateDiskOfferingTagsIfIsNotNull(null, diskOfferingVOMock); | ||||||
|  |         Mockito.verify(configurationMgr, Mockito.times(1)).updateDiskOfferingTagsIfIsNotNull(null, diskOfferingVOMock); | ||||||
|  |     } | ||||||
|  |     @Test | ||||||
|  |     public void updateDiskOfferingTagsIfIsNotNullTestWhenTagsIsNotNull(){ | ||||||
|  |         String tags = "tags"; | ||||||
|  |         Mockito.doNothing().when(configurationMgr).updateDiskOfferingTagsIfIsNotNull(tags, diskOfferingVOMock); | ||||||
|  |         this.configurationMgr.updateDiskOfferingTagsIfIsNotNull(tags, diskOfferingVOMock); | ||||||
|  |         Mockito.verify(configurationMgr, Mockito.times(1)).updateDiskOfferingTagsIfIsNotNull(tags, diskOfferingVOMock); | ||||||
|  |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -2613,7 +2613,8 @@ | |||||||
|                                     var data = { |                                     var data = { | ||||||
|                                         id: args.context.diskOfferings[0].id, |                                         id: args.context.diskOfferings[0].id, | ||||||
|                                         name: args.data.name, |                                         name: args.data.name, | ||||||
|                                         displaytext: args.data.displaytext |                                         displaytext: args.data.displaytext, | ||||||
|  |                                         tags: args.data.tags | ||||||
|                                     }; |                                     }; | ||||||
|                                     $.ajax({ |                                     $.ajax({ | ||||||
|                                         url: createURL('updateDiskOffering'), |                                         url: createURL('updateDiskOffering'), | ||||||
| @ -2939,7 +2940,41 @@ | |||||||
|                                         label: 'label.cache.mode' |                                         label: 'label.cache.mode' | ||||||
|                                     }, |                                     }, | ||||||
|                                     tags: { |                                     tags: { | ||||||
|                                         label: 'label.storage.tags' |                                         label: 'label.storage.tags', | ||||||
|  |                                         docID: 'helpPrimaryStorageTags', | ||||||
|  |                                         isEditable: true, | ||||||
|  |                                         isTokenInput: true, | ||||||
|  |                                         dataProvider: function(args) { | ||||||
|  |                                             $.ajax({ | ||||||
|  |                                                 url: createURL("listStorageTags"), | ||||||
|  |                                                 dataType: "json", | ||||||
|  |                                                 success: function(json) { | ||||||
|  |                                                     var item = json.liststoragetagsresponse.storagetag; | ||||||
|  |                                                     var tags = []; | ||||||
|  | 
 | ||||||
|  |                                                     if (item != null) | ||||||
|  |                                                     { | ||||||
|  |                                                         tags = $.map(item, function(tag) { | ||||||
|  |                                                             return { | ||||||
|  |                                                                 id: tag.name, | ||||||
|  |                                                                 name: tag.name | ||||||
|  |                                                             }; | ||||||
|  |                                                         }); | ||||||
|  |                                                     } | ||||||
|  | 
 | ||||||
|  |                                                     args.response.success({ | ||||||
|  |                                                         data: tags, | ||||||
|  |                                                         hintText: _l('hint.type.part.storage.tag'), | ||||||
|  |                                                         noResultsText: _l('hint.no.storage.tags') | ||||||
|  |                                                     }); | ||||||
|  |                                                 }, | ||||||
|  |                                                 error: function(XMLHttpResponse) { | ||||||
|  |                                                     var errorMsg = parseXMLHttpResponse(XMLHttpResponse); | ||||||
|  | 
 | ||||||
|  |                                                     args.response.error(errorMsg); | ||||||
|  |                                                 } | ||||||
|  |                                             }); | ||||||
|  |                                         } | ||||||
|                                     }, |                                     }, | ||||||
|                                     domain: { |                                     domain: { | ||||||
|                                         label: 'label.domain' |                                         label: 'label.domain' | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user