diff --git a/server/src/main/java/com/cloud/network/router/VpcNetworkHelperImpl.java b/server/src/main/java/com/cloud/network/router/VpcNetworkHelperImpl.java index b4cf809726d..4e49bd0e0a3 100644 --- a/server/src/main/java/com/cloud/network/router/VpcNetworkHelperImpl.java +++ b/server/src/main/java/com/cloud/network/router/VpcNetworkHelperImpl.java @@ -154,14 +154,15 @@ public class VpcNetworkHelperImpl extends NetworkHelperImpl { publicVlans.add(publicIp.getVlanTag()); } } - if (publicNetwork != null) { - if (networks.get(publicNetwork) != null) { - @SuppressWarnings("unchecked") final List publicNicProfiles = (List)networks.get(publicNetwork); - publicNicProfiles.addAll(publicNics); - networks.put(publicNetwork, publicNicProfiles); - } else { - networks.put(publicNetwork, publicNics); - } + } + if (publicNetwork != null) { + if (networks.get(publicNetwork) != null) { + @SuppressWarnings("unchecked") + final List publicNicProfiles = (List)networks.get(publicNetwork); + publicNicProfiles.addAll(publicNics); + networks.put(publicNetwork, publicNicProfiles); + } else { + networks.put(publicNetwork, publicNics); } } @@ -187,4 +188,4 @@ public class VpcNetworkHelperImpl extends NetworkHelperImpl { return networks; } -} \ No newline at end of file +} diff --git a/server/src/main/java/com/cloud/tags/TaggedResourceManagerImpl.java b/server/src/main/java/com/cloud/tags/TaggedResourceManagerImpl.java index 3fdb47f4ede..ae7949863b4 100644 --- a/server/src/main/java/com/cloud/tags/TaggedResourceManagerImpl.java +++ b/server/src/main/java/com/cloud/tags/TaggedResourceManagerImpl.java @@ -85,6 +85,7 @@ import org.apache.commons.collections.MapUtils; import javax.inject.Inject; import javax.naming.ConfigurationException; +import javax.persistence.EntityExistsException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -314,7 +315,11 @@ public class TaggedResourceManagerImpl extends ManagerBase implements TaggedReso } ResourceTagVO resourceTag = new ResourceTagVO(key, value, accountDomainPair.first(), accountDomainPair.second(), id, resourceType, customer, resourceUuid); - resourceTag = _resourceTagDao.persist(resourceTag); + try { + resourceTag = _resourceTagDao.persist(resourceTag); + } catch (EntityExistsException e) { + throw new CloudRuntimeException(String.format("tag %s already on %s with id %s", resourceTag.getKey(), resourceType.toString(), resourceId),e); + } resourceTags.add(resourceTag); } } diff --git a/test/integration/component/test_tags.py b/test/integration/component/test_tags.py index 11a0bbad196..9180e7b9256 100644 --- a/test/integration/component/test_tags.py +++ b/test/integration/component/test_tags.py @@ -2989,3 +2989,83 @@ class TestResourceTags(cloudstackTestCase): self.fail("User1 has access to create tags for User2.") return + + @attr(tags=["advanced", "basic"], required_hardware="false") + def test_33_duplicate_vm_tag(self): + """ + Test creation of a duplicate tag on UserVM and verify error return. + cleanup by deleting + """ + # Validate the following + # 1. Create a tag on VM using createTags API + # 2. Create the same tag on VM using createTags API + # 3. check the return for the right error message + + tag_key = 'scope' + tag_value = 'test_33_duplicate_vm_tag' + + self.debug("Creating a tag for user VM") + # use vm_2 as vm_1 is deleted in other tests :( + tag = Tag.create( + self.apiclient, + resourceIds=self.vm_2.id, + resourceType='userVM', + tags={tag_key: tag_value} + ) + self.debug("Tag created: %s" % tag.__dict__) + + self.debug("Trying second tag witgh the same key for user VM") + try: + erronousTag = Tag.create( + self.apiclient, + resourceIds=self.vm_2.id, + resourceType='userVM', + tags={tag_key: tag_value} + ) + except Exception as e: + # verify e.message + assert "tag scope already on UserVm with id" in e.message, \ + "neat error message missing from error result" + pass + + + # we should still find the tag + vms = VirtualMachine.list( + self.apiclient, + listall=True, + key=tag_key, + value=tag_value + ) + + self.assertEqual( + isinstance(vms, list), + True, + "Tag based VMs listing failed") + + self.debug("Deleting the created tag..") + try: + Tag.delete( + self.apiclient, + resourceIds=self.vm_2.id, + resourceType='userVM', + tags={tag_key: tag_value} + ) + except Exception as e: + self.fail("Failed to delete the tag - %s" % e) + + self.debug("Verifying if tag is actually deleted!") + tags = Tag.list( + self.apiclient, + listall=True, + resourceType='userVM', + account=self.account.name, + domainid=self.account.domainid, + key=tag_key, + value=tag_value + ) + self.assertEqual( + tags, + None, + "List tags should return empty response" + ) + return diff --git a/ui/scripts/ui/widgets/listView.js b/ui/scripts/ui/widgets/listView.js index 4a5d2016f1a..69a5c7a7f47 100644 --- a/ui/scripts/ui/widgets/listView.js +++ b/ui/scripts/ui/widgets/listView.js @@ -2497,6 +2497,8 @@ this.data('view-args').sections[activeSection].listView : this.data('view-args').listView; + toggleMultiSelectActions(this, false); + loadBody( this.find('table:last'), listViewArgs.dataProvider,