This is an automated email from the ASF dual-hosted git repository.

rohit pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cloudstack.git


The following commit(s) were added to refs/heads/master by this push:
     new a86160b  Cloudstack 10170: Fix resource tags security bugs and add 
account tags support (#2350)
a86160b is described below

commit a86160b389057e6f7241f49313c031db0b079a4f
Author: Bitworks Software, Ltd <[email protected]>
AuthorDate: Tue Jan 9 15:25:34 2018 +0700

    Cloudstack 10170: Fix resource tags security bugs and add account tags 
support (#2350)
    
    This PR introduces several features and fixes some bugs:
    - account tags feature
    - fixed resource tags bugs which happened during tags search (found wrong 
entries because of mysql string to number translation - see #905, but this PR 
does more and fixes also resource access - vulnerability during list resource 
tags)
    - some marvin improvements (speed, sanity)
    
    Improved resource tags code:
    1. Enhanced listTags security
    2. Added support for account tags (account tags are required to support 
tags common for all users of an account)
    3. Improved the tag management code (refactoring and cleanup)
    
    Marvin:
    1. Fixed Marvin wait timeout between async pools. To decrease polling 
interval and improve CI speed.
    2. Fixed /tmp/ to /tmp in zone configuration files.
    3. Fixed + to os.path.join in log class.
    4. Fixed + to os.path.join in deployDataCenter class.
    5. Fixed typos in tag tests.
    6. Modified Tags base class delete method.
    
    Deploy Datacenter script:
    1. Improved deployDatacenter. Added option logdir to specify where script 
places results of evaluation.
    
    ConfigurationManagerImpl:
    1. Added logging to ConfigurationManagerImpl to log when vlan is not found. 
Added test stubs for tags. Found accidental exception during simulator running 
after CI.
    
    tests_tags.py:
    1. Fixed stale undeleted tags.
    2. Changed region:India to scope:TestName.
---
 api/src/com/cloud/server/ResourceTag.java          |   1 +
 .../configuration/ConfigurationManagerImpl.java    |   3 +
 .../com/cloud/tags/TaggedResourceManagerImpl.java  | 174 ++---
 setup/dev/advanced.cfg                             |   2 +-
 setup/dev/advancedsg.cfg                           |   2 +-
 setup/dev/basic.cfg                                |   2 +-
 setup/dev/local.cfg                                |   2 +-
 setup/dev/s3.cfg                                   |   2 +-
 test/integration/component/test_tags.py            | 719 ++++++++++++++++-----
 tools/marvin/marvin/cloudstackConnection.py        |   4 +-
 tools/marvin/marvin/deployDataCenter.py            |  55 +-
 tools/marvin/marvin/lib/base.py                    |   3 +-
 tools/marvin/marvin/marvinLog.py                   |  36 +-
 13 files changed, 740 insertions(+), 265 deletions(-)

diff --git a/api/src/com/cloud/server/ResourceTag.java 
b/api/src/com/cloud/server/ResourceTag.java
index 067cb97..0bd5d73 100644
--- a/api/src/com/cloud/server/ResourceTag.java
+++ b/api/src/com/cloud/server/ResourceTag.java
@@ -38,6 +38,7 @@ public interface ResourceTag extends ControlledEntity, 
Identity, InternalIdentit
         SecurityGroupRule(true, false),
         PublicIpAddress(true, true),
         Project(true, false),
+        Account(true, false),
         Vpc(true, true),
         NetworkACL(true, true),
         StaticRoute(true, false),
diff --git a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java 
b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java
index 412ca5b..1632da9 100755
--- a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java
+++ b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java
@@ -3804,6 +3804,9 @@ public class ConfigurationManagerImpl extends ManagerBase 
implements Configurati
     @DB
     public boolean releasePublicIpRange(final long vlanDbId, final long 
userId, final Account caller) {
         VlanVO vlan = _vlanDao.findById(vlanDbId);
+        if(vlan == null) {
+            s_logger.warn("VLAN information for Account '" + caller + "', User 
'" + userId + "' VLAN '" + vlanDbId + "' is null. This is NPE situation.");
+        }
 
         // Verify range is dedicated
         boolean isAccountSpecific = false;
diff --git a/server/src/com/cloud/tags/TaggedResourceManagerImpl.java 
b/server/src/com/cloud/tags/TaggedResourceManagerImpl.java
index 9373a08..9803ce7 100644
--- a/server/src/com/cloud/tags/TaggedResourceManagerImpl.java
+++ b/server/src/com/cloud/tags/TaggedResourceManagerImpl.java
@@ -16,28 +16,13 @@
 // under the License.
 package com.cloud.tags;
 
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import javax.inject.Inject;
-import javax.naming.ConfigurationException;
-
-import org.apache.cloudstack.api.Identity;
-import org.apache.cloudstack.api.InternalIdentity;
-import org.apache.cloudstack.context.CallContext;
-import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
-import org.apache.commons.lang.StringUtils;
-import org.apache.log4j.Logger;
-
-import com.cloud.api.query.dao.ResourceTagJoinDao;
 import com.cloud.dc.DataCenterVO;
 import com.cloud.domain.PartOf;
 import com.cloud.event.ActionEvent;
 import com.cloud.event.EventTypes;
 import com.cloud.exception.InvalidParameterValueException;
 import com.cloud.exception.PermissionDeniedException;
+import com.cloud.offerings.NetworkOfferingVO;
 import com.cloud.network.LBHealthCheckPolicyVO;
 import com.cloud.network.as.AutoScaleVmGroupVO;
 import com.cloud.network.as.AutoScaleVmProfileVO;
@@ -58,7 +43,6 @@ import com.cloud.network.vpc.NetworkACLVO;
 import com.cloud.network.vpc.StaticRouteVO;
 import com.cloud.network.vpc.VpcOfferingVO;
 import com.cloud.network.vpc.VpcVO;
-import com.cloud.offerings.NetworkOfferingVO;
 import com.cloud.projects.ProjectVO;
 import com.cloud.server.ResourceTag;
 import com.cloud.server.ResourceTag.ResourceObjectType;
@@ -72,6 +56,7 @@ import com.cloud.storage.VolumeVO;
 import com.cloud.tags.dao.ResourceTagDao;
 import com.cloud.user.Account;
 import com.cloud.user.AccountManager;
+import com.cloud.user.AccountVO;
 import com.cloud.user.DomainManager;
 import com.cloud.user.OwnedBy;
 import com.cloud.user.UserVO;
@@ -89,11 +74,28 @@ import com.cloud.utils.exception.CloudRuntimeException;
 import com.cloud.vm.NicVO;
 import com.cloud.vm.UserVmVO;
 import com.cloud.vm.snapshot.VMSnapshotVO;
+import org.apache.cloudstack.api.Identity;
+import org.apache.cloudstack.api.InternalIdentity;
+import org.apache.cloudstack.context.CallContext;
+import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
+import org.apache.commons.lang.StringUtils;
+import org.apache.log4j.Logger;
+
+import org.apache.commons.collections.MapUtils;
+
+import javax.inject.Inject;
+import javax.naming.ConfigurationException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.stream.Collectors;
 
 public class TaggedResourceManagerImpl extends ManagerBase implements 
TaggedResourceService {
     public static final Logger s_logger = 
Logger.getLogger(TaggedResourceManagerImpl.class);
 
-    private static final Map<ResourceObjectType, Class<?>> s_typeMap = new 
HashMap<ResourceObjectType, Class<?>>();
+    private static final Map<ResourceObjectType, Class<?>> s_typeMap = new 
HashMap<>();
     static {
         s_typeMap.put(ResourceObjectType.UserVm, UserVmVO.class);
         s_typeMap.put(ResourceObjectType.Volume, VolumeVO.class);
@@ -108,6 +110,7 @@ public class TaggedResourceManagerImpl extends ManagerBase 
implements TaggedReso
         s_typeMap.put(ResourceObjectType.SecurityGroupRule, 
SecurityGroupRuleVO.class);
         s_typeMap.put(ResourceObjectType.PublicIpAddress, IPAddressVO.class);
         s_typeMap.put(ResourceObjectType.Project, ProjectVO.class);
+        s_typeMap.put(ResourceObjectType.Account, AccountVO.class);
         s_typeMap.put(ResourceObjectType.Vpc, VpcVO.class);
         s_typeMap.put(ResourceObjectType.Nic, NicVO.class);
         s_typeMap.put(ResourceObjectType.NetworkACL, NetworkACLItemVO.class);
@@ -140,8 +143,6 @@ public class TaggedResourceManagerImpl extends ManagerBase 
implements TaggedReso
     @Inject
     ResourceTagDao _resourceTagDao;
     @Inject
-    ResourceTagJoinDao _resourceTagJoinDao;
-    @Inject
     DomainManager _domainMgr;
     @Inject
     AccountDao _accountDao;
@@ -194,6 +195,12 @@ public class TaggedResourceManagerImpl extends ManagerBase 
implements TaggedReso
             domainId = ((SecurityGroupVO)SecurityGroup).getDomainId();
         }
 
+        if (resourceType == ResourceObjectType.Account) {
+            AccountVO account = (AccountVO)entity;
+            accountId = account.getId();
+            domainId = account.getDomainId();
+        }
+
         // if the resource type is network acl, get the accountId and domainId 
from VPC following: NetworkACLItem -> NetworkACL -> VPC
         if (resourceType == ResourceObjectType.NetworkACL) {
             NetworkACLItemVO aclItem = (NetworkACLItemVO)entity;
@@ -223,7 +230,23 @@ public class TaggedResourceManagerImpl extends ManagerBase 
implements TaggedReso
         if ((domainId == null) || ((accountId != null) && 
(domainId.longValue() == -1))) {
             domainId = _accountDao.getDomainIdForGivenAccountId(accountId);
         }
-        return new Pair<Long, Long>(accountId, domainId);
+        return new Pair<>(accountId, domainId);
+    }
+
+    private void checkResourceAccessible(Long accountId, Long domainId, String 
exceptionMessage) {
+        Account caller = CallContext.current().getCallingAccount();
+        if (Objects.equals(domainId, -1))
+        {
+            throw new CloudRuntimeException("Invalid DomainId: -1");
+        }
+        if (accountId != null) {
+            _accountMgr.checkAccess(caller, null, false, 
_accountMgr.getAccount(accountId));
+        } else if (domainId != null && 
!_accountMgr.isNormalUser(caller.getId())) {
+            //check permissions;
+            _accountMgr.checkAccess(caller, _domainMgr.getDomain(domainId));
+        } else {
+            throw new PermissionDeniedException(exceptionMessage);
+        }
     }
 
     @Override
@@ -238,12 +261,28 @@ public class TaggedResourceManagerImpl extends 
ManagerBase implements TaggedReso
     }
 
     @Override
+    public String getUuid(String resourceId, ResourceObjectType resourceType) {
+        if (!StringUtils.isNumeric(resourceId)) {
+            return resourceId;
+        }
+
+        Class<?> clazz = s_typeMap.get(resourceType);
+
+        Object entity = _entityMgr.findById(clazz, resourceId);
+        if (entity != null && entity instanceof Identity) {
+            return ((Identity)entity).getUuid();
+        }
+
+        return resourceId;
+    }
+
+    @Override
     @DB
     @ActionEvent(eventType = EventTypes.EVENT_TAGS_CREATE, eventDescription = 
"creating resource tags")
     public List<ResourceTag> createTags(final List<String> resourceIds, final 
ResourceObjectType resourceType, final Map<String, String> tags, final String 
customer) {
         final Account caller = CallContext.current().getCallingAccount();
 
-        final List<ResourceTag> resourceTags = new 
ArrayList<ResourceTag>(tags.size());
+        final List<ResourceTag> resourceTags = new ArrayList<>(tags.size());
 
         Transaction.execute(new TransactionCallbackNoReturn() {
             @Override
@@ -261,17 +300,8 @@ public class TaggedResourceManagerImpl extends ManagerBase 
implements TaggedReso
                         Long domainId = accountDomainPair.second();
                         Long accountId = accountDomainPair.first();
 
-                        if ((domainId != null) && (domainId == -1)) {
-                            throw new CloudRuntimeException("Invalid DomainId 
: -1");
-                        }
-                        if (accountId != null) {
-                            _accountMgr.checkAccess(caller, null, false, 
_accountMgr.getAccount(accountId));
-                        } else if (domainId != null && 
!_accountMgr.isNormalUser(caller.getId())) {
-                            //check permissions;
-                            _accountMgr.checkAccess(caller, 
_domainMgr.getDomain(domainId));
-                        } else {
-                            throw new PermissionDeniedException("Account " + 
caller + " doesn't have permissions to create tags" + " for resource " + key);
-                        }
+                        checkResourceAccessible(accountId, domainId, "Account 
'" + caller +
+                                "' doesn't have permissions to create tags" + 
" for resource '" + id + "(" + key + ")'.");
 
                         String value = tags.get(key);
 
@@ -290,20 +320,16 @@ public class TaggedResourceManagerImpl extends 
ManagerBase implements TaggedReso
         return resourceTags;
     }
 
-    @Override
-    public String getUuid(String resourceId, ResourceObjectType resourceType) {
-        if (!StringUtils.isNumeric(resourceId)) {
-            return resourceId;
-        }
-
-        Class<?> clazz = s_typeMap.get(resourceType);
-
-        Object entity = _entityMgr.findById(clazz, resourceId);
-        if (entity != null && entity instanceof Identity) {
-            return ((Identity)entity).getUuid();
-        }
+    private List<? extends ResourceTag> searchResourceTags(List<String> 
resourceIds, ResourceObjectType resourceType) {
+        List<String> resourceUuids = resourceIds.stream().map(resourceId -> 
getUuid(resourceId, resourceType)).collect(Collectors.toList());
+        SearchBuilder<ResourceTagVO> sb = 
_resourceTagDao.createSearchBuilder();
+        sb.and("resourceUuid", sb.entity().getResourceUuid(), 
SearchCriteria.Op.IN);
+        sb.and("resourceType", sb.entity().getResourceType(), 
SearchCriteria.Op.EQ);
 
-        return resourceId;
+        SearchCriteria<ResourceTagVO> sc = sb.create();
+        sc.setParameters("resourceUuid", resourceUuids.toArray());
+        sc.setParameters("resourceType", resourceType);
+        return _resourceTagDao.search(sc, null);
     }
 
     @Override
@@ -311,62 +337,60 @@ public class TaggedResourceManagerImpl extends 
ManagerBase implements TaggedReso
     @ActionEvent(eventType = EventTypes.EVENT_TAGS_DELETE, eventDescription = 
"deleting resource tags")
     public boolean deleteTags(List<String> resourceIds, ResourceObjectType 
resourceType, Map<String, String> tags) {
         Account caller = CallContext.current().getCallingAccount();
-
-        SearchBuilder<ResourceTagVO> sb = 
_resourceTagDao.createSearchBuilder();
-        sb.and().op("resourceId", sb.entity().getResourceId(), 
SearchCriteria.Op.IN);
-        sb.or("resourceUuid", sb.entity().getResourceUuid(), 
SearchCriteria.Op.IN);
-        sb.cp();
-        sb.and("resourceType", sb.entity().getResourceType(), 
SearchCriteria.Op.EQ);
-
-        SearchCriteria<ResourceTagVO> sc = sb.create();
-        sc.setParameters("resourceId", resourceIds.toArray());
-        sc.setParameters("resourceUuid", resourceIds.toArray());
-        sc.setParameters("resourceType", resourceType);
-
-        List<? extends ResourceTag> resourceTags = _resourceTagDao.search(sc, 
null);
-        ;
-        final List<ResourceTag> tagsToRemove = new ArrayList<ResourceTag>();
+        if(s_logger.isDebugEnabled()) {
+            s_logger.debug("ResourceIds to Find " + String.join(", ", 
resourceIds));
+        }
+        List<? extends ResourceTag> resourceTags = 
searchResourceTags(resourceIds, resourceType);
+        final List<ResourceTag> tagsToDelete = new ArrayList<>();
 
         // Finalize which tags should be removed
         for (ResourceTag resourceTag : resourceTags) {
             //1) validate the permissions
+            if(s_logger.isDebugEnabled()) {
+                s_logger.debug("Resource Tag Id: " + 
resourceTag.getResourceId());
+                s_logger.debug("Resource Tag AccountId: " + 
resourceTag.getAccountId());
+            }
             Account owner = _accountMgr.getAccount(resourceTag.getAccountId());
+            if(s_logger.isDebugEnabled()) {
+                s_logger.debug("Resource Owner: " + owner);
+            }
             _accountMgr.checkAccess(caller, null, false, owner);
             //2) Only remove tag if it matches key value pairs
-            if (tags != null && !tags.isEmpty()) {
+            if (MapUtils.isEmpty(tags)) {
+                tagsToDelete.add(resourceTag);
+            } else {
                 for (String key : tags.keySet()) {
-                    boolean canBeRemoved = false;
+                    boolean deleteTag = false;
                     if (resourceTag.getKey().equalsIgnoreCase(key)) {
                         String value = tags.get(key);
                         if (value != null) {
                             if 
(resourceTag.getValue().equalsIgnoreCase(value)) {
-                                canBeRemoved = true;
+                                deleteTag = true;
                             }
                         } else {
-                            canBeRemoved = true;
+                            deleteTag = true;
                         }
-                        if (canBeRemoved) {
-                            tagsToRemove.add(resourceTag);
+                        if (deleteTag) {
+                            tagsToDelete.add(resourceTag);
                             break;
                         }
                     }
                 }
-            } else {
-                tagsToRemove.add(resourceTag);
             }
         }
 
-        if (tagsToRemove.isEmpty()) {
-            throw new InvalidParameterValueException("Unable to find tags by 
parameters specified");
+        if (tagsToDelete.isEmpty()) {
+            throw new InvalidParameterValueException("Unable to find any tags 
which conform to specified delete parameters.");
         }
 
         //Remove the tags
         Transaction.execute(new TransactionCallbackNoReturn() {
             @Override
             public void doInTransactionWithoutResult(TransactionStatus status) 
{
-                for (ResourceTag tagToRemove : tagsToRemove) {
+                for (ResourceTag tagToRemove : tagsToDelete) {
                     _resourceTagDao.remove(tagToRemove.getId());
-                    s_logger.debug("Removed the tag " + tagToRemove);
+                    s_logger.debug("Removed the tag '" + tagToRemove + "' for 
resources (" +
+                            String.join(", ", resourceIds) + ")");
                 }
             }
         });
@@ -375,7 +399,7 @@ public class TaggedResourceManagerImpl extends ManagerBase 
implements TaggedReso
     }
 
     @Override
-    public List<? extends ResourceTag> 
listByResourceTypeAndId(ResourceObjectType type, long resourceId) {
-        return _resourceTagDao.listBy(resourceId, type);
+    public List<? extends ResourceTag> 
listByResourceTypeAndId(ResourceObjectType resourceType, long resourceId) {
+        return _resourceTagDao.listBy(resourceId, resourceType);
     }
 }
diff --git a/setup/dev/advanced.cfg b/setup/dev/advanced.cfg
index d5762c3..d458b01 100644
--- a/setup/dev/advanced.cfg
+++ b/setup/dev/advanced.cfg
@@ -154,7 +154,7 @@
     },
     "logger":
         {
-            "LogFolderPath": "/tmp/"
+            "LogFolderPath": "/tmp"
         },
     "globalConfig": [
         {
diff --git a/setup/dev/advancedsg.cfg b/setup/dev/advancedsg.cfg
index 01f7fcc..5fbd02e 100644
--- a/setup/dev/advancedsg.cfg
+++ b/setup/dev/advancedsg.cfg
@@ -109,7 +109,7 @@
     },
     "logger": 
         {
-            "LogFolderPath": "/tmp/"
+            "LogFolderPath": "/tmp"
         },
     "globalConfig": [
         {
diff --git a/setup/dev/basic.cfg b/setup/dev/basic.cfg
index db8c59b..b7f1486 100644
--- a/setup/dev/basic.cfg
+++ b/setup/dev/basic.cfg
@@ -110,7 +110,7 @@
     },
     "logger": 
         {
-            "LogFolderPath": "/tmp/"
+            "LogFolderPath": "/tmp"
         },
     "globalConfig": [
         {
diff --git a/setup/dev/local.cfg b/setup/dev/local.cfg
index 89d56a5..954d75f 100644
--- a/setup/dev/local.cfg
+++ b/setup/dev/local.cfg
@@ -25,7 +25,7 @@
     },
     "logger":
     {
-            "LogFolderPath": "/tmp/"
+            "LogFolderPath": "/tmp"
     },
     "mgtSvr": [
         {
diff --git a/setup/dev/s3.cfg b/setup/dev/s3.cfg
index a865e0d..de28e5b 100644
--- a/setup/dev/s3.cfg
+++ b/setup/dev/s3.cfg
@@ -115,7 +115,7 @@
     ],
     "logger":
     {
-            "LogFolderPath": "/tmp/"
+            "LogFolderPath": "/tmp"
     },
     "mgtSvr": [
         {
diff --git a/test/integration/component/test_tags.py 
b/test/integration/component/test_tags.py
index f9b0655..ed1aee7 100644
--- a/test/integration/component/test_tags.py
+++ b/test/integration/component/test_tags.py
@@ -185,9 +185,9 @@ class Services:
                 "cidrlist": '0.0.0.0/0',
             },
             # Cent OS 5.3 (64 bit)
-            "sleep": 60,
+            "sleep": 5,
             "ostype": 'CentOS 5.3 (64-bit)',
-            "timeout": 10,
+            "timeout": 5,
             "mode": 'advanced',
         }
 
@@ -287,10 +287,12 @@ class TestResourceTags(cloudstackTestCase):
             raise Exception("Warning: Exception during cleanup : %s" % e)
 
         for tag in self.rm_tags:
-            tag['tag_obj'].delete(self.apiclient, tag['resid'],
-                                  tag['restype'],
-                                  {tag['key']: tag['value']})
-
+            for concrete_tag in tag['tags']:
+                Tag.delete(self.apiclient,
+                           tag['resid'],
+                           tag['restype'],
+                           {concrete_tag['key']: concrete_tag['value']})
+                
         return
 
     @attr(tags=["advanced"], required_hardware="false")
@@ -404,7 +406,7 @@ class TestResourceTags(cloudstackTestCase):
 
         self.debug("Deleting the created tag..")
         try:
-            tag.delete(
+            Tag.delete(
                 self.apiclient,
                 resourceIds=lb_rule.id,
                 resourceType='LoadBalancer',
@@ -541,7 +543,7 @@ class TestResourceTags(cloudstackTestCase):
 
         self.debug("Deleting the created tag..")
         try:
-            tag.delete(
+            Tag.delete(
                 self.apiclient,
                 resourceIds=nat_rule.id,
                 resourceType='portForwardingRule',
@@ -683,7 +685,7 @@ class TestResourceTags(cloudstackTestCase):
 
         self.debug("Deleting the created tag..")
         try:
-            tag.delete(
+            Tag.delete(
                 self.apiclient,
                 resourceIds=fw_rule.id,
                 resourceType='FirewallRule',
@@ -835,7 +837,7 @@ class TestResourceTags(cloudstackTestCase):
         )
         self.debug("Deleting the created tag..")
         try:
-            tag.delete(
+            Tag.delete(
                 self.apiclient,
                 resourceIds=vpn.id,
                 resourceType='VPN',
@@ -876,12 +878,15 @@ class TestResourceTags(cloudstackTestCase):
         # 1. Create  a tag on VM using createTags API
         # 2. Delete above created tag using deleteTags API
 
+        tag_key = 'scope'
+        tag_value = 'test_05_vm_tag'
+        
         self.debug("Creating a tag for user VM")
         tag = Tag.create(
             self.apiclient,
             resourceIds=self.vm_1.id,
             resourceType='userVM',
-            tags={'region': 'India'}
+            tags={tag_key: tag_value}
         )
         self.debug("Tag created: %s" % tag.__dict__)
 
@@ -891,8 +896,8 @@ class TestResourceTags(cloudstackTestCase):
             resourceType='userVM',
             account=self.account.name,
             domainid=self.account.domainid,
-            key='region',
-            value='India'
+            key=tag_key,
+            value=tag_value
         )
         self.assertEqual(
             isinstance(tags, list),
@@ -901,15 +906,15 @@ class TestResourceTags(cloudstackTestCase):
         )
         self.assertEqual(
             tags[0].value,
-            'India',
+            tag_value,
             "The tag value should match with the original value"
         )
 
         vms = VirtualMachine.list(
             self.apiclient,
             listall=True,
-            key='region',
-            value='India'
+            key=tag_key,
+            value=tag_value
         )
 
         self.assertEqual(
@@ -919,11 +924,11 @@ class TestResourceTags(cloudstackTestCase):
 
         self.debug("Deleting the created tag..")
         try:
-            tag.delete(
+            Tag.delete(
                 self.apiclient,
                 resourceIds=self.vm_1.id,
                 resourceType='userVM',
-                tags={'region': 'India'}
+                tags={tag_key: tag_value}
             )
         except Exception as e:
             self.fail("Failed to delete the tag - %s" % e)
@@ -935,8 +940,8 @@ class TestResourceTags(cloudstackTestCase):
             resourceType='userVM',
             account=self.account.name,
             domainid=self.account.domainid,
-            key='region',
-            value='India'
+            key=tag_key,
+            value=tag_value
         )
         self.assertEqual(
             tags,
@@ -1031,7 +1036,7 @@ class TestResourceTags(cloudstackTestCase):
 
         self.debug("Deleting the created tag..")
         try:
-            tag.delete(
+            Tag.delete(
                 self.user_api_client,
                 resourceIds=template.id,
                 resourceType='Template',
@@ -1124,7 +1129,7 @@ class TestResourceTags(cloudstackTestCase):
 
         self.debug("Deleting the created tag..")
         try:
-            tag.delete(
+            Tag.delete(
                 self.apiclient,
                 resourceIds=iso.id,
                 resourceType='ISO',
@@ -1152,12 +1157,15 @@ class TestResourceTags(cloudstackTestCase):
 
     @attr(tags=["advanced", "basic"], required_hardware="false")
     def test_08_volume_tag(self):
-        """ Test creation, listing and deletion tagson volume
+        """ Test creation, listing and deletion tags on volume
         """
         # Validate the following
         # 1. Create a tag on volume using createTags API
         # 2. Delete above created tag using deleteTags API
 
+        tag_key = 'scope'
+        tag_value = 'test_08_volume_tag'
+        
         if self.hypervisor.lower() == 'lxc':
             if not find_storage_pool_type(self.apiclient, storagetype='rbd'):
                 self.skipTest("RBD storage type is required for data volumes 
for LXC")
@@ -1181,7 +1189,7 @@ class TestResourceTags(cloudstackTestCase):
             self.apiclient,
             resourceIds=volume.id,
             resourceType='volume',
-            tags={'region': 'India'}
+            tags={tag_key: tag_value}
         )
         self.debug("Tag created: %s" % tag.__dict__)
 
@@ -1191,8 +1199,8 @@ class TestResourceTags(cloudstackTestCase):
             resourceType='volume',
             account=self.account.name,
             domainid=self.account.domainid,
-            key='region',
-            value='India'
+            key=tag_key,
+            value=tag_value
         )
         self.assertEqual(
             isinstance(tags, list),
@@ -1201,14 +1209,14 @@ class TestResourceTags(cloudstackTestCase):
         )
         self.assertEqual(
             tags[0].value,
-            'India',
+            tag_value,
             'The tag should have original value'
         )
 
         vols = Volume.list(self.apiclient,
                            listall=True,
-                           key='region',
-                           value='India'
+                           key=tag_key,
+                           value=tag_value
                            )
         self.assertEqual(
             isinstance(vols, list),
@@ -1218,11 +1226,11 @@ class TestResourceTags(cloudstackTestCase):
 
         self.debug("Deleting the created tag..")
         try:
-            tag.delete(
+            Tag.delete(
                 self.apiclient,
                 resourceIds=volume.id,
                 resourceType='volume',
-                tags={'region': 'India'}
+                tags={tag_key: tag_value}
             )
         except Exception as e:
             self.fail("Failed to delete the tag - %s" % e)
@@ -1234,7 +1242,7 @@ class TestResourceTags(cloudstackTestCase):
             resourceType='volume',
             account=self.account.name,
             domainid=self.account.domainid,
-            key='region'
+            key=tag_key
         )
         self.assertEqual(
             tags,
@@ -1245,7 +1253,7 @@ class TestResourceTags(cloudstackTestCase):
 
     @attr(tags=["advanced", "basic"], required_hardware="false")
     def test_09_snapshot_tag(self):
-        """ Test creation, listing and deletion tag son snapshot
+        """ Test creation, listing and deletion tags on snapshot
         """
         # Validate the following
         # 1. Create a tag on snapshot using createTags API
@@ -1321,7 +1329,7 @@ class TestResourceTags(cloudstackTestCase):
 
         self.debug("Deleting the created tag..")
         try:
-            tag.delete(
+            Tag.delete(
                 self.apiclient,
                 resourceIds=snapshot.id,
                 resourceType='snapshot',
@@ -1350,12 +1358,15 @@ class TestResourceTags(cloudstackTestCase):
 
     @attr(tags=["advanced"], required_hardware="false")
     def test_10_network_tag(self):
-        """ Testcreation, listing and deletion tags on guest network
+        """ Test creation, listing and deletion tags on guest network
         """
         # Validate the following
         # 1. Create  a tag on Network using createTags API
         # 2. Delete above created tag using deleteTags API
 
+        tag_key = 'scope'
+        tag_value = 'test_10_network_tag'
+        
         self.debug("Fetching the network details for account: %s" %
                    self.account.name)
         networks = Network.list(
@@ -1378,7 +1389,7 @@ class TestResourceTags(cloudstackTestCase):
             self.apiclient,
             resourceIds=network.id,
             resourceType='Network',
-            tags={'region': 'India'}
+            tags={tag_key: tag_value}
         )
         self.debug("Tag created: %s" % tag.__dict__)
 
@@ -1388,8 +1399,8 @@ class TestResourceTags(cloudstackTestCase):
             resourceType='Network',
             account=self.account.name,
             domainid=self.account.domainid,
-            key='region',
-            value='India'
+            key=tag_key,
+            value=tag_value
         )
         self.assertEqual(
             isinstance(tags, list),
@@ -1398,7 +1409,7 @@ class TestResourceTags(cloudstackTestCase):
         )
         self.assertEqual(
             tags[0].value,
-            'India',
+            tag_value,
             'The tag should have original value'
         )
 
@@ -1407,8 +1418,8 @@ class TestResourceTags(cloudstackTestCase):
             account=self.account.name,
             domainid=self.account.domainid,
             listall=True,
-            key='region',
-            value='India'
+            key=tag_key,
+            value=tag_value
         )
         self.assertEqual(
             isinstance(networks, list),
@@ -1418,11 +1429,11 @@ class TestResourceTags(cloudstackTestCase):
 
         self.debug("Deleting the created tag..")
         try:
-            tag.delete(
+            Tag.delete(
                 self.apiclient,
                 resourceIds=network.id,
                 resourceType='Network',
-                tags={'region': 'India'}
+                tags={tag_key: tag_value}
             )
         except Exception as e:
             self.fail("Failed to delete the tag - %s" % e)
@@ -1434,8 +1445,8 @@ class TestResourceTags(cloudstackTestCase):
             resourceType='Network',
             account=self.account.name,
             domainid=self.account.domainid,
-            key='region',
-            value='India'
+            key=tag_key,
+            value=tag_value
         )
         self.assertEqual(
             tags,
@@ -1452,6 +1463,9 @@ class TestResourceTags(cloudstackTestCase):
         # 1. Create a tag on VM using createTags API
         # 2. Delete above created tag using deleteTags API
 
+        tag_key = 'scope'
+        tag_value = 'test_11_migrate_tagged_vm_del'
+        
         if self.hypervisor.lower() in ['lxc']:
             self.skipTest("vm migrate feature is not supported on %s" % 
self.hypervisor.lower())
 
@@ -1496,7 +1510,7 @@ class TestResourceTags(cloudstackTestCase):
             self.apiclient,
             resourceIds=self.vm_1.id,
             resourceType='userVM',
-            tags={'region': 'India'}
+            tags={tag_key: tag_value}
         )
         self.debug("Tag created: %s" % tag.__dict__)
 
@@ -1506,8 +1520,8 @@ class TestResourceTags(cloudstackTestCase):
             resourceType='userVM',
             account=self.account.name,
             domainid=self.account.domainid,
-            key='region',
-            value='India'
+            key=tag_key,
+            value=tag_value
         )
         self.assertEqual(
             isinstance(tags, list),
@@ -1517,7 +1531,7 @@ class TestResourceTags(cloudstackTestCase):
 
         self.assertEqual(
             tags[0].value,
-            'India',
+            tag_value,
             'The tag should have original value'
         )
 
@@ -1527,11 +1541,11 @@ class TestResourceTags(cloudstackTestCase):
 
         self.debug("Deleting the created tag..")
         try:
-            tag.delete(
+            Tag.delete(
                 self.apiclient,
                 resourceIds=self.vm_1.id,
                 resourceType='userVM',
-                tags={'region': 'India'}
+                tags={tag_key: tag_value}
             )
         except Exception as e:
             self.fail("Failed to delete the tag - %s" % e)
@@ -1543,8 +1557,8 @@ class TestResourceTags(cloudstackTestCase):
             resourceType='userVM',
             account=self.account.name,
             domainid=self.account.domainid,
-            key='region',
-            value='India'
+            key=tag_key,
+            value=tag_value
         )
         self.assertEqual(
             tags,
@@ -1562,12 +1576,15 @@ class TestResourceTags(cloudstackTestCase):
         # 2. Add same tag in upper case.
         # 3. Verify that tag creation failed.
 
+        tag_key = 'scope'
+        tag_value = 'test_13_tag_case_insensitive'
+        
         self.debug("Creating a tag for user VM")
         tag_1 = Tag.create(
             self.apiclient,
             resourceIds=self.vm_1.id,
             resourceType='userVM',
-            tags={'region': 'India'}
+            tags={tag_key: tag_value}
         )
         self.debug("Tag created: %s" % tag_1.__dict__)
 
@@ -1577,8 +1594,8 @@ class TestResourceTags(cloudstackTestCase):
             resourceType='userVM',
             account=self.account.name,
             domainid=self.account.domainid,
-            key='region',
-            value='India'
+            key=tag_key,
+            value=tag_value
         )
         self.assertEqual(
             isinstance(tags, list),
@@ -1588,25 +1605,25 @@ class TestResourceTags(cloudstackTestCase):
 
         self.assertEqual(
             tags[0].value,
-            'India',
+            tag_value,
             'The tag should have original value'
         )
         try:
             Tag.create(self.apiclient,
                        resourceIds=self.vm_1.id,
                        resourceType='userVM',
-                       tags={'REGION': 'INDIA'})
+                       tags={tag_key.upper(): tag_value.uppper()})
         except Exception as e:
             pass
         else:
             assert("Creating same tag in upper case succeeded")
 
         try:
-            tag_1.delete(
+            Tag.delete(
                 self.apiclient,
                 resourceIds=self.vm_1.id,
                 resourceType='userVM',
-                tags={'region': 'India'}
+                tags={tag_key: tag_value}
             )
         except Exception as e:
             self.fail("Failed to delete the tag - %s" % e)
@@ -1618,8 +1635,8 @@ class TestResourceTags(cloudstackTestCase):
             resourceType='userVM',
             account=self.account.name,
             domainid=self.account.domainid,
-            key='region',
-            value='India'
+            key=tag_key,
+            value=tag_value
         )
         self.assertEqual(
             tags,
@@ -1637,13 +1654,16 @@ class TestResourceTags(cloudstackTestCase):
         # 1. Create more than 10 tags to VM using createTags API
         # 2. Create a tag with special characters on VM using createTags API
 
+        tag_key = 'scope'
+        tag_value = 'test_14_special_char_mutiple_tags'
+        
         self.debug("Creating a tag for user VM")
         tag = Tag.create(
             self.apiclient,
             resourceIds=self.vm_1.id,
             resourceType='userVM',
             tags={
-                'region': 'India',
+                tag_key: tag_value,
                 'offering': 'high',
                 'type': 'webserver',
                 'priority': 'critical',
@@ -1664,8 +1684,8 @@ class TestResourceTags(cloudstackTestCase):
             resourceType='userVM',
             account=self.account.name,
             domainid=self.account.domainid,
-            key='region',
-            value='India'
+            key=tag_key,
+            value=tag_value
         )
         self.assertEqual(
             isinstance(tags, list),
@@ -1674,16 +1694,16 @@ class TestResourceTags(cloudstackTestCase):
         )
         self.assertEqual(
             tags[0].value,
-            'India',
+            tag_value,
             'The tag should have original value'
         )
         # Cleanup
-        tag.delete(
+        Tag.delete(
             self.apiclient,
             resourceIds=self.vm_1.id,
             resourceType='userVM',
             tags={
-                'region': 'India',
+                tag_key: tag_value,
                 'offering': 'high',
                 'type': 'webserver',
                 'priority': 'critical',
@@ -1707,6 +1727,9 @@ class TestResourceTags(cloudstackTestCase):
         # 2. Create a tag on projects using createTags API
         # 3. Delete the tag.
 
+        tag_key = 'scope'
+        tag_value = 'test_15_project_tag'
+                        
         # Create project as a domain admin
         project = Project.create(
             self.apiclient,
@@ -1724,7 +1747,7 @@ class TestResourceTags(cloudstackTestCase):
             self.apiclient,
             resourceIds=project.id,
             resourceType='project',
-            tags={'region': 'India'}
+            tags={tag_key: tag_value}
         )
         self.debug("Tag created: %s" % tag.__dict__)
 
@@ -1733,7 +1756,7 @@ class TestResourceTags(cloudstackTestCase):
             listall=True,
             resourceType='project',
             resourceIds=project.id,
-            key='region',
+            key=tag_key,
         )
         self.debug("tags = %s" % tags)
 
@@ -1744,15 +1767,15 @@ class TestResourceTags(cloudstackTestCase):
         )
         self.assertEqual(
             tags[0].value,
-            'India',
+            tag_value,
             'The tag should have original value'
         )
 
         projects = Project.list(
             self.apiclient,
             listall=True,
-            key='region',
-            value='India'
+            key=tag_key,
+            value=tag_value
         )
 
         self.assertEqual(
@@ -1763,11 +1786,11 @@ class TestResourceTags(cloudstackTestCase):
 
         self.debug("Deleting the created tag..")
         try:
-            tag.delete(
+            Tag.delete(
                 self.apiclient,
                 resourceIds=project.id,
                 resourceType='project',
-                tags={'region': 'India'}
+                tags={tag_key: tag_value}
             )
         except Exception as e:
             self.fail("Failed to delete the tag - %s" % e)
@@ -1779,8 +1802,8 @@ class TestResourceTags(cloudstackTestCase):
             resourceType='project',
             account=self.account.name,
             domainid=self.account.domainid,
-            key='region',
-            value='India'
+            key=tag_key,
+            value=tag_value
         )
         self.assertEqual(
             tags,
@@ -1799,8 +1822,11 @@ class TestResourceTags(cloudstackTestCase):
         # 3. Login with other account and query the tags using
         #    listTags API
 
+        tag_key = 'scope'
+        tag_value = 'test_16_query_tags_other_account'
+        
         self.debug("Creating user accounts..")
-
+        
         user_account = Account.create(
             self.apiclient,
             self.services["user"],
@@ -1836,7 +1862,7 @@ class TestResourceTags(cloudstackTestCase):
             self.apiclient,
             resourceIds=iso.id,
             resourceType='ISO',
-            tags={'region': 'India'}
+            tags={tag_key: tag_value}
         )
         self.debug("Tag created: %s" % tag.__dict__)
 
@@ -1846,7 +1872,7 @@ class TestResourceTags(cloudstackTestCase):
             resourceType='ISO',
             account=user_account.name,
             domainid=user_account.domainid,
-            key='region',
+            key=tag_key,
         )
         self.assertEqual(
             isinstance(tags, list),
@@ -1855,7 +1881,7 @@ class TestResourceTags(cloudstackTestCase):
         )
         self.assertEqual(
             tags[0].value,
-            'India',
+            tag_value,
             "The tag value should match with the original value"
         )
 
@@ -1866,7 +1892,7 @@ class TestResourceTags(cloudstackTestCase):
             resourceType='ISO',
             account=other_user_account.name,
             domainid=other_user_account.domainid,
-            key='region',
+            key=tag_key,
         )
 
         self.assertEqual(
@@ -1875,6 +1901,16 @@ class TestResourceTags(cloudstackTestCase):
             "List tags should return empty response"
         )
 
+        try:
+            Tag.delete(
+                self.apiclient,
+                resourceIds=iso.id,
+                resourceType='ISO',
+                tags={tag_key: tag_value}
+            )
+        except Exception as e:
+            self.fail("Failed to delete the tag - %s" % e)
+                        
         return
 
     @attr(tags=["advanced", "basic"], required_hardware="false")
@@ -1887,6 +1923,9 @@ class TestResourceTags(cloudstackTestCase):
         # 3. Login with admin account and query the tags using
         #    listTags API
 
+        tag_key = 'scope'
+        tag_value = 'test_17_query_tags_admin_account'
+        
         self.debug("Creating user accounts..")
 
         user_account = Account.create(
@@ -1913,7 +1952,7 @@ class TestResourceTags(cloudstackTestCase):
         Tag.create(self.apiclient,
                    resourceIds=iso.id,
                    resourceType='ISO',
-                   tags={'region': 'India'})
+                   tags={tag_key: tag_value})
 
         tags = Tag.list(
             self.apiclient,
@@ -1921,7 +1960,7 @@ class TestResourceTags(cloudstackTestCase):
             resourceType='ISO',
             account=user_account.name,
             domainid=user_account.domainid,
-            key='region',
+            key=tag_key,
         )
         self.assertEqual(
             isinstance(tags, list),
@@ -1930,7 +1969,7 @@ class TestResourceTags(cloudstackTestCase):
         )
         self.assertEqual(
             tags[0].value,
-            'India',
+            tag_value,
             "The tag value should match with the original value"
         )
 
@@ -1939,7 +1978,7 @@ class TestResourceTags(cloudstackTestCase):
             self.apiclient,
             listall=True,
             resourceType='ISO',
-            key='region',
+            key=tag_key,
         )
         self.assertEqual(
             isinstance(tags, list),
@@ -1948,10 +1987,20 @@ class TestResourceTags(cloudstackTestCase):
         )
         self.assertEqual(
             tags[0].value,
-            'India',
+            tag_value,
             'The tag should have original value'
         )
 
+        try:
+            Tag.delete(
+                self.apiclient,
+                resourceIds=iso.id,
+                resourceType='ISO',
+                tags={tag_key: tag_value}
+            )
+        except Exception as e:
+            self.fail("Failed to delete the tag - %s" % e)
+        
         return
 
     @attr(tags=["advanced", "basic", "simulator"], required_hardware="false")
@@ -1962,12 +2011,15 @@ class TestResourceTags(cloudstackTestCase):
         # 1. Create a tag on  supported resource type(ex:vms)
         # 2. Run the list API commands  with passing invalid key parameter
 
+        tag_key = 'scope'
+        tag_value = 'test_18_invalid_list_parameters'
+        
         self.debug("Creating a tag for user VM")
         tag = Tag.create(
             self.apiclient,
             resourceIds=self.vm_1.id,
             resourceType='userVM',
-            tags={'region': 'India'}
+            tags={tag_key: tag_value}
         )
         self.debug("Tag created: %s" % tag.__dict__)
 
@@ -1979,14 +2031,15 @@ class TestResourceTags(cloudstackTestCase):
         self.rm_tags.append({'tag_obj': tag,
                              'restype': 'userVM',
                              'resid': self.vm_1.id,
-                             'key': 'region',
-                             'value': 'India'})
+                             'tags': [
+                                 {'key': tag_key, 'value': tag_value}
+                             ]})
 
         self.debug("Passing invalid key parameter to the listAPI for vms")
 
         vms = VirtualMachine.list(self.apiclient,
-                                  **{'tags[0].key': 'region111',
-                                     'tags[0].value': 'India',
+                                  **{'tags[0].key': tag_key + '1',
+                                     'tags[0].value': tag_value,
                                      'listall': 'True'}
                                   )
         self.assertEqual(
@@ -2006,12 +2059,15 @@ class TestResourceTags(cloudstackTestCase):
         # 1. Deletion of a tag without any errors.
         # 2. Add same tag.
 
+        tag_key = 'scope'
+        tag_value = 'test_19_delete_add_same_tag'        
+        
         self.debug("Creating a tag for user VM")
         tag = Tag.create(
             self.apiclient,
             resourceIds=self.vm_1.id,
             resourceType='userVM',
-            tags={'region': 'India'}
+            tags={tag_key: tag_value}
         )
         self.debug("Tag created: %s" % tag.__dict__)
 
@@ -2021,8 +2077,8 @@ class TestResourceTags(cloudstackTestCase):
             resourceType='userVM',
             account=self.account.name,
             domainid=self.account.domainid,
-            key='region',
-            value='India'
+            key=tag_key,
+            value=tag_value
         )
         self.assertEqual(
             isinstance(tags, list),
@@ -2032,17 +2088,17 @@ class TestResourceTags(cloudstackTestCase):
 
         self.assertEqual(
             tags[0].value,
-            "India",
+            tag_value,
             "Tag created with incorrect value"
         )
 
         self.debug("Deleting the created tag..")
         try:
-            tag.delete(
+            Tag.delete(
                 self.apiclient,
                 resourceIds=self.vm_1.id,
                 resourceType='userVM',
-                tags={'region': 'India'}
+                tags={tag_key: tag_value}
             )
         except Exception as e:
             self.fail("Failed to delete the tag - %s" % e)
@@ -2054,8 +2110,8 @@ class TestResourceTags(cloudstackTestCase):
             resourceType='userVM',
             account=self.account.name,
             domainid=self.account.domainid,
-            key='region',
-            value='India'
+            key=tag_key,
+            value=tag_value
         )
         self.assertEqual(
             tags,
@@ -2067,7 +2123,7 @@ class TestResourceTags(cloudstackTestCase):
             self.apiclient,
             resourceIds=self.vm_1.id,
             resourceType='userVM',
-            tags={'region': 'India'}
+            tags={tag_key: tag_value}
         )
         self.debug("Tag created: %s" % tag.__dict__)
 
@@ -2077,8 +2133,8 @@ class TestResourceTags(cloudstackTestCase):
             resourceType='userVM',
             account=self.account.name,
             domainid=self.account.domainid,
-            key='region',
-            value='India'
+            key=tag_key,
+            value=tag_value
         )
         self.assertEqual(
             isinstance(tags, list),
@@ -2087,17 +2143,17 @@ class TestResourceTags(cloudstackTestCase):
         )
 
         self.assertEqual(tags[0].value,
-                         "India",
+                         tag_value,
                          "Tag created with incorrect value"
                          )
 
         self.debug("Deleting the created tag..")
         try:
-            tag.delete(
+            Tag.delete(
                 self.apiclient,
                 resourceIds=self.vm_1.id,
                 resourceType='userVM',
-                tags={'region': 'India'}
+                tags={tag_key: tag_value}
             )
         except Exception as e:
             self.fail("Failed to delete the tag - %s" % e)
@@ -2107,8 +2163,11 @@ class TestResourceTags(cloudstackTestCase):
     def test_20_create_tags_multiple_resources(self):
         "Test creation of same tag on multiple resources"
 
-        self.debug("Creating volume for account: %s " %
-                   self.account.name)
+        tag_key = 'scope'
+        tag_value = 'test_20_create_tags_multiple_resources'
+                        
+        self.debug("Creating volume for account: %s " % self.account.name)
+        
         volume = Volume.create(
             self.apiclient,
             self.services["volume"],
@@ -2126,7 +2185,7 @@ class TestResourceTags(cloudstackTestCase):
             self.apiclient,
             resourceIds=volume.id,
             resourceType='volume',
-            tags={'region': 'India'}
+            tags={tag_key: tag_value}
         )
         self.debug("Tag created: %s" % tag.__dict__)
 
@@ -2136,7 +2195,7 @@ class TestResourceTags(cloudstackTestCase):
             resourceType='volume',
             account=self.account.name,
             domainid=self.account.domainid,
-            key='region',
+            key=tag_key,
         )
         self.assertEqual(
             isinstance(tags, list),
@@ -2145,7 +2204,7 @@ class TestResourceTags(cloudstackTestCase):
         )
         self.assertEqual(
             tags[0].value,
-            'India',
+            tag_value,
             'The tag should have original value'
         )
 
@@ -2154,7 +2213,7 @@ class TestResourceTags(cloudstackTestCase):
             self.apiclient,
             resourceIds=self.vm_1.id,
             resourceType='userVM',
-            tags={'region': 'India'}
+            tags={tag_key: tag_value}
         )
         self.debug("Tag created: %s" % tag.__dict__)
 
@@ -2164,8 +2223,8 @@ class TestResourceTags(cloudstackTestCase):
             resourceType='userVM',
             account=self.account.name,
             domainid=self.account.domainid,
-            key='region',
-            value='India'
+            key=tag_key,
+            value=tag_value
         )
         self.assertEqual(
             isinstance(tags, list),
@@ -2175,17 +2234,17 @@ class TestResourceTags(cloudstackTestCase):
 
         self.assertEqual(
             tags[0].value,
-            "India",
-            "Tag created with incorrect value"
+            tag_value,
+            "Expected tag value is incorrect"
         )
 
         self.debug("Deleting the created tag..")
         try:
-            tag.delete(
+            Tag.delete(
                 self.apiclient,
                 resourceIds=self.vm_1.id,
                 resourceType='userVM',
-                tags={'region': 'India'}
+                tags={tag_key: tag_value}
             )
         except Exception as e:
             self.fail("Failed to delete the tag - %s" % e)
@@ -2197,8 +2256,8 @@ class TestResourceTags(cloudstackTestCase):
             resourceType='userVM',
             account=self.account.name,
             domainid=self.account.domainid,
-            key='region',
-            value='India'
+            key=tag_key,
+            value=tag_value
         )
         self.assertEqual(
             tags,
@@ -2212,6 +2271,9 @@ class TestResourceTags(cloudstackTestCase):
     def test_21_create_tag_stopped_vm(self):
         "Test creation of tag on stopped vm."
 
+        tag_key = 'scope'
+        tag_value = 'test_21_create_tag_stopped_vm'        
+        
         try:
             self.debug("Stopping the virtual machine: %s" % self.vm_1.name)
             # Stop virtual machine
@@ -2222,7 +2284,7 @@ class TestResourceTags(cloudstackTestCase):
                 self.apiclient,
                 resourceIds=self.vm_1.id,
                 resourceType='userVM',
-                tags={'region': 'India'}
+                tags={tag_key: tag_value}
             )
             self.debug("Tag created: %s" % tag.__dict__)
 
@@ -2232,8 +2294,8 @@ class TestResourceTags(cloudstackTestCase):
                 resourceType='userVM',
                 account=self.account.name,
                 domainid=self.account.domainid,
-                key='region',
-                value='India'
+                key=tag_key,
+                value=tag_value
             )
             self.assertEqual(
                 isinstance(tags, list),
@@ -2243,16 +2305,16 @@ class TestResourceTags(cloudstackTestCase):
 
             self.assertEqual(
                 tags[0].value,
-                "India",
+                tag_value,
                 "Tag created with incorrect value"
             )
 
             self.debug("Deleting the created tag..")
-            tag.delete(
+            Tag.delete(
                 self.apiclient,
                 resourceIds=self.vm_1.id,
                 resourceType='userVM',
-                tags={'region': 'India'}
+                tags={tag_key: tag_value}
             )
         except Exception as e:
             self.fail("Exception occured - %s" % e)
@@ -2262,6 +2324,9 @@ class TestResourceTags(cloudstackTestCase):
     def test_22_create_tag_destroyed_vm(self):
         "Test creation of tag on stopped vm."
 
+        tag_key = 'scope'
+        tag_value = 'test_22_create_tag_destroyed_vm'
+        
         self.debug("Destroying instance: %s" % self.vm_1.name)
         self.vm_1.delete(self.apiclient, expunge=False)
 
@@ -2270,7 +2335,7 @@ class TestResourceTags(cloudstackTestCase):
             self.apiclient,
             resourceIds=self.vm_1.id,
             resourceType='userVM',
-            tags={'region': 'India'}
+            tags={tag_key: tag_value}
         )
         self.debug("Tag created: %s" % tag.__dict__)
 
@@ -2280,8 +2345,8 @@ class TestResourceTags(cloudstackTestCase):
             resourceType='userVM',
             account=self.account.name,
             domainid=self.account.domainid,
-            key='region',
-            value='India'
+            key=tag_key,
+            value=tag_value
         )
         self.assertEqual(
             isinstance(tags, list),
@@ -2291,17 +2356,17 @@ class TestResourceTags(cloudstackTestCase):
 
         self.assertEqual(
             tags[0].value,
-            "India",
+            tag_value,
             "Tag created with incorrect value"
         )
 
         self.debug("Deleting the created tag..")
         try:
-            tag.delete(
+            Tag.delete(
                 self.apiclient,
                 resourceIds=self.vm_1.id,
                 resourceType='userVM',
-                tags={'region': 'India'}
+                tags={tag_key: tag_value}
             )
         except Exception as e:
             self.fail("Failed to delete the tag - %s" % e)
@@ -2405,8 +2470,8 @@ class TestResourceTags(cloudstackTestCase):
         return
 
     @attr(tags=["advanced"], required_hardware="false")
-    def test_24_public_IP_tag(self):
-        """ Testcreation, adding and removing tag on public IP address
+    def test_24_public_ip_tag(self):
+        """ Test creation, adding and removing tag on public IP address
         """
         # Validate the following
         # 1. Create a domain and admin account under the new domain
@@ -2414,6 +2479,9 @@ class TestResourceTags(cloudstackTestCase):
         # 3. Delete above created tag using deleteTags API
         # 4. Perform steps 2&3 using domain-admin
 
+        tag_key = 'scope'
+        tag_value = 'test_24_public_ip_tag'
+                
         self.debug("Creating a sub-domain under: %s" % self.domain.name)
         self.child_domain = Domain.create(
             self.apiclient,
@@ -2479,7 +2547,7 @@ class TestResourceTags(cloudstackTestCase):
             self.dom_admin_api_client,
             resourceIds=public_ip.ipaddress.id,
             resourceType='PublicIpAddress',
-            tags={'region': 'India'}
+            tags={tag_key: tag_value}
         )
         self.debug("Tag created: %s" % tag.__dict__)
 
@@ -2489,8 +2557,8 @@ class TestResourceTags(cloudstackTestCase):
             resourceType='PublicIpAddress',
             account=self.child_do_admin.name,
             domainid=self.child_do_admin.domainid,
-            key='region',
-            value='India'
+            key=tag_key,
+            value=tag_value
         )
         self.assertEqual(
             isinstance(tags, list),
@@ -2499,7 +2567,7 @@ class TestResourceTags(cloudstackTestCase):
         )
         self.assertEqual(
             tags[0].value,
-            'India',
+            tag_value,
             'The tag should have original value'
         )
         publicIps = PublicIPAddress.list(
@@ -2507,8 +2575,8 @@ class TestResourceTags(cloudstackTestCase):
             account=self.child_do_admin.name,
             domainid=self.child_do_admin.domainid,
             listall=True,
-            key='region',
-            value='India'
+            key=tag_key,
+            value=tag_value
         )
         self.assertEqual(
             isinstance(publicIps, list),
@@ -2518,11 +2586,11 @@ class TestResourceTags(cloudstackTestCase):
 
         self.debug("Deleting the created tag..")
         try:
-            tag.delete(
+            Tag.delete(
                 self.dom_admin_api_client,
                 resourceIds=public_ip.ipaddress.id,
                 resourceType='PublicIpAddress',
-                tags={'region': 'India'}
+                tags={tag_key: tag_value}
             )
         except Exception as e:
             self.fail("Failed to delete the tag - %s" % e)
@@ -2534,8 +2602,8 @@ class TestResourceTags(cloudstackTestCase):
             resourceType='PublicIpAddress',
             account=self.child_do_admin.name,
             domainid=self.child_do_admin.domainid,
-            key='region',
-            value='India'
+            key=tag_key,
+            value=tag_value
         )
         self.assertEqual(
             tags,
@@ -2543,3 +2611,366 @@ class TestResourceTags(cloudstackTestCase):
             "List tags should return empty response"
         )
         return
+
+    def __test_account_tags(self, apiclient, account, listall = False):
+        set_tags = {'primary-contact-name': 'John Doe',
+                    'primary-contact-phone': '1-022-333-444'}
+
+        Tag.create(
+            apiclient,
+            resourceIds=account.id,
+            resourceType='Account',
+            tags=set_tags)
+
+        received_tags = Tag.list(
+            apiclient,
+            resourceId=account.id,
+            listAll=listall,
+            resourceType='Account')
+
+        self.assertEqual(
+            isinstance(received_tags, list),
+            True,
+            "List tags should return list response."
+        )
+
+        received_tag_map = {}
+        for t in received_tags:
+            received_tag_map[t.key] = t.value
+        
+        self.assertEqual(
+            set_tags,
+            received_tag_map,
+            "Tags saved and received differ."
+        )
+
+        try:
+            Tag.delete(
+                apiclient,
+                resourceIds=account.id,
+                resourceType='Account',
+                tags=set_tags)
+        except Exception as e:
+            self.fail("Failed to delete the tag - %s" % e)
+
+        received_tags_removed = Tag.list(
+            apiclient,
+            resourceId=account.id,
+            listAll=listall,
+            resourceType='Account')
+
+        self.assertEqual(
+            received_tags_removed,
+            None,
+            "List tags should return empty list response when tags are 
removed."
+        )
+        return
+    
+    @attr(tags=["advanced","basic"], required_hardware="false")
+    def test_25_admin_account_tags(self):
+        '''Test create, list, delete tag for admin account from admin 
account'''
+        self.debug("Creating a tag for Admin account")
+        admin_account = Account.list(self.apiclient, name='admin')
+        self.__test_account_tags(self.apiclient, admin_account[0])
+        return
+
+    @attr(tags=["advanced","basic"], required_hardware="false")    
+    def test_26_domain_admin_account_tags(self):
+        child_domain = Domain.create(
+            self.apiclient,
+            services=self.services["domain"],
+            parentdomainid=self.domain.id
+        )
+        child_domain_admin = Account.create(
+            self.apiclient,
+            self.services["account"],
+            admin=True,
+            domainid=child_domain.id
+        )
+        # Cleanup the resources created at end of test
+        self.cleanup.append(child_domain_admin)
+        self.cleanup.append(child_domain)
+        domain_admin_api_client = self.testClient.getUserApiClient(
+            UserName=child_domain_admin.name,
+            DomainName=child_domain_admin.domain
+        )
+        self.__test_account_tags(domain_admin_api_client, child_domain_admin)
+        return
+
+    @attr(tags=["advanced","basic"], required_hardware="false")
+    def test_27_regular_user_account_tags(self):
+        regular_account = Account.create(
+            self.apiclient,
+            self.services["account"],
+            admin=False,
+            domainid=self.domain.id
+        )
+        # Cleanup the resources created at end of test
+        self.cleanup.append(regular_account)
+        regular_account_api_client = 
self.testClient.getUserApiClient(UserName=regular_account.name, 
DomainName=self.domain.name)
+        self.__test_account_tags(regular_account_api_client, regular_account)
+        return
+    
+    @attr(tags=["advanced","basic"], required_hardware="false")
+    def test_28_admin_access_domain_admin_account_tags(self):
+        '''Test create, list, delete tag for domain admin account from admin 
account'''
+        child_domain = Domain.create(
+            self.apiclient,
+            services=self.services["domain"],
+            parentdomainid=self.domain.id
+        )
+        child_domain_admin = Account.create(
+            self.apiclient,
+            self.services["account"],
+            admin=True,
+            domainid=child_domain.id
+        )
+        # Cleanup the resources created at end of test
+        self.cleanup.append(child_domain_admin)
+        self.cleanup.append(child_domain)
+        self.__test_account_tags(self.apiclient, child_domain_admin, listall = 
True)
+        return
+
+    @attr(tags=["advanced","basic"], required_hardware="false")
+    def test_29_admin_access_user_account_tags(self):
+        '''Test create, list, delete tag for user account from admin account'''
+        regular_account = Account.create(
+            self.apiclient,
+            self.services["account"],
+            admin=False
+        )
+        # Cleanup the resources created at end of test
+        self.cleanup.append(regular_account)
+        self.__test_account_tags(self.apiclient, regular_account, listall = 
True)
+        return
+
+    @attr(tags=["advanced","basic"], required_hardware="false")
+    def test_30_domain_admin_access_user_account_same_domain_tags(self):
+        '''Test create, list, delete tag for user account from admin account'''
+
+        child_domain = Domain.create(
+            self.apiclient,
+            services=self.services["domain"],
+            parentdomainid=self.domain.id
+        )
+        child_domain_admin = Account.create(
+            self.apiclient,
+            self.services["account"],
+            admin=True,
+            domainid=child_domain.id
+        )
+
+        regular_account = Account.create(
+            self.apiclient,
+            self.services["account"],
+            admin=False,
+            domainid=child_domain.id
+        )
+        # Cleanup the resources created at end of test
+        self.cleanup.append(regular_account)
+                                
+        # Cleanup the resources created at end of test
+        self.cleanup.append(child_domain_admin)
+        self.cleanup.append(child_domain)
+
+        domain_admin_api_client = self.testClient.getUserApiClient(
+            UserName=child_domain_admin.name,
+            DomainName=child_domain.name
+        )
+        self.__test_account_tags(domain_admin_api_client, regular_account, 
listall = True)
+        return
+
+    @attr(tags=["advanced","basic"], required_hardware="false")
+    def test_31_user_cant_remove_update_admin_tags(self):
+        '''Tests that an user is unable to remove, modify tags created by 
admin but should access'''
+
+        tag_key_user = 'scope_user'
+        tag_value_user = 'test_31_user_cant_remove_update_admin_tags'
+
+        tag_key_admin = 'scope_admin'
+        tag_value_admin = 'test_31_user_cant_remove_update_admin_tags'
+                       
+        regular_account = Account.create(
+            self.apiclient,
+            self.services["account"],
+            admin=False
+        )
+        self.cleanup.append(regular_account)
+        
+        regular_account_api_client = 
self.testClient.getUserApiClient(UserName=regular_account.name, 
DomainName=self.domain.name)
+
+        def create_admin_tag():
+            return Tag.create(
+                self.apiclient,
+                resourceIds=regular_account.id,
+                resourceType='Account',
+                tags={ tag_key_admin: tag_value_admin})
+            
+
+        def create_user_tag():
+            return Tag.create(
+                regular_account_api_client,
+                resourceIds=regular_account.id,
+                resourceType='Account',
+                tags={ tag_key_user: tag_value_user})
+            
+        create_admin_tag()
+        create_user_tag()
+
+        #
+        # List test expressions
+        #
+        def list_tags(apiclient, listAll):
+            return Tag.list(
+                apiclient,
+                resourceId=regular_account.id,
+                listAll=listAll,
+                resourceType='Account')
+
+        def tags_to_map(tags):
+            m = {}
+            for t in tags:
+                m[t.key] = t.value                            
+            return m
+
+        # admin requests user account tags and gets None (without listall)
+        received_tags_admin = list_tags(self.apiclient, False)
+        self.assertEqual(
+            received_tags_admin,
+            None,
+            "List tags should return empty list response when tags are not set 
on self-owned account."
+        )
+
+        # admin requests user account tags and gets all (with listall)
+        received_tags_admin_listall = list_tags(self.apiclient, True)
+        self.assertEqual(
+            tags_to_map(received_tags_admin_listall),
+            {tag_key_admin: tag_value_admin, tag_key_user: tag_value_user},
+            "List (with listAll=true) tags should return information for admin 
tags and user tags"
+        )
+
+        # user requests own account tags and receives all (without listall)
+        received_tags_user = list_tags(regular_account_api_client, False)
+        self.assertEqual(
+            tags_to_map(received_tags_user),
+            {tag_key_admin: tag_value_admin, tag_key_user: tag_value_user},
+            "List (with listAll=false) tags should return information for user 
tags"
+        )       
+
+        # user requests own account tags and receives all (with listall)
+        received_tags_user_listall = list_tags(regular_account_api_client, 
True)
+        self.assertEqual(
+            tags_to_map(received_tags_user_listall),
+            {tag_key_admin: tag_value_admin, tag_key_user: tag_value_user},
+            "List (with listAll=false) tags should return information for user 
tags"
+        )
+       
+        #
+        # Delete test expressions
+        #
+        
+        def delete_tags(apiclient, tags):
+            Tag.delete(
+                apiclient,
+                resourceIds=regular_account.id,
+                resourceType='Account',
+                tags=tags)
+
+        # user tries to delete admin tag on own account and succeeds 
+        try:
+            delete_tags(regular_account_api_client, {tag_key_admin: 
tag_value_admin})
+        except Exception as e:
+            self.fail("Regular user is not able to delete administrator tag on 
own account - %s" % e)
+                        
+        # user tries to delete user tag and succeeds
+        try:
+            delete_tags(regular_account_api_client, {tag_key_user: 
tag_value_user})
+        except Exception as e:
+            self.fail("Regular user is not able to delete own tag - %s" % e)
+
+        # recover tag to run admin tests
+        create_user_tag()
+        create_admin_tag()
+                
+        # admin tries to delete tags and succeeds
+        try:
+            delete_tags(self.apiclient, {tag_key_admin: tag_value_admin, 
tag_key_user: tag_value_user})
+        except Exception as e:
+            self.fail("Administrator is not able to delete a tag - %s" % e)    
    
+
+        return
+            
+    @attr(tags=["advanced","basic"], required_hardware="false")
+    def test_32_user_a_doesnt_have_access_to_user_b_tags(self):
+        '''Test resource security between regular accounts A and B'''
+
+        tag_key_user1 = 'scope_user1'
+        tag_value_user1 = 
'test_32_user_a_doesnt_have_access_to_user_b_tags-user1'
+
+        tag_key_user2 = 'scope_user2'
+        tag_value_user2 = 
'test_32_user_a_doesnt_have_access_to_user_b_tags-user2'
+                
+        regular_account1 = Account.create(
+            self.apiclient,
+            self.services["account"],
+            admin=False
+        )
+        self.cleanup.append(regular_account1)
+
+        regular_account_api_client1 = 
self.testClient.getUserApiClient(UserName=regular_account1.name, 
DomainName=self.domain.name)
+
+        regular_account2 = Account.create(
+            self.apiclient,
+            self.services["account"],
+            admin=False
+        )
+        self.cleanup.append(regular_account2)
+
+        regular_account_api_client2 = 
self.testClient.getUserApiClient(UserName=regular_account2.name, 
DomainName=self.domain.name)
+
+        Tag.create(
+            regular_account_api_client1,
+            resourceIds=regular_account1.id,
+            resourceType='Account',
+            tags={tag_key_user1: tag_value_user1})
+
+        Tag.create(
+            regular_account_api_client2,
+            resourceIds=regular_account2.id,
+            resourceType='Account',
+            tags={tag_key_user2: tag_value_user2})
+
+        try:
+            Tag.list(
+                regular_account_api_client1,
+                resourceId=regular_account2.id,
+                listAll=listAll,
+                resourceType='Account')
+        except Exception as e:
+            pass
+        else:
+            self.fail("User1 has access to list tags of User2.")
+
+        try:
+            Tag.delete(
+                regular_account_api_client1,
+                resourceIds=regular_account2.id,
+                resourceType='Account',
+                tags={tag_key_user2: tag_value_user2})
+        except Exception as e:
+            pass
+        else:
+            self.fail("User1 has access to delete tags of User2.")             
       
+
+        try:
+            Tag.create(
+                regular_account_api_client1,
+                resourceIds=regular_account2.id,
+                resourceType='Account',
+                tags={tag_key_user1: tag_value_user1})
+        except Exception as e:
+            pass
+        else:
+            self.fail("User1 has access to create tags for User2.")
+                                
+        return
diff --git a/tools/marvin/marvin/cloudstackConnection.py 
b/tools/marvin/marvin/cloudstackConnection.py
index d044fdd..8260697 100644
--- a/tools/marvin/marvin/cloudstackConnection.py
+++ b/tools/marvin/marvin/cloudstackConnection.py
@@ -103,8 +103,8 @@ class CSConnection(object):
                     elif job_status == JOB_FAILED:
                         raise Exception("Job failed: %s"\
                                          % async_response)
-                time.sleep(5)
-                timeout -= 5
+                time.sleep(1)
+                timeout -= 1
                 self.logger.debug("=== JobId:%s is Still Processing, "
                                   "Will TimeOut in:%s ====" % (str(jobid),
                                                                str(timeout)))
diff --git a/tools/marvin/marvin/deployDataCenter.py 
b/tools/marvin/marvin/deployDataCenter.py
index 8d553c8..0ef3f3c 100644
--- a/tools/marvin/marvin/deployDataCenter.py
+++ b/tools/marvin/marvin/deployDataCenter.py
@@ -35,6 +35,7 @@ from marvin.lib.utils import (random_gen)
 from marvin.config.test_data import test_data
 from sys import exit
 import os
+import errno
 import pickle
 from time import sleep, strftime, localtime
 from optparse import OptionParser
@@ -65,18 +66,16 @@ class DeployDataCenters(object):
     def __persistDcConfig(self):
         try:
             if self.__logFolderPath:
-                dc_file_path = self.__logFolderPath + "/dc_entries.obj"
+                dc_file_path = os.path.join(self.__logFolderPath, 
"dc_entries.obj")
             else:
                 ts = strftime("%b_%d_%Y_%H_%M_%S", localtime())
                 dc_file_path = "dc_entries_" + str(ts) + ".obj"
+
             file_to_write = open(dc_file_path, 'w')
             if file_to_write:
                 pickle.dump(self.__cleanUp, file_to_write)
-                print "\n=== Data Center Settings are dumped to %s===" % \
-                      dc_file_path
-                self.__tcRunLogger.debug(
-                    "\n=== Data Center Settings are dumped to %s===" %
-                    dc_file_path)
+                print "\n=== Data Center Settings are dumped to %s===" % 
dc_file_path
+                self.__tcRunLogger.debug("\n=== Data Center Settings are 
dumped to %s===" % dc_file_path)
         except Exception as e:
             print "Exception Occurred  while persisting DC Settings: %s" % \
                   GetDetailExceptionInfo(e)
@@ -1110,38 +1109,46 @@ class DeleteDataCenters:
         finally:
             return ret
 
+def mkdirpath(path):
+    try:
+        os.makedirs(path)
+    except OSError as exc:
+        if exc.errno == errno.EEXIST and os.path.isdir(path):
+            pass
+        else:
+            raise
 
 if __name__ == "__main__":
     '''
     @Desc : This module facilitates the following:
             1. Deploying DataCenter by using the input provided
             configuration.
-              EX: python deployDataCenter.py -i <inp-cfg-file>
+              EX: python deployDataCenter.py -i <inp-cfg-file> [-l <directory 
with logs and output data location>]
             2. Removes a created DataCenter by providing
             the input configuration file and data center settings file
               EX: python deployDataCenter.py -i <inp-cfg-file>
-              -r <dc_exported_entries>
+              -r <dc_exported_entries> [-l <directory with logs and output 
data location>] 
     '''
     parser = OptionParser()
-    parser.add_option("-i", "--input", action="store",
-                      default=None, dest="input",
-                      help="the path \
-                      where the json config file generated")
-
-    parser.add_option("-r", "--remove", action="store",
-                      default=None, dest="remove",
-                      help="path to file\
-                      where the created dc entries are kept")
+    parser.add_option("-i", "--input", action="store", default=None, 
dest="input",
+                      help="The path where the json zones config file is 
located.")
+
+    parser.add_option("-r", "--remove", action="store", default=None, 
dest="remove",
+                      help="The path to file where the created dc entries are 
kept.")
+
+    parser.add_option("-l", "--logdir", action="store", default=None, 
dest="logdir",
+                      help="The directory where result logs of running the 
script are stored:"
+                      "[dc_entries.obj, failed_plus_exceptions.txt, 
runinfo.txt]." +
+                      "Created automatically if doesn't exists.")
+
     (options, args) = parser.parse_args()
 
     '''
     Verify the input validity
     '''
     if options.input is None and options.remove is None:
-        print "\n==== For DeployDataCenter: Please Specify a " \
-              "Valid Input Configuration File===="
-        print "\n==== For DeleteDataCenters: Please Specify a " \
-              "Valid Input Configuration File and DC Settings===="
+        print "\n==== For DeployDataCenter: Please Specify a valid Input 
Configuration File===="
+        print "\n==== For DeleteDataCenters: Please Specify a valid Input 
Configuration File and DC Settings===="
         exit(1)
 
     '''
@@ -1161,8 +1168,10 @@ if __name__ == "__main__":
     cfg = configGenerator.getSetupConfig(options.input)
     log = cfg.logger
 
-    ret = log_obj.createLogs("DeployDataCenter",
-                             log)
+    if options.logdir != None:
+        mkdirpath(options.logdir)
+
+    ret = log_obj.createLogs("DeployDataCenter", log, options.logdir, 
options.logdir == None)
     if ret != FAILED:
         log_folder_path = log_obj.getLogFolderPath()
         tc_run_logger = log_obj.getLogger()
diff --git a/tools/marvin/marvin/lib/base.py b/tools/marvin/marvin/lib/base.py
index 02ee138..b7f25ac 100755
--- a/tools/marvin/marvin/lib/base.py
+++ b/tools/marvin/marvin/lib/base.py
@@ -4304,7 +4304,8 @@ class Tag:
             })
         return Tag(apiclient.createTags(cmd).__dict__)
 
-    def delete(self, apiclient, resourceIds, resourceType, tags):
+    @classmethod
+    def delete(cls, apiclient, resourceIds, resourceType, tags):
         """Delete tags"""
 
         cmd = deleteTags.deleteTagsCmd()
diff --git a/tools/marvin/marvin/marvinLog.py b/tools/marvin/marvin/marvinLog.py
index ea8eaee..582d2e1 100644
--- a/tools/marvin/marvin/marvinLog.py
+++ b/tools/marvin/marvin/marvinLog.py
@@ -128,7 +128,7 @@ class MarvinLog:
     def createLogs(self,
                    test_module_name=None,
                    log_cfg=None,
-                   user_provided_logpath=None):
+                   user_provided_logpath=None, use_temp_path=True):
         '''
         @Name : createLogs
         @Desc : Gets the Logger with file paths initialized and created
@@ -140,29 +140,34 @@ class MarvinLog:
                                        If user provided log path
                                        is available, then one in cfg
                                        will  not be picked up.
+                 use_temp_path: Boolean value which specifies either logs will
+                                       be prepended by random path or not.
         @Output : SUCCESS\FAILED
         '''
         try:
-            temp_ts = time.strftime("%b_%d_%Y_%H_%M_%S",
-                                    time.localtime())
+            temp_ts = time.strftime("%b_%d_%Y_%H_%M_%S", time.localtime())
+
             if test_module_name is None:
                 temp_path = temp_ts + "_" + random_gen()
             else:
-                temp_path = str(test_module_name) + \
-                    "__" + str(temp_ts) + "_" + random_gen()
+                temp_path = str(test_module_name) + "__" + str(temp_ts) + "_" 
+ random_gen()
 
             if user_provided_logpath:
-                temp_dir = user_provided_logpath + "/MarvinLogs"
+                temp_dir = os.path.join(user_provided_logpath, "MarvinLogs")
             elif ((log_cfg is not None) and
                     ('LogFolderPath' in log_cfg.__dict__.keys()) and
                     (log_cfg.__dict__.get('LogFolderPath') is not None)):
-                temp_dir = \
-                    log_cfg.__dict__.get('LogFolderPath') + "/MarvinLogs"
+                temp_dir = os.path.join(log_cfg.__dict__.get('LogFolderPath'), 
"MarvinLogs")
+
+            if use_temp_path == True:
+                self.__logFolderDir = os.path.join(temp_dir, temp_path)
+            else:
+                if test_module_name == None:
+                    self.__logFolderDir = temp_dir
+                else:
+                    self.__logFolderDir = os.path.join(temp_dir, 
str(test_module_name))
 
-            self.__logFolderDir = temp_dir + "//" + temp_path
-            print "\n==== Log Folder Path: %s. " \
-                  "All logs will be available here ====" \
-                  % str(self.__logFolderDir)
+            print "\n==== Log Folder Path: %s. All logs will be available here 
====" % str(self.__logFolderDir)
             os.makedirs(self.__logFolderDir)
 
             '''
@@ -171,9 +176,10 @@ class MarvinLog:
             2. RunLog contains the complete Run Information for Test Run
             3. ResultFile contains the TC result information for Test Run
             '''
-            tc_failed_exception_log = \
-                self.__logFolderDir + "/failed_plus_exceptions.txt"
-            tc_run_log = self.__logFolderDir + "/runinfo.txt"
+
+            tc_failed_exception_log = os.path.join(self.__logFolderDir, 
"failed_plus_exceptions.txt")
+            tc_run_log = os.path.join(self.__logFolderDir, "runinfo.txt")
+
             if self.__setLogHandler(tc_run_log,
                                     log_level=logging.DEBUG) != FAILED:
                 self.__setLogHandler(tc_failed_exception_log,

-- 
To stop receiving notification emails like this one, please contact
['"[email protected]" <[email protected]>'].

Reply via email to