Преглед на файлове

Support for labels and names added with aws passing

Nuwan Goonasekera преди 7 години
родител
ревизия
695296600d

+ 66 - 58
cloudbridge/cloud/base/resources.py

@@ -8,13 +8,14 @@ import os
 import re
 import re
 import shutil
 import shutil
 import time
 import time
+import uuid
 
 
 import six
 import six
 
 
 import cloudbridge.cloud.base.helpers as cb_helpers
 import cloudbridge.cloud.base.helpers as cb_helpers
 from cloudbridge.cloud.interfaces.exceptions \
 from cloudbridge.cloud.interfaces.exceptions \
     import InvalidConfigurationException
     import InvalidConfigurationException
-from cloudbridge.cloud.interfaces.exceptions import InvalidNameException
+from cloudbridge.cloud.interfaces.exceptions import InvalidLabelException
 from cloudbridge.cloud.interfaces.exceptions import WaitStateException
 from cloudbridge.cloud.interfaces.exceptions import WaitStateException
 from cloudbridge.cloud.interfaces.resources import AttachmentInfo
 from cloudbridge.cloud.interfaces.resources import AttachmentInfo
 from cloudbridge.cloud.interfaces.resources import Bucket
 from cloudbridge.cloud.interfaces.resources import Bucket
@@ -60,13 +61,13 @@ class BaseCloudResource(CloudResource):
     Base implementation of a CloudBridge Resource.
     Base implementation of a CloudBridge Resource.
     """
     """
 
 
-    # Regular expression for valid cloudbridge resource names.
+    # Regular expression for valid cloudbridge resource labels.
     # They, must match the same criteria as GCE labels.
     # They, must match the same criteria as GCE labels.
     # as discussed here: https://github.com/CloudVE/cloudbridge/issues/55
     # as discussed here: https://github.com/CloudVE/cloudbridge/issues/55
     #
     #
     # NOTE: The following regex is based on GCEs internal validation logic,
     # NOTE: The following regex is based on GCEs internal validation logic,
     # and is significantly complex to allow for international characters.
     # and is significantly complex to allow for international characters.
-    CB_NAME_PATTERN = re.compile(six.u(
+    CB_LABEL_PATTERN = re.compile(six.u(
         r"^[\u0061-\u007A\u00B5\u00DF-\u00F6\u00F8-\u00FF\u0101\u0103\u0105"
         r"^[\u0061-\u007A\u00B5\u00DF-\u00F6\u00F8-\u00FF\u0101\u0103\u0105"
         "\u0107\u0109\u010B\u010D\u010F\u0111\u0113\u0115\u0117\u0119\u011B"
         "\u0107\u0109\u010B\u010D\u010F\u0111\u0113\u0115\u0117\u0119\u011B"
         "\u011D\u011F\u0121\u0123\u0125\u0127\u0129\u012B\u012D\u012F\u0131"
         "\u011D\u011F\u0121\u0123\u0125\u0127\u0129\u012B\u012D\u012F\u0131"
@@ -196,17 +197,22 @@ class BaseCloudResource(CloudResource):
         self.__provider = provider
         self.__provider = provider
 
 
     @staticmethod
     @staticmethod
-    def is_valid_resource_name(name):
-        return True if BaseCloudResource.CB_NAME_PATTERN.match(name) else False
+    def is_valid_resource_label(label):
+        return (True if BaseCloudResource.CB_LABEL_PATTERN.match(label)
+                else False)
 
 
     @staticmethod
     @staticmethod
-    def assert_valid_resource_name(name):
-        if not BaseCloudResource.is_valid_resource_name(name):
-            log.debug("InvalidNameException raised on %s", name)
-            raise InvalidNameException(
-                u"Invalid name: %s. Name must be at most 63 characters "
+    def assert_valid_resource_label(label):
+        if not BaseCloudResource.is_valid_resource_label(label):
+            log.debug("InvalidLabelException raised on %s", label)
+            raise InvalidLabelException(
+                u"Invalid label: %s. Label must be at most 63 characters "
                 "long and consist of lowercase letters, numbers, "
                 "long and consist of lowercase letters, numbers, "
-                "underscores, dashes or international characters" % name)
+                "underscores, dashes or international characters" % label)
+
+    @staticmethod
+    def _generate_name_from_label(label):
+        return (label[:57] if label else 'cb') + '_' + uuid.uuid4().hex[:6]
 
 
     @property
     @property
     def _provider(self):
     def _provider(self):
@@ -401,7 +407,7 @@ class BaseInstance(BaseCloudResource, BaseObjectLifeCycleMixin, Instance):
                 self.id == other.id and
                 self.id == other.id and
                 # check from most to least likely mutables
                 # check from most to least likely mutables
                 self.state == other.state and
                 self.state == other.state and
-                self.name == other.name and
+                self.label == other.label and
                 self.vm_firewalls == other.vm_firewalls and
                 self.vm_firewalls == other.vm_firewalls and
                 self.public_ips == other.public_ips and
                 self.public_ips == other.public_ips and
                 self.private_ips == other.private_ips and
                 self.private_ips == other.private_ips and
@@ -416,7 +422,7 @@ class BaseInstance(BaseCloudResource, BaseObjectLifeCycleMixin, Instance):
 
 
     def __repr__(self):
     def __repr__(self):
         return "<CB-{0}: {1} ({2})>".format(self.__class__.__name__,
         return "<CB-{0}: {1} ({2})>".format(self.__class__.__name__,
-                                            self.name, self.id)
+                                            self.label, self.name)
 
 
 
 
 class BaseLaunchConfig(LaunchConfig):
 class BaseLaunchConfig(LaunchConfig):
@@ -505,7 +511,7 @@ class BaseMachineImage(
                 self.id == other.id and
                 self.id == other.id and
                 # check from most to least likely mutables
                 # check from most to least likely mutables
                 self.state == other.state and
                 self.state == other.state and
-                self.name == other.name and
+                self.label == other.label and
                 self.description == other.description)
                 self.description == other.description)
 
 
     def wait_till_ready(self, timeout=None, interval=None):
     def wait_till_ready(self, timeout=None, interval=None):
@@ -552,7 +558,7 @@ class BaseVolume(BaseCloudResource, BaseObjectLifeCycleMixin, Volume):
                 self.id == other.id and
                 self.id == other.id and
                 # check from most to least likely mutables
                 # check from most to least likely mutables
                 self.state == other.state and
                 self.state == other.state and
-                self.name == other.name)
+                self.label == other.label)
 
 
     def wait_till_ready(self, timeout=None, interval=None):
     def wait_till_ready(self, timeout=None, interval=None):
         self.wait_for(
         self.wait_for(
@@ -563,7 +569,7 @@ class BaseVolume(BaseCloudResource, BaseObjectLifeCycleMixin, Volume):
 
 
     def __repr__(self):
     def __repr__(self):
         return "<CB-{0}: {1} ({2})>".format(self.__class__.__name__,
         return "<CB-{0}: {1} ({2})>".format(self.__class__.__name__,
-                                            self.name, self.id)
+                                            self.label, self.name)
 
 
 
 
 class BaseSnapshot(BaseCloudResource, BaseObjectLifeCycleMixin, Snapshot):
 class BaseSnapshot(BaseCloudResource, BaseObjectLifeCycleMixin, Snapshot):
@@ -578,7 +584,7 @@ class BaseSnapshot(BaseCloudResource, BaseObjectLifeCycleMixin, Snapshot):
                 self.id == other.id and
                 self.id == other.id and
                 # check from most to least likely mutables
                 # check from most to least likely mutables
                 self.state == other.state and
                 self.state == other.state and
-                self.name == other.name)
+                self.label == other.label)
 
 
     def wait_till_ready(self, timeout=None, interval=None):
     def wait_till_ready(self, timeout=None, interval=None):
         self.wait_for(
         self.wait_for(
@@ -589,7 +595,7 @@ class BaseSnapshot(BaseCloudResource, BaseObjectLifeCycleMixin, Snapshot):
 
 
     def __repr__(self):
     def __repr__(self):
         return "<CB-{0}: {1} ({2})>".format(self.__class__.__name__,
         return "<CB-{0}: {1} ({2})>".format(self.__class__.__name__,
-                                            self.name, self.id)
+                                            self.label, self.name)
 
 
 
 
 class BaseKeyPair(BaseCloudResource, KeyPair):
 class BaseKeyPair(BaseCloudResource, KeyPair):
@@ -617,7 +623,7 @@ class BaseKeyPair(BaseCloudResource, KeyPair):
         """
         """
         Return the name of this key pair.
         Return the name of this key pair.
         """
         """
-        return self._key_pair.name
+        return self.id
 
 
     @property
     @property
     def material(self):
     def material(self):
@@ -640,7 +646,7 @@ class BaseKeyPair(BaseCloudResource, KeyPair):
         self._key_pair.delete()
         self._key_pair.delete()
 
 
     def __repr__(self):
     def __repr__(self):
-        return "<CBKeyPair: {0}>".format(self.name)
+        return "<CBKeyPair: {0}>".format(self.id)
 
 
 
 
 class BaseVMFirewall(BaseCloudResource, VMFirewall):
 class BaseVMFirewall(BaseCloudResource, VMFirewall):
@@ -676,7 +682,7 @@ class BaseVMFirewall(BaseCloudResource, VMFirewall):
         """
         """
         Return the name of this VM firewall.
         Return the name of this VM firewall.
         """
         """
-        return self._vm_firewall.name
+        return self.id
 
 
     @property
     @property
     def description(self):
     def description(self):
@@ -693,7 +699,7 @@ class BaseVMFirewall(BaseCloudResource, VMFirewall):
 
 
     def __repr__(self):
     def __repr__(self):
         return "<CB-{0}: {1} ({2})>".format(self.__class__.__name__,
         return "<CB-{0}: {1} ({2})>".format(self.__class__.__name__,
-                                            self.id, self.name)
+                                            self.label or self.name, self.id)
 
 
 
 
 class BaseVMFirewallRuleContainer(BasePageableObjectMixin,
 class BaseVMFirewallRuleContainer(BasePageableObjectMixin,
@@ -817,7 +823,7 @@ class BaseRegion(BaseCloudResource, Region):
     def to_json(self):
     def to_json(self):
         attr = inspect.getmembers(self, lambda a: not(inspect.isroutine(a)))
         attr = inspect.getmembers(self, lambda a: not(inspect.isroutine(a)))
         js = {k: v for(k, v) in attr if not k.startswith('_')}
         js = {k: v for(k, v) in attr if not k.startswith('_')}
-        js['zones'] = [z.name for z in self.zones]
+        js['zones'] = [z.id for z in self.zones]
         return js
         return js
 
 
 
 
@@ -829,23 +835,25 @@ class BaseBucketObject(BaseCloudResource, BucketObject):
     #
     #
     # Note: The following regex is based on: https://stackoverflow.com/question
     # Note: The following regex is based on: https://stackoverflow.com/question
     # s/537772/what-is-the-most-correct-regular-expression-for-a-unix-file-path
     # s/537772/what-is-the-most-correct-regular-expression-for-a-unix-file-path
-    CB_NAME_PATTERN = re.compile(r"[^\0]+")
+    CB_LABEL_PATTERN = re.compile(r"[^\0]+")
 
 
     def __init__(self, provider):
     def __init__(self, provider):
         super(BaseBucketObject, self).__init__(provider)
         super(BaseBucketObject, self).__init__(provider)
 
 
     @staticmethod
     @staticmethod
-    def is_valid_resource_name(name):
-        return True if BaseBucketObject.CB_NAME_PATTERN.match(name) else False
+    def is_valid_resource_label(label):
+        return (True if BaseBucketObject.CB_LABEL_PATTERN.match(label)
+                else False)
 
 
     @staticmethod
     @staticmethod
-    def assert_valid_resource_name(name):
-        if not BaseBucketObject.is_valid_resource_name(name):
-            log.debug("InvalidNameException raised on %s", name, exc_info=True)
-            raise InvalidNameException(
-                u"Invalid object name: %s. Name must match criteria defined "
+    def assert_valid_resource_label(label):
+        if not BaseBucketObject.is_valid_resource_label(label):
+            log.debug("InvalidLabelException raised on %s", label,
+                      exc_info=True)
+            raise InvalidLabelException(
+                u"Invalid object label: %s. Label must match criteria defined "
                 "in: http://docs.aws.amazon.com/AmazonS3/latest/dev/UsingMeta"
                 "in: http://docs.aws.amazon.com/AmazonS3/latest/dev/UsingMeta"
-                "data.html#object-key-guidelines" % name)
+                "data.html#object-key-guidelines" % label)
 
 
     def save_content(self, target_stream):
     def save_content(self, target_stream):
         shutil.copyfileobj(self.iter_content(), target_stream)
         shutil.copyfileobj(self.iter_content(), target_stream)
@@ -860,7 +868,7 @@ class BaseBucketObject(BaseCloudResource, BucketObject):
 
 
     def __repr__(self):
     def __repr__(self):
         return "<CB-{0}: {1}>".format(self.__class__.__name__,
         return "<CB-{0}: {1}>".format(self.__class__.__name__,
-                                      self.name)
+                                      self.id)
 
 
 
 
 class BaseBucket(BaseCloudResource, Bucket):
 class BaseBucket(BaseCloudResource, Bucket):
@@ -871,23 +879,23 @@ class BaseBucket(BaseCloudResource, Bucket):
     #
     #
     # NOTE: The following regex is based on: https://stackoverflow.com/questio
     # NOTE: The following regex is based on: https://stackoverflow.com/questio
     # ns/2063213/regular-expression-for-validating-dns-label-host-name
     # ns/2063213/regular-expression-for-validating-dns-label-host-name
-    CB_NAME_PATTERN = re.compile(r"^(?![0-9]+$)(?!-)[a-z0-9-]{3,63}(?<!-)$")
+    CB_LABEL_PATTERN = re.compile(r"^(?![0-9]+$)(?!-)[a-z0-9-]{3,63}(?<!-)$")
 
 
     def __init__(self, provider):
     def __init__(self, provider):
         super(BaseBucket, self).__init__(provider)
         super(BaseBucket, self).__init__(provider)
 
 
     @staticmethod
     @staticmethod
-    def is_valid_resource_name(name):
-        return True if BaseBucket.CB_NAME_PATTERN.match(name) else False
+    def is_valid_resource_label(label):
+        return True if BaseBucket.CB_LABEL_PATTERN.match(label) else False
 
 
     @staticmethod
     @staticmethod
-    def assert_valid_resource_name(name):
-        if not BaseBucket.is_valid_resource_name(name):
-            log.debug("Invalid resource name %s", name, exc_info=True)
-            raise InvalidNameException(
+    def assert_valid_resource_label(label):
+        if not BaseBucket.is_valid_resource_label(label):
+            log.debug("Invalid bucket name %s", label, exc_info=True)
+            raise InvalidLabelException(
                 u"Invalid bucket name: %s. Name must match criteria defined "
                 u"Invalid bucket name: %s. Name must match criteria defined "
                 "in: http://docs.aws.amazon.com/awscloudtrail/latest/userguide"
                 "in: http://docs.aws.amazon.com/awscloudtrail/latest/userguide"
-                "/cloudtrail-s3-bucket-naming-requirements.html" % name)
+                "/cloudtrail-s3-bucket-naming-requirements.html" % label)
 
 
     def __eq__(self, other):
     def __eq__(self, other):
         return (isinstance(other, Bucket) and
         return (isinstance(other, Bucket) and
@@ -899,7 +907,7 @@ class BaseBucket(BaseCloudResource, Bucket):
 
 
     def __repr__(self):
     def __repr__(self):
         return "<CB-{0}: {1}>".format(self.__class__.__name__,
         return "<CB-{0}: {1}>".format(self.__class__.__name__,
-                                      self.name)
+                                      self.id)
 
 
 
 
 class BaseBucketContainer(BasePageableObjectMixin, BucketContainer):
 class BaseBucketContainer(BasePageableObjectMixin, BucketContainer):
@@ -922,15 +930,15 @@ class BaseGatewayContainer(GatewayContainer, BasePageableObjectMixin):
 
 
 class BaseNetwork(BaseCloudResource, BaseObjectLifeCycleMixin, Network):
 class BaseNetwork(BaseCloudResource, BaseObjectLifeCycleMixin, Network):
 
 
-    CB_DEFAULT_NETWORK_NAME = os.environ.get('CB_DEFAULT_NETWORK_NAME',
-                                             'cloudbridge-net')
+    CB_DEFAULT_NETWORK_LABEL = os.environ.get('CB_DEFAULT_NETWORK_LABEL',
+                                              'cloudbridge-net')
 
 
     def __init__(self, provider):
     def __init__(self, provider):
         super(BaseNetwork, self).__init__(provider)
         super(BaseNetwork, self).__init__(provider)
 
 
     def __repr__(self):
     def __repr__(self):
         return "<CB-{0}: {1} ({2})>".format(self.__class__.__name__,
         return "<CB-{0}: {1} ({2})>".format(self.__class__.__name__,
-                                            self.id, self.name)
+                                            self.id, self.label)
 
 
     def wait_till_ready(self, timeout=None, interval=None):
     def wait_till_ready(self, timeout=None, interval=None):
         self.wait_for(
         self.wait_for(
@@ -939,9 +947,9 @@ class BaseNetwork(BaseCloudResource, BaseObjectLifeCycleMixin, Network):
             timeout=timeout,
             timeout=timeout,
             interval=interval)
             interval=interval)
 
 
-    def create_subnet(self, name, cidr_block, zone=None):
+    def create_subnet(self, cidr_block, label=None, zone=None):
         return self._provider.networking.subnets.create(
         return self._provider.networking.subnets.create(
-            name=name, network=self, cidr_block=cidr_block, zone=zone)
+            label=label, network=self, cidr_block=cidr_block, zone=zone)
 
 
     def __eq__(self, other):
     def __eq__(self, other):
         return (isinstance(other, Network) and
         return (isinstance(other, Network) and
@@ -952,15 +960,15 @@ class BaseNetwork(BaseCloudResource, BaseObjectLifeCycleMixin, Network):
 
 
 class BaseSubnet(BaseCloudResource, BaseObjectLifeCycleMixin, Subnet):
 class BaseSubnet(BaseCloudResource, BaseObjectLifeCycleMixin, Subnet):
 
 
-    CB_DEFAULT_SUBNET_NAME = os.environ.get('CB_DEFAULT_SUBNET_NAME',
-                                            'cloudbridge-subnet')
+    CB_DEFAULT_SUBNET_LABEL = os.environ.get('CB_DEFAULT_SUBNET_LABEL',
+                                             'cloudbridge-subnet')
 
 
     def __init__(self, provider):
     def __init__(self, provider):
         super(BaseSubnet, self).__init__(provider)
         super(BaseSubnet, self).__init__(provider)
 
 
     def __repr__(self):
     def __repr__(self):
         return "<CB-{0}: {1} ({2})>".format(self.__class__.__name__,
         return "<CB-{0}: {1} ({2})>".format(self.__class__.__name__,
-                                            self.id, self.name)
+                                            self.id, self.label)
 
 
     def __eq__(self, other):
     def __eq__(self, other):
         return (isinstance(other, Subnet) and
         return (isinstance(other, Subnet) and
@@ -1005,7 +1013,7 @@ class BaseFloatingIP(BaseCloudResource, BaseObjectLifeCycleMixin, FloatingIP):
 
 
     @property
     @property
     def name(self):
     def name(self):
-        # VM firewall rules don't support names, so pass
+        # VM firewall rules don't support labels
         return self.public_ip
         return self.public_ip
 
 
     @property
     @property
@@ -1022,7 +1030,7 @@ class BaseFloatingIP(BaseCloudResource, BaseObjectLifeCycleMixin, FloatingIP):
 
 
     def __repr__(self):
     def __repr__(self):
         return "<CB-{0}: {1} ({2})>".format(self.__class__.__name__,
         return "<CB-{0}: {1} ({2})>".format(self.__class__.__name__,
-                                            self.id, self.public_ip)
+                                            self.id, self.name)
 
 
     def __eq__(self, other):
     def __eq__(self, other):
         return (isinstance(other, FloatingIP) and
         return (isinstance(other, FloatingIP) and
@@ -1033,15 +1041,15 @@ class BaseFloatingIP(BaseCloudResource, BaseObjectLifeCycleMixin, FloatingIP):
 
 
 class BaseRouter(BaseCloudResource, Router):
 class BaseRouter(BaseCloudResource, Router):
 
 
-    CB_DEFAULT_ROUTER_NAME = os.environ.get('CB_DEFAULT_ROUTER_NAME',
-                                            'cloudbridge-router')
+    CB_DEFAULT_ROUTER_LABEL = os.environ.get('CB_DEFAULT_ROUTER_LABEL',
+                                             'cloudbridge-router')
 
 
     def __init__(self, provider):
     def __init__(self, provider):
         super(BaseRouter, self).__init__(provider)
         super(BaseRouter, self).__init__(provider)
 
 
     def __repr__(self):
     def __repr__(self):
         return "<CB-{0}: {1} ({2})>".format(self.__class__.__name__, self.id,
         return "<CB-{0}: {1} ({2})>".format(self.__class__.__name__, self.id,
-                                            self.name)
+                                            self.label)
 
 
     def __eq__(self, other):
     def __eq__(self, other):
         return (isinstance(other, Router) and
         return (isinstance(other, Router) and
@@ -1053,8 +1061,8 @@ class BaseRouter(BaseCloudResource, Router):
 class BaseInternetGateway(BaseCloudResource, BaseObjectLifeCycleMixin,
 class BaseInternetGateway(BaseCloudResource, BaseObjectLifeCycleMixin,
                           InternetGateway):
                           InternetGateway):
 
 
-    CB_DEFAULT_INET_GATEWAY_NAME = os.environ.get(
-        'CB_DEFAULT_INET_GATEWAY_NAME', 'cloudbridge-inetgateway')
+    CB_DEFAULT_INET_GATEWAY_LABEL = os.environ.get(
+        'CB_DEFAULT_INET_GATEWAY_LABEL', 'cloudbridge-inetgateway')
 
 
     def __init__(self, provider):
     def __init__(self, provider):
         super(BaseInternetGateway, self).__init__(provider)
         super(BaseInternetGateway, self).__init__(provider)
@@ -1062,7 +1070,7 @@ class BaseInternetGateway(BaseCloudResource, BaseObjectLifeCycleMixin,
 
 
     def __repr__(self):
     def __repr__(self):
         return "<CB-{0}: {1} ({2})>".format(self.__class__.__name__, self.id,
         return "<CB-{0}: {1} ({2})>".format(self.__class__.__name__, self.id,
-                                            self.name)
+                                            self.label)
 
 
     def __eq__(self, other):
     def __eq__(self, other):
         return (isinstance(other, InternetGateway) and
         return (isinstance(other, InternetGateway) and

+ 1 - 1
cloudbridge/cloud/base/services.py

@@ -186,7 +186,7 @@ class BaseSubnetService(
 
 
     def find(self, **kwargs):
     def find(self, **kwargs):
         obj_list = self
         obj_list = self
-        filters = ['name']
+        filters = ['label']
         matches = cb_helpers.generic_find(filters, kwargs, obj_list)
         matches = cb_helpers.generic_find(filters, kwargs, obj_list)
         return ClientPagedResultList(self._provider, list(matches))
         return ClientPagedResultList(self._provider, list(matches))
 
 

+ 4 - 4
cloudbridge/cloud/interfaces/exceptions.py

@@ -47,15 +47,15 @@ class ProviderConnectionException(CloudBridgeBaseException):
     pass
     pass
 
 
 
 
-class InvalidNameException(CloudBridgeBaseException):
+class InvalidLabelException(CloudBridgeBaseException):
     """
     """
-    Marker interface for any attempt to set an invalid name on
+    Marker interface for any attempt to set an invalid label on
     a CloudBridge resource.An example would be setting uppercase
     a CloudBridge resource.An example would be setting uppercase
-    letters, which are not allowed in a resource name.
+    letters, which are not allowed in a resource label.
     """
     """
 
 
     def __init__(self, msg):
     def __init__(self, msg):
-        super(InvalidNameException, self).__init__(msg)
+        super(InvalidLabelException, self).__init__(msg)
 
 
 
 
 class InvalidValueException(CloudBridgeBaseException):
 class InvalidValueException(CloudBridgeBaseException):

+ 1 - 1
cloudbridge/cloud/interfaces/provider.py

@@ -147,7 +147,7 @@ class CloudProvider(object):
 
 
             networks = provider.networking.networks.list()
             networks = provider.networking.networks.list()
             network = provider.networking.networks.create(
             network = provider.networking.networks.create(
-                           name="DevNet", cidr_block='10.0.0.0/16')
+                           label="DevNet", cidr_block='10.0.0.0/16')
 
 
         :rtype: :class:`.NetworkingService`
         :rtype: :class:`.NetworkingService`
         :return:  a NetworkingService object
         :return:  a NetworkingService object

+ 117 - 94
cloudbridge/cloud/interfaces/resources.py

@@ -31,9 +31,12 @@ class CloudResource(object):
 
 
     This interface has a  _provider property that can be used to access the
     This interface has a  _provider property that can be used to access the
     provider associated with the resource, which is only intended for use by
     provider associated with the resource, which is only intended for use by
-    subclasses. Every cloudbridge resource also has an id and name property.
-    The id property is a unique identifier for the resource. The name property
-    is a display value.
+    subclasses. Every cloudbridge resource also has an id, a name and a
+    label property. The id property is a unique identifier for the resource.
+    The name is a more user-friendly version of an id, suitable for
+    display to an end-user. However, it cannot be used in place of id. See
+    @name documentation. The label property is a user-assignable
+    identifier for the resource.
     """
     """
     __metaclass__ = ABCMeta
     __metaclass__ = ABCMeta
 
 
@@ -64,42 +67,52 @@ class CloudResource(object):
         pass
         pass
 
 
     @abstractproperty
     @abstractproperty
-    def display_id(self):
+    def name(self):
         """
         """
-        Get the displayable id for the resource.
+        Get the name id for the resource.
 
 
-        The display_id property is typically a user-friendly id value for the
-        resource. The display_id is different from the id property in the
+        The name property is typically a user-friendly id value for the
+        resource. The name is different from the id property in the
         following ways:
         following ways:
-        1. The display_id property is often a more user-friendly value to
+        1. The name property is often a more user-friendly value to
            display to the user than the id property.
            display to the user than the id property.
-        2. The display_id may sometimes be the same as the id, but should never
+        2. The name may sometimes be the same as the id, but should never
            be used in place of the id.
            be used in place of the id.
         3. The id is what will uniquely identify a resource, and will be used
         3. The id is what will uniquely identify a resource, and will be used
            internally by cloudbridge for all get operations etc.
            internally by cloudbridge for all get operations etc.
-        4. All resources have a display_id.
-        5. The display_id is read-only.
-        6. However, the display_id may not necessarily be unique, which is the
+        4. All resources have a name.
+        5. The name is read-only.
+        6. However, the name may not necessarily be unique, which is the
            reason why it should not be used for uniquely identifying a
            reason why it should not be used for uniquely identifying a
            resource.
            resource.
         Example:
         Example:
-        The AWS machine image name is a display_id. It is not editable and is
-        a user friendly name such as 'Ubuntu 14.04' and corresponds to the
-        ami-name. It is distinct from the ami-id, which corresponds to
-        cloudbridge's id property. The ami-name cannot be edited, and is set
-        at creation time. It is not necessarily unique.
-        In Azure, the machine image's display_id corresponds to the name
+        The AWS machine image name maps to a cloudbridge name. It is not
+        editable and is a user friendly name such as 'Ubuntu 14.04' and
+        corresponds to the ami-name. It is distinct from the ami-id, which
+        maps to cloudbridge's id property. The ami-name cannot be edited, and
+        is set at creation time. It is not necessarily unique.
+        In Azure, the machine image's name corresponds to cloudbridge's name
         property. In Azure, it also happens to be the same as the id property.
         property. In Azure, it also happens to be the same as the id property.
         """
         """
         pass
         pass
 
 
+    @abstractmethod
+    def to_json(self):
+        """
+        Returns a JSON representation of the CloudResource object.
+        """
+        pass
+
+
+class LabeledCloudResource(CloudResource):
+
     @abstractproperty
     @abstractproperty
     def label(self):
     def label(self):
         """
         """
         Get the resource label.
         Get the resource label.
 
 
         The label property is a user-defined, editable identifier for a
         The label property is a user-defined, editable identifier for a
-        resource. It will often correspond to a user editable resource name
+        resource. It will often correspond to a user editable resource label
         in the underlying cloud provider, or be simulated through tags/labels.
         in the underlying cloud provider, or be simulated through tags/labels.
 
 
         The label property adheres to the following restrictions:
         The label property adheres to the following restrictions:
@@ -116,13 +129,6 @@ class CloudResource(object):
         """
         """
         pass
         pass
 
 
-    @abstractmethod
-    def to_json(self):
-        """
-        Returns a JSON representation of the CloudResource object.
-        """
-        pass
-
 
 
 class Configuration(dict):
 class Configuration(dict):
     """
     """
@@ -484,19 +490,15 @@ class InstanceState(object):
     ERROR = "error"
     ERROR = "error"
 
 
 
 
-class Instance(ObjectLifeCycleMixin, CloudResource):
+class Instance(ObjectLifeCycleMixin, LabeledCloudResource):
 
 
     __metaclass__ = ABCMeta
     __metaclass__ = ABCMeta
 
 
-    @CloudResource.name.setter
+    @LabeledCloudResource.label.setter
     @abstractmethod
     @abstractmethod
-    def name(self, value):
+    def label(self, value):
         """
         """
-        Set the instance name.
-
-        Note that the changing the name of an existing resource may result in
-        cloud-dependent code. See the following page for more details:
-        http://cloudbridge.cloudve.org/en/latest/topics/design-decisions.html
+        Set the instance label.
         """
         """
         pass
         pass
 
 
@@ -530,7 +532,7 @@ class Instance(ObjectLifeCycleMixin, CloudResource):
         object, you can use the ``instance.vm_type`` property instead.
         object, you can use the ``instance.vm_type`` property instead.
 
 
         :rtype: ``str``
         :rtype: ``str``
-        :return: VM type name for this instance (e.g., ``m1.large``)
+        :return: VM type id for this instance (e.g., ``m1.large``)
         """
         """
         pass
         pass
 
 
@@ -624,15 +626,15 @@ class Instance(ObjectLifeCycleMixin, CloudResource):
     @abstractproperty
     @abstractproperty
     def key_pair_name(self):
     def key_pair_name(self):
         """
         """
-        Get the name of the key pair associated with this instance.
+        Get the id of the key pair associated with this instance.
 
 
         :rtype: ``str``
         :rtype: ``str``
-        :return: Name of the ssh key pair associated with this instance.
+        :return: Id of the ssh key pair associated with this instance.
         """
         """
         pass
         pass
 
 
     @abstractmethod
     @abstractmethod
-    def create_image(self, name):
+    def create_image(self, label=None):
         """
         """
         Create a new image based on this instance.
         Create a new image based on this instance.
 
 
@@ -722,8 +724,8 @@ class LaunchConfig(object):
         lc = provider.compute.instances.create_launch_config()
         lc = provider.compute.instances.create_launch_config()
         lc.add_block_device(...)
         lc.add_block_device(...)
 
 
-        inst = provider.compute.instances.create(name, image, vm_type,
-                                                 network, launch_config=lc)
+        inst = provider.compute.instances.create(
+            image, vm_type, network, label='MyVM', launch_config=lc)
     """
     """
 
 
     @abstractmethod
     @abstractmethod
@@ -874,12 +876,20 @@ class NetworkState(object):
     ERROR = "error"
     ERROR = "error"
 
 
 
 
-class Network(ObjectLifeCycleMixin, CloudResource):
+class Network(ObjectLifeCycleMixin, LabeledCloudResource):
     """
     """
     Represents a software-defined network, like the Virtual Private Cloud.
     Represents a software-defined network, like the Virtual Private Cloud.
     """
     """
     __metaclass__ = ABCMeta
     __metaclass__ = ABCMeta
 
 
+    @LabeledCloudResource.label.setter
+    @abstractmethod
+    def label(self, value):
+        """
+        Set the resource label.
+        """
+        pass
+
     @abstractproperty
     @abstractproperty
     def external(self):
     def external(self):
         """
         """
@@ -934,18 +944,18 @@ class Network(ObjectLifeCycleMixin, CloudResource):
         pass
         pass
 
 
     @abstractmethod
     @abstractmethod
-    def create_subnet(self, name, cidr_block, zone=None):
+    def create_subnet(self, cidr_block, label=None, zone=None):
         """
         """
         Create a new network subnet and associate it with this Network.
         Create a new network subnet and associate it with this Network.
 
 
-        :type name: ``str``
-        :param name: The subnet name. The name will be set if the
-                     provider supports it.
-
         :type cidr_block: ``str``
         :type cidr_block: ``str``
         :param cidr_block: CIDR block within this Network to assign to the
         :param cidr_block: CIDR block within this Network to assign to the
                            subnet.
                            subnet.
 
 
+        :type label: ``str``
+        :param label: The subnet label. The subnet name will be derived from
+                      this label.
+
         :type zone: ``str``
         :type zone: ``str``
         :param zone: Placement zone where to create the subnet. Some providers
         :param zone: Placement zone where to create the subnet. Some providers
                      may not support subnet zones, in which case the value is
                      may not support subnet zones, in which case the value is
@@ -984,12 +994,20 @@ class SubnetState(object):
     ERROR = "error"
     ERROR = "error"
 
 
 
 
-class Subnet(ObjectLifeCycleMixin, CloudResource):
+class Subnet(ObjectLifeCycleMixin, LabeledCloudResource):
     """
     """
     Represents a subnet, as part of a Network.
     Represents a subnet, as part of a Network.
     """
     """
     __metaclass__ = ABCMeta
     __metaclass__ = ABCMeta
 
 
+    @LabeledCloudResource.label.setter
+    @abstractmethod
+    def label(self, value):
+        """
+        Set the resource label.
+        """
+        pass
+
     @abstractproperty
     @abstractproperty
     def cidr_block(self):
     def cidr_block(self):
         """
         """
@@ -1067,7 +1085,7 @@ class FloatingIPContainer(PageableObjectMixin):
         """
         """
         Searches for a FloatingIP by a given list of attributes.
         Searches for a FloatingIP by a given list of attributes.
 
 
-        Supported attributes: name, public_ip
+        Supported attributes: label, public_ip
 
 
         Example:
         Example:
 
 
@@ -1180,7 +1198,7 @@ class RouterState(object):
     DETACHED = "detached"
     DETACHED = "detached"
 
 
 
 
-class Router(CloudResource):
+class Router(LabeledCloudResource):
     """
     """
     Represents a private network router.
     Represents a private network router.
 
 
@@ -1191,6 +1209,14 @@ class Router(CloudResource):
     """
     """
     __metaclass__ = ABCMeta
     __metaclass__ = ABCMeta
 
 
+    @LabeledCloudResource.label.setter
+    @abstractmethod
+    def label(self, value):
+        """
+        Set the resource label.
+        """
+        pass
+
     @abstractproperty
     @abstractproperty
     def state(self):
     def state(self):
         """
         """
@@ -1294,16 +1320,15 @@ class GatewayContainer(PageableObjectMixin):
     __metaclass__ = ABCMeta
     __metaclass__ = ABCMeta
 
 
     @abstractmethod
     @abstractmethod
-    def get_or_create_inet_gateway(self, name=None):
+    def get_or_create_inet_gateway(self, label=None):
         """
         """
         Creates new or returns an existing internet gateway for a network.
         Creates new or returns an existing internet gateway for a network.
 
 
         The returned gateway object can subsequently be attached to a router to
         The returned gateway object can subsequently be attached to a router to
         provide internet routing to a network.
         provide internet routing to a network.
 
 
-        :type  name: ``str``
-        :param name: The gateway name. This applies only if creating a gateway
-                     and if the provider supports it.
+        :type  label: ``str``
+        :param label: The gateway label.
 
 
         :rtype: ``object``  of :class:`.InternetGateway` or ``None``
         :rtype: ``object``  of :class:`.InternetGateway` or ``None``
         :return: an InternetGateway object of ``None`` if not found.
         :return: an InternetGateway object of ``None`` if not found.
@@ -1331,12 +1356,20 @@ class GatewayContainer(PageableObjectMixin):
         pass
         pass
 
 
 
 
-class Gateway(CloudResource):
+class Gateway(LabeledCloudResource):
     """
     """
     Represents a gateway resource.
     Represents a gateway resource.
     """
     """
     __metaclass__ = ABCMeta
     __metaclass__ = ABCMeta
 
 
+    @LabeledCloudResource.label.setter
+    @abstractmethod
+    def label(self, value):
+        """
+        Set the resource label.
+        """
+        pass
+
     @abstractproperty
     @abstractproperty
     def network_id(self):
     def network_id(self):
         """
         """
@@ -1431,22 +1464,18 @@ class VolumeState(object):
     ERROR = "error"
     ERROR = "error"
 
 
 
 
-class Volume(ObjectLifeCycleMixin, CloudResource):
+class Volume(ObjectLifeCycleMixin, LabeledCloudResource):
     """
     """
     Represents a block storage device (aka volume).
     Represents a block storage device (aka volume).
     """
     """
 
 
     __metaclass__ = ABCMeta
     __metaclass__ = ABCMeta
 
 
-    @CloudResource.name.setter
+    @LabeledCloudResource.label.setter
     @abstractmethod
     @abstractmethod
-    def name(self, value):
+    def label(self, value):
         """
         """
-        Set the volume name.
-
-        Note that the changing the name of an existing resource may result in
-        cloud-dependent code. See the following page for more details:
-        http://cloudbridge.cloudve.org/en/latest/topics/design-decisions.html
+        Set the volume label.
         """
         """
         pass
         pass
 
 
@@ -1456,7 +1485,7 @@ class Volume(ObjectLifeCycleMixin, CloudResource):
         Get the volume description.
         Get the volume description.
 
 
         Some cloud providers may not support this property, and will return the
         Some cloud providers may not support this property, and will return the
-        volume name instead.
+        volume label instead.
 
 
         :rtype: ``str``
         :rtype: ``str``
         :return: Description for this volume as returned by the cloud
         :return: Description for this volume as returned by the cloud
@@ -1472,7 +1501,7 @@ class Volume(ObjectLifeCycleMixin, CloudResource):
 
 
         Some cloud providers may not support this property, and setting the
         Some cloud providers may not support this property, and setting the
         description may have no effect (providers that do not support this
         description may have no effect (providers that do not support this
-        property will always return the volume name as the description).
+        property will always return the volume label as the description).
         """
         """
         pass
         pass
 
 
@@ -1571,12 +1600,12 @@ class Volume(ObjectLifeCycleMixin, CloudResource):
         pass
         pass
 
 
     @abstractmethod
     @abstractmethod
-    def create_snapshot(self, name, description=None):
+    def create_snapshot(self, label=None, description=None):
         """
         """
         Create a snapshot of this Volume.
         Create a snapshot of this Volume.
 
 
-        :type name: ``str``
-        :param name: The name of this snapshot.
+        :type label: ``str``
+        :param label: The label for this snapshot.
 
 
         :type description: ``str``
         :type description: ``str``
         :param description: A description of the snapshot.
         :param description: A description of the snapshot.
@@ -1616,22 +1645,18 @@ class SnapshotState(object):
     ERROR = "error"
     ERROR = "error"
 
 
 
 
-class Snapshot(ObjectLifeCycleMixin, CloudResource):
+class Snapshot(ObjectLifeCycleMixin, LabeledCloudResource):
     """
     """
     Represents a snapshot of a block storage device.
     Represents a snapshot of a block storage device.
     """
     """
 
 
     __metaclass__ = ABCMeta
     __metaclass__ = ABCMeta
 
 
-    @CloudResource.name.setter
+    @LabeledCloudResource.label.setter
     @abstractmethod
     @abstractmethod
-    def name(self, value):
+    def label(self, value):
         """
         """
-        Set the snapshot name.
-
-        Note that the changing the name of an existing resource may result in
-        cloud-dependent code. See the following page for more details:
-        http://cloudbridge.cloudve.org/en/latest/topics/design-decisions.html
+        Set the snapshot label.
         """
         """
         pass
         pass
 
 
@@ -1641,7 +1666,7 @@ class Snapshot(ObjectLifeCycleMixin, CloudResource):
         Get the snapshot description.
         Get the snapshot description.
 
 
         Some cloud providers may not support this property, and will return the
         Some cloud providers may not support this property, and will return the
-        snapshot name instead.
+        snapshot label instead.
 
 
         :rtype: ``str``
         :rtype: ``str``
         :return: Description for this snapshot as returned by the cloud
         :return: Description for this snapshot as returned by the cloud
@@ -1657,7 +1682,7 @@ class Snapshot(ObjectLifeCycleMixin, CloudResource):
 
 
         Some cloud providers may not support this property, and setting the
         Some cloud providers may not support this property, and setting the
         description may have no effect (providers that do not support this
         description may have no effect (providers that do not support this
-        property will always return the snapshot name as the description).
+        property will always return the snapshot label as the description).
 
 
         :type value: ``str``
         :type value: ``str``
         :param value: The value for the snapshot description.
         :param value: The value for the snapshot description.
@@ -1824,7 +1849,7 @@ class PlacementZone(CloudResource):
         A region this placement zone is associated with.
         A region this placement zone is associated with.
 
 
         :rtype: ``str``
         :rtype: ``str``
-        :return: The name of the region the zone is associated with.
+        :return: The id of the region the zone is associated with.
         """
         """
         pass
         pass
 
 
@@ -1921,7 +1946,7 @@ class VMType(CloudResource):
         pass
         pass
 
 
 
 
-class VMFirewall(CloudResource):
+class VMFirewall(LabeledCloudResource):
     """
     """
     Represents a firewall resource applied to virtual machines.
     Represents a firewall resource applied to virtual machines.
 
 
@@ -1930,6 +1955,14 @@ class VMFirewall(CloudResource):
 
 
     __metaclass__ = ABCMeta
     __metaclass__ = ABCMeta
 
 
+    @LabeledCloudResource.label.setter
+    @abstractmethod
+    def label(self, value):
+        """
+        Set the resource label.
+        """
+        pass
+
     @abstractproperty
     @abstractproperty
     def description(self):
     def description(self):
         """
         """
@@ -1983,7 +2016,7 @@ class VMFirewallRuleContainer(PageableObjectMixin):
 
 
             fw = provider.security.vm_firewalls.get('my_fw_id')
             fw = provider.security.vm_firewalls.get('my_fw_id')
             rule = fw.rules.get('rule_id')
             rule = fw.rules.get('rule_id')
-            print(rule.id, rule.name)
+            print(rule.id, rule.label)
 
 
         :rtype: :class:`.FirewallRule`
         :rtype: :class:`.FirewallRule`
         :return:  a FirewallRule instance
         :return:  a FirewallRule instance
@@ -2055,8 +2088,8 @@ class VMFirewallRuleContainer(PageableObjectMixin):
         """
         """
         Find a firewall rule filtered by the given parameters.
         Find a firewall rule filtered by the given parameters.
 
 
-        :type name: str
-        :param name: The name of the VM firewall to retrieve.
+        :type label: str
+        :param label: The label of the VM firewall to retrieve.
 
 
         :type protocol: ``str``
         :type protocol: ``str``
         :param protocol: Either ``tcp`` | ``udp`` | ``icmp``.
         :param protocol: Either ``tcp`` | ``udp`` | ``icmp``.
@@ -2202,11 +2235,6 @@ class BucketObject(CloudResource):
         """
         """
         Retrieve the name of the current object.
         Retrieve the name of the current object.
 
 
-        The bucket object name adheres to a naming requirement that is more
-        relaxed than the naming requirement enforced across CloudBridge. More
-        details are available here: http://docs.aws.amazon.com/AmazonS3/latest/
-        dev/UsingMetadata.html#object-key-guidelines
-
         :rtype: ``str``
         :rtype: ``str``
         :return: Name for this object as returned by the cloud middleware.
         :return: Name for this object as returned by the cloud middleware.
         """
         """
@@ -2318,11 +2346,6 @@ class Bucket(CloudResource):
         """
         """
         Retrieve the name of the current bucket.
         Retrieve the name of the current bucket.
 
 
-        The bucket name adheres to a naming requirement that is more
-        relaxed than the naming requirement enforced across CloudBridge. More
-        details are available here: http://docs.aws.amazon.com/awscloudtrail/
-        latest/userguide/cloudtrail-s3-bucket-naming-requirements.html
-
         :rtype: ``str``
         :rtype: ``str``
         :return: Name for this instance as returned by the cloud middleware.
         :return: Name for this instance as returned by the cloud middleware.
         """
         """
@@ -2342,7 +2365,7 @@ class Bucket(CloudResource):
             # Show all objects in bucket
             # Show all objects in bucket
             print(list(bucket.objects))
             print(list(bucket.objects))
 
 
-            # Find an object by name
+            # Find an object by label
             print(bucket.objects.find(name='my_obj.txt'))
             print(bucket.objects.find(name='my_obj.txt'))
 
 
             # Get first page of bucket list
             # Get first page of bucket list
@@ -2413,7 +2436,7 @@ class BucketContainer(PageableObjectMixin):
     @abstractmethod
     @abstractmethod
     def find(self, **kwargs):
     def find(self, **kwargs):
         """
         """
-        Searche for an object by a given list of attributes.
+        Search for an object by a given list of attributes.
 
 
         Supported attributes: ``name``
         Supported attributes: ``name``
 
 

+ 53 - 52
cloudbridge/cloud/interfaces/services.py

@@ -48,15 +48,15 @@ class ComputeService(CloudService):
 
 
             # print all images
             # print all images
             for image in provider.compute.images:
             for image in provider.compute.images:
-                print(image.id, image.name)
+                print(image.id, image.name, image.label)
 
 
             # print only first 50 images
             # print only first 50 images
             for image in provider.compute.images.list(limit=50):
             for image in provider.compute.images.list(limit=50):
-                print(image.id, image.name)
+                print(image.id, image.name, image.label)
 
 
             # find image by name
             # find image by name
-            image = provider.compute.images.find(name='Ubuntu 16.04')
-            print(image.id, image.name)
+            image = provider.compute.images.find(name='Ubuntu 16.04')[0]
+            print(image.id, image.name, image.label)
 
 
         :rtype: :class:`.ImageService`
         :rtype: :class:`.ImageService`
         :return: an ImageService object
         :return: an ImageService object
@@ -77,7 +77,7 @@ class ComputeService(CloudService):
                 print(vm_type.id, vm_type.name)
                 print(vm_type.id, vm_type.name)
 
 
             # find a specific size by name
             # find a specific size by name
-            vm_type = provider.compute.vm_types.find(name='m1.small')
+            vm_type = provider.compute.vm_types.find(name='m1.small')[0]
             print(vm_type.vcpus)
             print(vm_type.vcpus)
 
 
         :rtype: :class:`.VMTypeService`
         :rtype: :class:`.VMTypeService`
@@ -164,11 +164,14 @@ class InstanceService(PageableObjectMixin, CloudService):
         """
         """
         Searches for an instance by a given list of attributes.
         Searches for an instance by a given list of attributes.
 
 
-        Supported attributes: name
+        Supported attributes: name, label
 
 
         :type  name: ``str``
         :type  name: ``str``
         :param name: The name to search for
         :param name: The name to search for
 
 
+        :type  label: ``str``
+        :param label: The label to search for
+
         :rtype: List of ``object`` of :class:`.Instance`
         :rtype: List of ``object`` of :class:`.Instance`
         :return: A list of Instance objects matching the supplied attributes.
         :return: A list of Instance objects matching the supplied attributes.
         """
         """
@@ -210,16 +213,13 @@ class InstanceService(PageableObjectMixin, CloudService):
         pass
         pass
 
 
     @abstractmethod
     @abstractmethod
-    def create(self, name, image, vm_type, subnet, zone=None,
+    def create(self, image, vm_type, subnet, label=None, zone=None,
                key_pair=None, vm_firewalls=None, user_data=None,
                key_pair=None, vm_firewalls=None, user_data=None,
                launch_config=None,
                launch_config=None,
                **kwargs):
                **kwargs):
         """
         """
         Creates a new virtual machine instance.
         Creates a new virtual machine instance.
 
 
-        :type  name: ``str``
-        :param name: The name of the virtual machine instance
-
         :type  image: ``MachineImage`` or ``str``
         :type  image: ``MachineImage`` or ``str``
         :param image: The MachineImage object or id to boot the virtual machine
         :param image: The MachineImage object or id to boot the virtual machine
                       with
                       with
@@ -239,8 +239,12 @@ class InstanceService(PageableObjectMixin, CloudService):
                        work. Some providers (e.g. OpenStack) support a null
                        work. Some providers (e.g. OpenStack) support a null
                        value but the behaviour is implementation specific.
                        value but the behaviour is implementation specific.
 
 
+        :type  label: ``str``
+        :param label: The label of the virtual machine instance. The instance
+                      name will be derived from this label.
+
         :type  zone: ``Zone`` or ``str``
         :type  zone: ``Zone`` or ``str``
-        :param zone: The Zone or its name, where the instance should be placed.
+        :param zone: The Zone or its id, where the instance should be placed.
                      This parameter is provided for legacy compatibility (with
                      This parameter is provided for legacy compatibility (with
                      classic networks).
                      classic networks).
 
 
@@ -248,7 +252,7 @@ class InstanceService(PageableObjectMixin, CloudService):
                      parameter, but in its absence, this value will be used.
                      parameter, but in its absence, this value will be used.
 
 
         :type  key_pair: ``KeyPair`` or ``str``
         :type  key_pair: ``KeyPair`` or ``str``
-        :param key_pair: The KeyPair object or its name, to set for the
+        :param key_pair: The KeyPair object or its id, to set for the
                          instance.
                          instance.
 
 
         :type  vm_firewalls: A ``list`` of ``VMFirewall`` objects or a
         :type  vm_firewalls: A ``list`` of ``VMFirewall`` objects or a
@@ -311,7 +315,7 @@ class VolumeService(PageableObjectMixin, CloudService):
         """
         """
         Searches for a volume by a given list of attributes.
         Searches for a volume by a given list of attributes.
 
 
-        Supported attributes: name
+        Supported attributes: label
 
 
         :rtype: ``object`` of :class:`.Volume`
         :rtype: ``object`` of :class:`.Volume`
         :return: a Volume object or ``None`` if not found.
         :return: a Volume object or ``None`` if not found.
@@ -329,19 +333,19 @@ class VolumeService(PageableObjectMixin, CloudService):
         pass
         pass
 
 
     @abstractmethod
     @abstractmethod
-    def create(self, name, size, zone, snapshot=None, description=None):
+    def create(self, size, zone, label=None, snapshot=None, description=None):
         """
         """
         Creates a new volume.
         Creates a new volume.
 
 
-        :type  name: ``str``
-        :param name: The name of the volume.
-
         :type  size: ``int``
         :type  size: ``int``
         :param size: The size of the volume (in GB).
         :param size: The size of the volume (in GB).
 
 
         :type  zone: ``str`` or :class:`.PlacementZone` object
         :type  zone: ``str`` or :class:`.PlacementZone` object
         :param zone: The availability zone in which the Volume will be created.
         :param zone: The availability zone in which the Volume will be created.
 
 
+        :type  label: ``str``
+        :param label: The label for the volume.
+
         :type  snapshot: ``str`` or :class:`.Snapshot` object
         :type  snapshot: ``str`` or :class:`.Snapshot` object
         :param snapshot: An optional reference to a snapshot from which this
         :param snapshot: An optional reference to a snapshot from which this
                          volume should be created.
                          volume should be created.
@@ -378,7 +382,7 @@ class SnapshotService(PageableObjectMixin, CloudService):
         """
         """
         Searches for a snapshot by a given list of attributes.
         Searches for a snapshot by a given list of attributes.
 
 
-        Supported attributes: name
+        Supported attributes: label
 
 
         :rtype: list of :class:`.Snapshot`
         :rtype: list of :class:`.Snapshot`
         :return: a Snapshot object or an empty list if none found.
         :return: a Snapshot object or an empty list if none found.
@@ -396,16 +400,16 @@ class SnapshotService(PageableObjectMixin, CloudService):
         pass
         pass
 
 
     @abstractmethod
     @abstractmethod
-    def create(self, name, volume, description=None):
+    def create(self, volume, label=None, description=None):
         """
         """
         Creates a new snapshot off a volume.
         Creates a new snapshot off a volume.
 
 
-        :type  name: ``str``
-        :param name: The name of the snapshot
-
         :type  volume: ``str`` or ``Volume``
         :type  volume: ``str`` or ``Volume``
         :param volume: The volume to create a snapshot of.
         :param volume: The volume to create a snapshot of.
 
 
+        :type  label: ``str``
+        :param label: The label for the snapshot.
+
         :type  description: ``str``
         :type  description: ``str``
         :param description: An optional description that may be supported by
         :param description: An optional description that may be supported by
                             some providers. Providers that do not support this
                             some providers. Providers that do not support this
@@ -437,11 +441,11 @@ class StorageService(CloudService):
 
 
             # print all volumes
             # print all volumes
             for vol in provider.storage.volumes:
             for vol in provider.storage.volumes:
-                print(vol.id, vol.name)
+                print(vol.id, vol.name, vol.label)
 
 
-            # find volume by name
-            vol = provider.storage.volumes.find(name='my_vol')[0]
-            print(vol.id, vol.name)
+            # find volume by label
+            vol = provider.storage.volumes.find(label='my_vol')[0]
+            print(vol.id, vol.name, vol.label)
 
 
         :rtype: :class:`.VolumeService`
         :rtype: :class:`.VolumeService`
         :return: a VolumeService object
         :return: a VolumeService object
@@ -459,11 +463,11 @@ class StorageService(CloudService):
 
 
             # print all snapshots
             # print all snapshots
             for snap in provider.storage.snapshots:
             for snap in provider.storage.snapshots:
-                print(snap.id, snap.name)
+                print(snap.id, snap.name, snap.label)
 
 
-            # find snapshot by name
-            snap = provider.storage.snapshots.find(name='my_snap')[0]
-            print(snap.id, snap.name)
+            # find snapshot by label
+            snap = provider.storage.snapshots.find(label='my_snap')[0]
+            print(snap.id, snap.name, snap.label)
 
 
         :rtype: :class:`.SnapshotService`
         :rtype: :class:`.SnapshotService`
         :return: a SnapshotService object
         :return: a SnapshotService object
@@ -516,7 +520,7 @@ class ImageService(PageableObjectMixin, CloudService):
         """
         """
         Searches for an image by a given list of attributes
         Searches for an image by a given list of attributes
 
 
-        Supported attributes: name
+        Supported attributes: name, label
 
 
         :rtype: ``object`` of :class:`.Image`
         :rtype: ``object`` of :class:`.Image`
         :return:  an Image instance
         :return:  an Image instance
@@ -616,7 +620,7 @@ class NetworkService(PageableObjectMixin, CloudService):
         """
         """
         Searches for a network by a given list of attributes.
         Searches for a network by a given list of attributes.
 
 
-        Supported attributes: name
+        Supported attributes: name, label
 
 
         :rtype: List of ``object`` of :class:`.Network`
         :rtype: List of ``object`` of :class:`.Network`
         :return: A list of Network objects matching the supplied attributes.
         :return: A list of Network objects matching the supplied attributes.
@@ -624,14 +628,10 @@ class NetworkService(PageableObjectMixin, CloudService):
         pass
         pass
 
 
     @abstractmethod
     @abstractmethod
-    def create(self, name, cidr_block):
+    def create(self, cidr_block, label=None):
         """
         """
         Create a new network.
         Create a new network.
 
 
-        :type name: ``str``
-        :param name: A network name. The name will be set if the
-                     provider supports it.
-
         :type cidr_block: ``str``
         :type cidr_block: ``str``
         :param cidr_block: The cidr block for this network. Some providers
         :param cidr_block: The cidr block for this network. Some providers
                            will respect this at the network level, while others
                            will respect this at the network level, while others
@@ -642,6 +642,9 @@ class NetworkService(PageableObjectMixin, CloudService):
                            between a /16 netmask (65,536 IP addresses) and /28
                            between a /16 netmask (65,536 IP addresses) and /28
                            netmask (16 IP addresses). e.g. 10.0.0.0/16
                            netmask (16 IP addresses). e.g. 10.0.0.0/16
 
 
+        :type label: ``str``
+        :param label: A label for the network.
+
         :rtype: ``object`` of :class:`.Network`
         :rtype: ``object`` of :class:`.Network`
         :return:  A Network object
         :return:  A Network object
         """
         """
@@ -668,11 +671,11 @@ class NetworkService(PageableObjectMixin, CloudService):
 
 
             # Print all subnets
             # Print all subnets
             for s in provider.networking.subnets:
             for s in provider.networking.subnets:
-                print(s.id, s.name)
+                print(s.id, s.name, s.label)
 
 
             # Get subnet by ID
             # Get subnet by ID
             s = provider.networking.subnets.get('subnet-id')
             s = provider.networking.subnets.get('subnet-id')
-            print(s.id, s.name)
+            print(s.id, s.name, s.label)
 
 
         :rtype: :class:`.SubnetService`
         :rtype: :class:`.SubnetService`
         :return: a SubnetService object
         :return: a SubnetService object
@@ -719,7 +722,7 @@ class SubnetService(PageableObjectMixin, CloudService):
         """
         """
         Searches for a subnet by a given list of attributes.
         Searches for a subnet by a given list of attributes.
 
 
-        Supported attributes: name
+        Supported attributes: name, label
 
 
         :rtype: List of ``object`` of :class:`.Subnet`
         :rtype: List of ``object`` of :class:`.Subnet`
         :return: A list of Subnet objects matching the supplied attributes.
         :return: A list of Subnet objects matching the supplied attributes.
@@ -727,14 +730,10 @@ class SubnetService(PageableObjectMixin, CloudService):
         pass
         pass
 
 
     @abstractmethod
     @abstractmethod
-    def create(self, name, network_id, cidr_block, zone):
+    def create(self, network_id, cidr_block, zone, label=None):
         """
         """
         Create a new subnet within the supplied network.
         Create a new subnet within the supplied network.
 
 
-        :type name: ``str``
-        :param name: The subnet name. The name will be set if the
-                     provider supports it.
-
         :type network: :class:`.Network` object or ``str``
         :type network: :class:`.Network` object or ``str``
         :param network: Network object or ID under which to create the subnet.
         :param network: Network object or ID under which to create the subnet.
 
 
@@ -746,6 +745,9 @@ class SubnetService(PageableObjectMixin, CloudService):
         :param zone: A placement zone for the subnet. Some providers
         :param zone: A placement zone for the subnet. Some providers
                      may not support this, in which case the value is ignored.
                      may not support this, in which case the value is ignored.
 
 
+        :type label: ``str``
+        :param label: The subnet label.
+
         :rtype: ``object`` of :class:`.Subnet`
         :rtype: ``object`` of :class:`.Subnet`
         :return:  A Subnet object
         :return:  A Subnet object
         """
         """
@@ -759,7 +761,7 @@ class SubnetService(PageableObjectMixin, CloudService):
         are not particularly concerned with how the network is structured.
         are not particularly concerned with how the network is structured.
 
 
         A default network is one marked as such by the provider or matches the
         A default network is one marked as such by the provider or matches the
-        default name used by this library (e.g., cloudbridge-net).
+        default label used by this library (e.g., cloudbridge-net).
 
 
         :type zone: :class:`.PlacementZone` object ``str``
         :type zone: :class:`.PlacementZone` object ``str``
         :param zone: Placement zone where to look for the subnet.
         :param zone: Placement zone where to look for the subnet.
@@ -814,7 +816,7 @@ class RouterService(PageableObjectMixin, CloudService):
         """
         """
         Searches for a router by a given list of attributes.
         Searches for a router by a given list of attributes.
 
 
-        Supported attributes: name
+        Supported attributes: name, label
 
 
         :rtype: List of ``object`` of :class:`.Router`
         :rtype: List of ``object`` of :class:`.Router`
         :return: A list of Router objects matching the supplied attributes.
         :return: A list of Router objects matching the supplied attributes.
@@ -822,17 +824,16 @@ class RouterService(PageableObjectMixin, CloudService):
         pass
         pass
 
 
     @abstractmethod
     @abstractmethod
-    def create(self, name, network):
+    def create(self, network, label=None):
         """
         """
         Create a new router.
         Create a new router.
 
 
-        :type name: ``str``
-        :param name: A router name. The name will be set if the provider
-                     supports it.
-
         :type network: :class:`.Network` object or ``str``
         :type network: :class:`.Network` object or ``str``
         :param network: Network object or ID under which to create the router.
         :param network: Network object or ID under which to create the router.
 
 
+        :type label: ``str``
+        :param label: A router label.
+
         :rtype: ``object`` of :class:`.Router`
         :rtype: ``object`` of :class:`.Router`
         :return:  A Router object
         :return:  A Router object
         """
         """

+ 85 - 50
cloudbridge/cloud/providers/aws/resources.py

@@ -141,7 +141,7 @@ class AWSPlacementZone(BasePlacementZone):
 
 
     @property
     @property
     def name(self):
     def name(self):
-        return self._aws_zone
+        return self.id
 
 
     @property
     @property
     def region_name(self):
     def region_name(self):
@@ -160,7 +160,7 @@ class AWSVMType(BaseVMType):
 
 
     @property
     @property
     def name(self):
     def name(self):
-        return self._inst_dict['instance_type']
+        return self.id
 
 
     @property
     @property
     def family(self):
     def family(self):
@@ -222,17 +222,21 @@ class AWSInstance(BaseInstance):
         return self._ec2_instance.id
         return self._ec2_instance.id
 
 
     @property
     @property
-    # pylint:disable=arguments-differ
     def name(self):
     def name(self):
+        return self.id
+
+    @property
+    # pylint:disable=arguments-differ
+    def label(self):
         """
         """
         .. note:: an instance must have a (case sensitive) tag ``Name``
         .. note:: an instance must have a (case sensitive) tag ``Name``
         """
         """
         return find_tag_value(self._ec2_instance.tags, 'Name')
         return find_tag_value(self._ec2_instance.tags, 'Name')
 
 
-    @name.setter
+    @label.setter
     # pylint:disable=arguments-differ
     # pylint:disable=arguments-differ
-    def name(self, value):
-        self.assert_valid_resource_name(value)
+    def label(self, value):
+        self.assert_valid_resource_label(value)
         self._ec2_instance.create_tags(Tags=[{'Key': 'Name', 'Value': value}])
         self._ec2_instance.create_tags(Tags=[{'Key': 'Name', 'Value': value}])
 
 
     @property
     @property
@@ -290,14 +294,17 @@ class AWSInstance(BaseInstance):
     def key_pair_name(self):
     def key_pair_name(self):
         return self._ec2_instance.key_name
         return self._ec2_instance.key_name
 
 
-    def create_image(self, name):
-        self.assert_valid_resource_name(name)
+    def create_image(self, label=None):
+        self.assert_valid_resource_label(label)
+        name = self._generate_name_from_label(label)
 
 
         image = AWSMachineImage(self._provider,
         image = AWSMachineImage(self._provider,
                                 self._ec2_instance.create_image(Name=name))
                                 self._ec2_instance.create_image(Name=name))
         # Wait for the image to exist
         # Wait for the image to exist
         self._provider.ec2_conn.meta.client.get_waiter('image_exists').wait(
         self._provider.ec2_conn.meta.client.get_waiter('image_exists').wait(
             ImageIds=[image.id])
             ImageIds=[image.id])
+        # Add image label
+        image.label = label
         # Return the image
         # Return the image
         image.refresh()
         image.refresh()
         return image
         return image
@@ -385,17 +392,21 @@ class AWSVolume(BaseVolume):
         return self._volume.id
         return self._volume.id
 
 
     @property
     @property
-    # pylint:disable=arguments-differ
     def name(self):
     def name(self):
+        return self.id
+
+    @property
+    # pylint:disable=arguments-differ
+    def label(self):
         try:
         try:
             return find_tag_value(self._volume.tags, 'Name')
             return find_tag_value(self._volume.tags, 'Name')
         except ClientError as e:
         except ClientError as e:
-            log.warn("Cannot get name for volume {0}: {1}".format(self.id, e))
+            log.warn("Cannot get label for volume {0}: {1}".format(self.id, e))
 
 
-    @name.setter
+    @label.setter
     # pylint:disable=arguments-differ
     # pylint:disable=arguments-differ
-    def name(self, value):
-        self.assert_valid_resource_name(value)
+    def label(self, value):
+        self.assert_valid_resource_label(value)
         self._volume.create_tags(Tags=[{'Key': 'Name', 'Value': value}])
         self._volume.create_tags(Tags=[{'Key': 'Name', 'Value': value}])
 
 
     @property
     @property
@@ -449,12 +460,12 @@ class AWSVolume(BaseVolume):
                 Device=a.device,
                 Device=a.device,
                 Force=force)
                 Force=force)
 
 
-    def create_snapshot(self, name, description=None):
+    def create_snapshot(self, label=None, description=None):
         snap = AWSSnapshot(
         snap = AWSSnapshot(
             self._provider,
             self._provider,
             self._volume.create_snapshot(
             self._volume.create_snapshot(
                 Description=description))
                 Description=description))
-        snap.name = name
+        snap.label = label
         return snap
         return snap
 
 
     def delete(self):
     def delete(self):
@@ -498,17 +509,21 @@ class AWSSnapshot(BaseSnapshot):
         return self._snapshot.id
         return self._snapshot.id
 
 
     @property
     @property
-    # pylint:disable=arguments-differ
     def name(self):
     def name(self):
+        return self.id
+
+    @property
+    # pylint:disable=arguments-differ
+    def label(self):
         try:
         try:
             return find_tag_value(self._snapshot.tags, 'Name')
             return find_tag_value(self._snapshot.tags, 'Name')
         except ClientError as e:
         except ClientError as e:
-            log.warn("Cannot get name for snap {0}: {1}".format(self.id, e))
+            log.warn("Cannot get label for snap {0}: {1}".format(self.id, e))
 
 
-    @name.setter
+    @label.setter
     # pylint:disable=arguments-differ
     # pylint:disable=arguments-differ
-    def name(self, value):
-        self.assert_valid_resource_name(value)
+    def label(self, value):
+        self.assert_valid_resource_label(value)
         self._snapshot.create_tags(Tags=[{'Key': 'Name', 'Value': value}])
         self._snapshot.create_tags(Tags=[{'Key': 'Name', 'Value': value}])
 
 
     @property
     @property
@@ -553,13 +568,13 @@ class AWSSnapshot(BaseSnapshot):
         self._snapshot.delete()
         self._snapshot.delete()
 
 
     def create_volume(self, placement, size=None, volume_type=None, iops=None):
     def create_volume(self, placement, size=None, volume_type=None, iops=None):
+        label = "from_snap_{0}".format(self.label or self.id)
         cb_vol = self._provider.storage.volumes.create(
         cb_vol = self._provider.storage.volumes.create(
-            name=self.name,
+            label=label,
             size=size,
             size=size,
             zone=placement,
             zone=placement,
             snapshot=self.id)
             snapshot=self.id)
         cb_vol.wait_till_ready()
         cb_vol.wait_till_ready()
-        cb_vol.name = "from_snap_{0}".format(self.name or self.id)
         return cb_vol
         return cb_vol
 
 
 
 
@@ -577,18 +592,22 @@ class AWSVMFirewall(BaseVMFirewall):
 
 
     @property
     @property
     def name(self):
     def name(self):
+        """
+        Return the name of this VM firewall.
+        """
+        return self._vm_firewall.group_name
+
+    @property
+    def label(self):
         try:
         try:
-            name = find_tag_value(self._vm_firewall.tags, 'Name')
-            if not name:  # Return group_name (which cannot be changed)
-                name = self._vm_firewall.group_name
-            return name
+            return find_tag_value(self._vm_firewall.tags, 'Name')
         except ClientError:
         except ClientError:
-            return self._vm_firewall.group_name
+            return None
 
 
-    @name.setter
+    @label.setter
     # pylint:disable=arguments-differ
     # pylint:disable=arguments-differ
-    def name(self, value):
-        self.assert_valid_resource_name(value)
+    def label(self, value):
+        self.assert_valid_resource_label(value)
         self._vm_firewall.create_tags(Tags=[{'Key': 'Name', 'Value': value}])
         self._vm_firewall.create_tags(Tags=[{'Key': 'Name', 'Value': value}])
 
 
     @property
     @property
@@ -826,7 +845,7 @@ class AWSBucket(BaseBucket):
 
 
     @property
     @property
     def name(self):
     def name(self):
-        return self._bucket.name
+        return self.id
 
 
     @property
     @property
     def objects(self):
     def objects(self):
@@ -924,12 +943,16 @@ class AWSNetwork(BaseNetwork):
 
 
     @property
     @property
     def name(self):
     def name(self):
+        return self.id
+
+    @property
+    def label(self):
         return find_tag_value(self._vpc.tags, 'Name')
         return find_tag_value(self._vpc.tags, 'Name')
 
 
-    @name.setter
+    @label.setter
     # pylint:disable=arguments-differ
     # pylint:disable=arguments-differ
-    def name(self, value):
-        self.assert_valid_resource_name(value)
+    def label(self, value):
+        self.assert_valid_resource_label(value)
         self._vpc.create_tags(Tags=[{'Key': 'Name', 'Value': value}])
         self._vpc.create_tags(Tags=[{'Key': 'Name', 'Value': value}])
 
 
     @property
     @property
@@ -996,12 +1019,16 @@ class AWSSubnet(BaseSubnet):
 
 
     @property
     @property
     def name(self):
     def name(self):
+        return self.id
+
+    @property
+    def label(self):
         return find_tag_value(self._subnet.tags, 'Name')
         return find_tag_value(self._subnet.tags, 'Name')
 
 
-    @name.setter
+    @label.setter
     # pylint:disable=arguments-differ
     # pylint:disable=arguments-differ
-    def name(self, value):
-        self.assert_valid_resource_name(value)
+    def label(self, value):
+        self.assert_valid_resource_label(value)
         self._subnet.create_tags(Tags=[{'Key': 'Name', 'Value': value}])
         self._subnet.create_tags(Tags=[{'Key': 'Name', 'Value': value}])
 
 
     @property
     @property
@@ -1105,12 +1132,16 @@ class AWSRouter(BaseRouter):
 
 
     @property
     @property
     def name(self):
     def name(self):
+        return self.id
+
+    @property
+    def label(self):
         return find_tag_value(self._route_table.tags, 'Name')
         return find_tag_value(self._route_table.tags, 'Name')
 
 
-    @name.setter
+    @label.setter
     # pylint:disable=arguments-differ
     # pylint:disable=arguments-differ
-    def name(self, value):
-        self.assert_valid_resource_name(value)
+    def label(self, value):
+        self.assert_valid_resource_label(value)
         self._route_table.create_tags(Tags=[{'Key': 'Name', 'Value': value}])
         self._route_table.create_tags(Tags=[{'Key': 'Name', 'Value': value}])
 
 
     def refresh(self):
     def refresh(self):
@@ -1168,15 +1199,15 @@ class AWSGatewayContainer(BaseGatewayContainer):
                                   cb_resource=AWSInternetGateway,
                                   cb_resource=AWSInternetGateway,
                                   boto_collection_name='internet_gateways')
                                   boto_collection_name='internet_gateways')
 
 
-    def get_or_create_inet_gateway(self, name=None):
-        log.debug("Get or create inet gateway %s on net %s", name,
+    def get_or_create_inet_gateway(self, label=None):
+        log.debug("Get or create inet gateway %s on net %s", label,
                   self._network)
                   self._network)
-        if name:
-            AWSInternetGateway.assert_valid_resource_name(name)
+        if label:
+            AWSInternetGateway.assert_valid_resource_label(label)
 
 
         network_id = self._network.id if isinstance(
         network_id = self._network.id if isinstance(
             self._network, AWSNetwork) else self._network
             self._network, AWSNetwork) else self._network
-        # Don't filter by name because it may conflict with at least the
+        # Don't filter by label because it may conflict with at least the
         # default VPC that most accounts have but that network is typically
         # default VPC that most accounts have but that network is typically
         # without a name.
         # without a name.
         gtw = self.svc.find(filter_name='attachment.vpc-id',
         gtw = self.svc.find(filter_name='attachment.vpc-id',
@@ -1185,8 +1216,8 @@ class AWSGatewayContainer(BaseGatewayContainer):
             return gtw[0]  # There can be only one gtw attached to a VPC
             return gtw[0]  # There can be only one gtw attached to a VPC
         # Gateway does not exist so create one and attach to the supplied net
         # Gateway does not exist so create one and attach to the supplied net
         cb_gateway = self.svc.create('create_internet_gateway')
         cb_gateway = self.svc.create('create_internet_gateway')
-        if name:
-            cb_gateway.name = name
+        if label:
+            cb_gateway.label = label
         cb_gateway._gateway.attach_to_vpc(VpcId=network_id)
         cb_gateway._gateway.attach_to_vpc(VpcId=network_id)
         return cb_gateway
         return cb_gateway
 
 
@@ -1219,12 +1250,16 @@ class AWSInternetGateway(BaseInternetGateway):
 
 
     @property
     @property
     def name(self):
     def name(self):
+        return self.id
+
+    @property
+    def label(self):
         return find_tag_value(self._gateway.tags, 'Name')
         return find_tag_value(self._gateway.tags, 'Name')
 
 
-    @name.setter
+    @label.setter
     # pylint:disable=arguments-differ
     # pylint:disable=arguments-differ
-    def name(self, value):
-        self.assert_valid_resource_name(value)
+    def label(self, value):
+        self.assert_valid_resource_label(value)
         self._gateway.create_tags(Tags=[{'Key': 'Name', 'Value': value}])
         self._gateway.create_tags(Tags=[{'Key': 'Name', 'Value': value}])
 
 
     def refresh(self):
     def refresh(self):

+ 83 - 79
cloudbridge/cloud/providers/aws/services.py

@@ -100,7 +100,7 @@ class AWSKeyPairService(BaseKeyPairService):
 
 
     def create(self, name, public_key_material=None):
     def create(self, name, public_key_material=None):
         log.debug("Creating Key Pair Service %s", name)
         log.debug("Creating Key Pair Service %s", name)
-        AWSKeyPair.assert_valid_resource_name(name)
+        AWSKeyPair.assert_valid_resource_label(name)
         private_key = None
         private_key = None
         if not public_key_material:
         if not public_key_material:
             public_key_material, private_key = cb_helpers.generate_key_pair()
             public_key_material, private_key = cb_helpers.generate_key_pair()
@@ -132,24 +132,27 @@ class AWSVMFirewallService(BaseVMFirewallService):
     def list(self, limit=None, marker=None):
     def list(self, limit=None, marker=None):
         return self.svc.list(limit=limit, marker=marker)
         return self.svc.list(limit=limit, marker=marker)
 
 
-    def create(self, name, description, network_id):
+    def create(self, description, network_id, label=None):
         log.debug("Creating Firewall Service with the parameters "
         log.debug("Creating Firewall Service with the parameters "
-                  "[name: %s id: %s description: %s]", name, network_id,
+                  "[label: %s id: %s description: %s]", label, network_id,
                   description)
                   description)
-        AWSVMFirewall.assert_valid_resource_name(name)
-        return self.svc.create('create_security_group', GroupName=name,
-                               Description=description, VpcId=network_id)
+        AWSVMFirewall.assert_valid_resource_label(label)
+        name = AWSVMFirewall._generate_name_from_label(label)
+        obj = self.svc.create('create_security_group', GroupName=name,
+                              Description=description, VpcId=network_id)
+        obj.label = label
+        return obj
 
 
     def find(self, **kwargs):
     def find(self, **kwargs):
-        name = kwargs.pop('name', None)
-
+        # Filter by name or label
+        label = kwargs.pop('label', None)
+        log.debug("Searching for Firewall Service %s", label)
         # All kwargs should have been popped at this time.
         # All kwargs should have been popped at this time.
         if len(kwargs) > 0:
         if len(kwargs) > 0:
             raise TypeError("Unrecognised parameters for search: %s."
             raise TypeError("Unrecognised parameters for search: %s."
-                            " Supported attributes: %s" % (kwargs, 'name'))
-
-        log.debug("Searching for Firewall Service %s", name)
-        return self.svc.find(filter_name='group-name', filter_value=name)
+                            " Supported attributes: %s" % (kwargs, 'label'))
+        return self.svc.find(filter_name='tag:Name',
+                             filter_value=label)
 
 
     def delete(self, firewall_id):
     def delete(self, firewall_id):
         log.info("Deleting Firewall Service with the id %s", firewall_id)
         log.info("Deleting Firewall Service with the id %s", firewall_id)
@@ -195,25 +198,25 @@ class AWSVolumeService(BaseVolumeService):
         return self.svc.get(volume_id)
         return self.svc.get(volume_id)
 
 
     def find(self, **kwargs):
     def find(self, **kwargs):
-        name = kwargs.pop('name', None)
+        label = kwargs.pop('label', None)
 
 
         # All kwargs should have been popped at this time.
         # All kwargs should have been popped at this time.
         if len(kwargs) > 0:
         if len(kwargs) > 0:
             raise TypeError("Unrecognised parameters for search: %s."
             raise TypeError("Unrecognised parameters for search: %s."
-                            " Supported attributes: %s" % (kwargs, 'name'))
+                            " Supported attributes: %s" % (kwargs, 'label'))
 
 
-        log.debug("Searching for AWS Volume Service %s", name)
-        return self.svc.find(filter_name='tag:Name', filter_value=name)
+        log.debug("Searching for AWS Volume Service %s", label)
+        return self.svc.find(filter_name='tag:Name', filter_value=label)
 
 
     def list(self, limit=None, marker=None):
     def list(self, limit=None, marker=None):
         return self.svc.list(limit=limit, marker=marker)
         return self.svc.list(limit=limit, marker=marker)
 
 
-    def create(self, name, size, zone, snapshot=None, description=None):
+    def create(self, size, zone, label=None, snapshot=None, description=None):
         log.debug("Creating AWS Volume Service with the parameters "
         log.debug("Creating AWS Volume Service with the parameters "
-                  "[name: %s size: %s zone: %s snapshot: %s "
-                  "description: %s]", name, size, zone, snapshot,
+                  "[label: %s size: %s zone: %s snapshot: %s "
+                  "description: %s]", label, size, zone, snapshot,
                   description)
                   description)
-        AWSVolume.assert_valid_resource_name(name)
+        AWSVolume.assert_valid_resource_label(label)
 
 
         zone_id = zone.id if isinstance(zone, PlacementZone) else zone
         zone_id = zone.id if isinstance(zone, PlacementZone) else zone
         snapshot_id = snapshot.id if isinstance(
         snapshot_id = snapshot.id if isinstance(
@@ -224,7 +227,7 @@ class AWSVolumeService(BaseVolumeService):
                                  SnapshotId=snapshot_id)
                                  SnapshotId=snapshot_id)
         # Wait until ready to tag instance
         # Wait until ready to tag instance
         cb_vol.wait_till_ready()
         cb_vol.wait_till_ready()
-        cb_vol.name = name
+        cb_vol.label = label
         if description:
         if description:
             cb_vol.description = description
             cb_vol.description = description
         return cb_vol
         return cb_vol
@@ -244,34 +247,34 @@ class AWSSnapshotService(BaseSnapshotService):
         return self.svc.get(snapshot_id)
         return self.svc.get(snapshot_id)
 
 
     def find(self, **kwargs):
     def find(self, **kwargs):
-        name = kwargs.pop('name', None)
+        label = kwargs.pop('label', None)
 
 
         # All kwargs should have been popped at this time.
         # All kwargs should have been popped at this time.
         if len(kwargs) > 0:
         if len(kwargs) > 0:
             raise TypeError("Unrecognised parameters for search: %s."
             raise TypeError("Unrecognised parameters for search: %s."
-                            " Supported attributes: %s" % (kwargs, 'name'))
+                            " Supported attributes: %s" % (kwargs, 'label'))
 
 
-        log.debug("Searching for AWS Snapshot Service %s", name)
-        return self.svc.find(filter_name='tag:Name', filter_value=name)
+        log.debug("Searching for AWS Snapshot Service %s", label)
+        return self.svc.find(filter_name='tag:Name', filter_value=label)
 
 
     def list(self, limit=None, marker=None):
     def list(self, limit=None, marker=None):
         return self.svc.list(limit=limit, marker=marker)
         return self.svc.list(limit=limit, marker=marker)
 
 
-    def create(self, name, volume, description=None):
+    def create(self, volume, label=None, description=None):
         """
         """
         Creates a new snapshot of a given volume.
         Creates a new snapshot of a given volume.
         """
         """
         log.debug("Creating a new AWS snapshot Service with the "
         log.debug("Creating a new AWS snapshot Service with the "
-                  "parameters [name: %s volume: %s description: %s]",
-                  name, volume, description)
-        AWSSnapshot.assert_valid_resource_name(name)
+                  "parameters [label: %s volume: %s description: %s]",
+                  label, volume, description)
+        AWSSnapshot.assert_valid_resource_label(label)
 
 
         volume_id = volume.id if isinstance(volume, AWSVolume) else volume
         volume_id = volume.id if isinstance(volume, AWSVolume) else volume
 
 
         cb_snap = self.svc.create('create_snapshot', VolumeId=volume_id)
         cb_snap = self.svc.create('create_snapshot', VolumeId=volume_id)
         # Wait until ready to tag instance
         # Wait until ready to tag instance
         cb_snap.wait_till_ready()
         cb_snap.wait_till_ready()
-        cb_snap.name = name
+        cb_snap.label = label
         if cb_snap.description:
         if cb_snap.description:
             cb_snap.description = description
             cb_snap.description = description
         return cb_snap
         return cb_snap
@@ -328,7 +331,7 @@ class AWSBucketService(BaseBucketService):
     def create(self, name, location=None):
     def create(self, name, location=None):
         log.debug("Creating AWS Bucket with the params "
         log.debug("Creating AWS Bucket with the params "
                   "[name: %s, location: %s]", name, location)
                   "[name: %s, location: %s]", name, location)
-        AWSBucket.assert_valid_resource_name(name)
+        AWSBucket.assert_valid_resource_label(name)
         loc_constraint = location or self.provider.region_name
         loc_constraint = location or self.provider.region_name
         # Due to an API issue in S3, specifying us-east-1 as a
         # Due to an API issue in S3, specifying us-east-1 as a
         # LocationConstraint results in an InvalidLocationConstraint.
         # LocationConstraint results in an InvalidLocationConstraint.
@@ -356,15 +359,15 @@ class AWSImageService(BaseImageService):
         return self.svc.get(image_id)
         return self.svc.get(image_id)
 
 
     def find(self, **kwargs):
     def find(self, **kwargs):
+        # Filter by name or label
         name = kwargs.pop('name', None)
         name = kwargs.pop('name', None)
-
-        # All kwargs should have been popped at this time.
-        if len(kwargs) > 0:
-            raise TypeError("Unrecognised parameters for search: %s."
-                            " Supported attributes: %s" % (kwargs, 'name'))
-
-        log.debug("Searching for AWS Image Service %s", name)
-        return self.svc.find(filter_name='name', filter_value=name)
+        if name:
+            log.debug("Searching for AWS Image Service %s", name)
+            obj_list = self.svc.find(filter_name='name', filter_value=name)
+        else:
+            obj_list = self.svc
+        filters = ['label']
+        return cb_helpers.generic_find(filters, kwargs, obj_list)
 
 
     def list(self, filter_by_owner=True, limit=None, marker=None):
     def list(self, filter_by_owner=True, limit=None, marker=None):
         return self.svc.list(Owners=['self'] if filter_by_owner else [],
         return self.svc.list(Owners=['self'] if filter_by_owner else [],
@@ -405,15 +408,15 @@ class AWSInstanceService(BaseInstanceService):
                                   cb_resource=AWSInstance,
                                   cb_resource=AWSInstance,
                                   boto_collection_name='instances')
                                   boto_collection_name='instances')
 
 
-    def create(self, name, image, vm_type, subnet, zone,
+    def create(self, image, vm_type, subnet, zone, label=None,
                key_pair=None, vm_firewalls=None, user_data=None,
                key_pair=None, vm_firewalls=None, user_data=None,
                launch_config=None, **kwargs):
                launch_config=None, **kwargs):
         log.debug("Creating AWS Instance Service with the params "
         log.debug("Creating AWS Instance Service with the params "
-                  "[name: %s image: %s type: %s subnet: %s zone: %s "
+                  "[label: %s image: %s type: %s subnet: %s zone: %s "
                   "key pair: %s firewalls: %s user data: %s config %s "
                   "key pair: %s firewalls: %s user data: %s config %s "
-                  "others: %s]", name, image, vm_type, subnet, zone,
+                  "others: %s]", label, image, vm_type, subnet, zone,
                   key_pair, vm_firewalls, user_data, launch_config, kwargs)
                   key_pair, vm_firewalls, user_data, launch_config, kwargs)
-        AWSInstance.assert_valid_resource_name(name)
+        AWSInstance.assert_valid_resource_label(label)
 
 
         image_id = image.id if isinstance(image, MachineImage) else image
         image_id = image.id if isinstance(image, MachineImage) else image
         vm_size = vm_type.id if \
         vm_size = vm_type.id if \
@@ -450,7 +453,7 @@ class AWSInstanceService(BaseInstanceService):
             # pylint:disable=protected-access
             # pylint:disable=protected-access
             inst[0]._wait_till_exists()
             inst[0]._wait_till_exists()
             # Tag the instance w/ the name
             # Tag the instance w/ the name
-            inst[0].name = name
+            inst[0].label = label
             return inst[0]
             return inst[0]
         raise ValueError(
         raise ValueError(
             'Expected a single object response, got a list: %s' % inst)
             'Expected a single object response, got a list: %s' % inst)
@@ -544,14 +547,14 @@ class AWSInstanceService(BaseInstanceService):
         return self.svc.get(instance_id)
         return self.svc.get(instance_id)
 
 
     def find(self, **kwargs):
     def find(self, **kwargs):
-        name = kwargs.pop('name', None)
+        label = kwargs.pop('label', None)
 
 
         # All kwargs should have been popped at this time.
         # All kwargs should have been popped at this time.
         if len(kwargs) > 0:
         if len(kwargs) > 0:
             raise TypeError("Unrecognised parameters for search: %s."
             raise TypeError("Unrecognised parameters for search: %s."
-                            " Supported attributes: %s" % (kwargs, 'name'))
+                            " Supported attributes: %s" % (kwargs, 'label'))
 
 
-        return self.svc.find(filter_name='tag:Name', filter_value=name)
+        return self.svc.find(filter_name='tag:Name', filter_value=label)
 
 
     def list(self, limit=None, marker=None):
     def list(self, limit=None, marker=None):
         return self.svc.list(limit=limit, marker=marker)
         return self.svc.list(limit=limit, marker=marker)
@@ -653,26 +656,26 @@ class AWSNetworkService(BaseNetworkService):
         return self.svc.list(limit=limit, marker=marker)
         return self.svc.list(limit=limit, marker=marker)
 
 
     def find(self, **kwargs):
     def find(self, **kwargs):
-        name = kwargs.pop('name', None)
+        label = kwargs.pop('label', None)
 
 
         # All kwargs should have been popped at this time.
         # All kwargs should have been popped at this time.
         if len(kwargs) > 0:
         if len(kwargs) > 0:
             raise TypeError("Unrecognised parameters for search: %s."
             raise TypeError("Unrecognised parameters for search: %s."
-                            " Supported attributes: %s" % (kwargs, 'name'))
+                            " Supported attributes: %s" % (kwargs, 'label'))
 
 
-        log.debug("Searching for AWS Network Service %s", name)
-        return self.svc.find(filter_name='tag:Name', filter_value=name)
+        log.debug("Searching for AWS Network Service %s", label)
+        return self.svc.find(filter_name='tag:Name', filter_value=label)
 
 
-    def create(self, name, cidr_block):
+    def create(self, cidr_block, label=None):
         log.debug("Creating AWS Network Service with the params "
         log.debug("Creating AWS Network Service with the params "
-                  "[name: %s block: %s]", name, cidr_block)
-        AWSNetwork.assert_valid_resource_name(name)
+                  "[label: %s block: %s]", label, cidr_block)
+        AWSNetwork.assert_valid_resource_label(label)
 
 
         cb_net = self.svc.create('create_vpc', CidrBlock=cidr_block)
         cb_net = self.svc.create('create_vpc', CidrBlock=cidr_block)
         # Wait until ready to tag instance
         # Wait until ready to tag instance
         cb_net.wait_till_ready()
         cb_net.wait_till_ready()
-        if name:
-            cb_net.name = name
+        if label:
+            cb_net.label = label
         return cb_net
         return cb_net
 
 
 
 
@@ -698,21 +701,21 @@ class AWSSubnetService(BaseSubnetService):
             return self.svc.list(limit=limit, marker=marker)
             return self.svc.list(limit=limit, marker=marker)
 
 
     def find(self, **kwargs):
     def find(self, **kwargs):
-        name = kwargs.pop('name', None)
+        label = kwargs.pop('label', None)
 
 
         # All kwargs should have been popped at this time.
         # All kwargs should have been popped at this time.
         if len(kwargs) > 0:
         if len(kwargs) > 0:
             raise TypeError("Unrecognised parameters for search: %s."
             raise TypeError("Unrecognised parameters for search: %s."
-                            " Supported attributes: %s" % (kwargs, 'name'))
+                            " Supported attributes: %s" % (kwargs, 'label'))
 
 
-        log.debug("Searching for AWS Subnet Service %s", name)
-        return self.svc.find(filter_name='tag:Name', filter_value=name)
+        log.debug("Searching for AWS Subnet Service %s", label)
+        return self.svc.find(filter_name='tag:Name', filter_value=label)
 
 
-    def create(self, name, network, cidr_block, zone):
+    def create(self, network, cidr_block, zone, label=None):
         log.debug("Creating AWS Subnet Service with the params "
         log.debug("Creating AWS Subnet Service with the params "
-                  "[name: %s network: %s block: %s zone: %s]",
-                  name, network, cidr_block, zone)
-        AWSSubnet.assert_valid_resource_name(name)
+                  "[label: %s network: %s block: %s zone: %s]",
+                  label, network, cidr_block, zone)
+        AWSSubnet.assert_valid_resource_label(label)
 
 
         network_id = network.id if isinstance(network, AWSNetwork) else network
         network_id = network.id if isinstance(network, AWSNetwork) else network
 
 
@@ -720,8 +723,8 @@ class AWSSubnetService(BaseSubnetService):
                                  VpcId=network_id,
                                  VpcId=network_id,
                                  CidrBlock=cidr_block,
                                  CidrBlock=cidr_block,
                                  AvailabilityZone=zone)
                                  AvailabilityZone=zone)
-        if name:
-            subnet.name = name
+        if label:
+            subnet.label = label
         return subnet
         return subnet
 
 
     def get_or_create_default(self, zone):
     def get_or_create_default(self, zone):
@@ -744,17 +747,18 @@ class AWSSubnetService(BaseSubnetService):
             # pylint:disable=protected-access
             # pylint:disable=protected-access
             for tag in sn._subnet.tags or {}:
             for tag in sn._subnet.tags or {}:
                 if (tag.get('Key') == 'Name' and
                 if (tag.get('Key') == 'Name' and
-                        tag.get('Value') == AWSSubnet.CB_DEFAULT_SUBNET_NAME):
+                        tag.get('Value') == AWSSubnet.CB_DEFAULT_SUBNET_LABEL):
                     return sn
                     return sn
         # No provider-default Subnet exists, try to create it (net + subnets)
         # No provider-default Subnet exists, try to create it (net + subnets)
         default_net = self.provider.networking.networks.create(
         default_net = self.provider.networking.networks.create(
-            name=AWSNetwork.CB_DEFAULT_NETWORK_NAME, cidr_block='10.0.0.0/16')
+            label=AWSNetwork.CB_DEFAULT_NETWORK_LABEL,
+            cidr_block='10.0.0.0/16')
         # Create a subnet in each of the region's zones
         # Create a subnet in each of the region's zones
         region = self.provider.compute.regions.get(self.provider.region_name)
         region = self.provider.compute.regions.get(self.provider.region_name)
         default_sn = None
         default_sn = None
         for i, z in enumerate(region.zones):
         for i, z in enumerate(region.zones):
-            sn = self.create(AWSSubnet.CB_DEFAULT_SUBNET_NAME, default_net,
-                             '10.0.{0}.0/24'.format(i), z.name)
+            sn = self.create(default_net, '10.0.{0}.0/24'.format(i), z.name,
+                             label=AWSSubnet.CB_DEFAULT_SUBNET_LABEL)
             if zone and zone == z.name:
             if zone and zone == z.name:
                 default_sn = sn
                 default_sn = sn
         # No specific zone was supplied; return the last created subnet
         # No specific zone was supplied; return the last created subnet
@@ -782,27 +786,27 @@ class AWSRouterService(BaseRouterService):
         return self.svc.get(router_id)
         return self.svc.get(router_id)
 
 
     def find(self, **kwargs):
     def find(self, **kwargs):
-        name = kwargs.pop('name', None)
+        label = kwargs.pop('label', None)
 
 
         # All kwargs should have been popped at this time.
         # All kwargs should have been popped at this time.
         if len(kwargs) > 0:
         if len(kwargs) > 0:
             raise TypeError("Unrecognised parameters for search: %s."
             raise TypeError("Unrecognised parameters for search: %s."
-                            " Supported attributes: %s" % (kwargs, 'name'))
+                            " Supported attributes: %s" % (kwargs, 'label'))
 
 
-        log.debug("Searching for AWS Router Service %s", name)
-        return self.svc.find(filter_name='tag:Name', filter_value=name)
+        log.debug("Searching for AWS Router Service %s", label)
+        return self.svc.find(filter_name='tag:Name', filter_value=label)
 
 
     def list(self, limit=None, marker=None):
     def list(self, limit=None, marker=None):
         return self.svc.list(limit=limit, marker=marker)
         return self.svc.list(limit=limit, marker=marker)
 
 
-    def create(self, name, network):
+    def create(self, network, label=None):
         log.debug("Creating AWS Router Service with the params "
         log.debug("Creating AWS Router Service with the params "
-                  "[name: %s network: %s]", name, network)
-        AWSRouter.assert_valid_resource_name(name)
+                  "[label: %s network: %s]", label, network)
+        AWSRouter.assert_valid_resource_label(label)
 
 
         network_id = network.id if isinstance(network, AWSNetwork) else network
         network_id = network.id if isinstance(network, AWSNetwork) else network
 
 
         cb_router = self.svc.create('create_route_table', VpcId=network_id)
         cb_router = self.svc.create('create_route_table', VpcId=network_id)
-        if name:
-            cb_router.name = name
+        if label:
+            cb_router.label = label
         return cb_router
         return cb_router

+ 2 - 2
cloudbridge/cloud/providers/azure/azure_client.py

@@ -19,7 +19,7 @@ from msrestazure.azure_exceptions import CloudError
 import tenacity
 import tenacity
 
 
 from cloudbridge.cloud.interfaces.exceptions import \
 from cloudbridge.cloud.interfaces.exceptions import \
-    InvalidNameException, ProviderConnectionException, WaitStateException
+    InvalidLabelException, ProviderConnectionException, WaitStateException
 
 
 from . import helpers as azure_helpers
 from . import helpers as azure_helpers
 
 
@@ -343,7 +343,7 @@ class AzureClient(object):
                                    'azure/azure-resource-manager/resource-' \
                                    'azure/azure-resource-manager/resource-' \
                                    'manager-storage-account-name-errors\n' \
                                    'manager-storage-account-name-errors\n' \
                                    % cloud_error2
                                    % cloud_error2
-                            raise InvalidNameException(mess)
+                            raise InvalidLabelException(mess)
                         else:
                         else:
                             raise cloud_error2
                             raise cloud_error2
                 else:
                 else:

+ 115 - 56
cloudbridge/cloud/providers/openstack/resources.py

@@ -99,10 +99,27 @@ class OpenStackMachineImage(BaseMachineImage):
     @property
     @property
     def name(self):
     def name(self):
         """
         """
-        Get the image name.
+        Get the image identifier.
+        """
+        return self._os_image.id
+
+    @property
+    def label(self):
+        """
+        Get the image label.
         """
         """
         return self._os_image.name
         return self._os_image.name
 
 
+    @label.setter
+    # pylint:disable=arguments-differ
+    def label(self, value):
+        """
+        Set the image label.
+        """
+        self.assert_valid_resource_label(value)
+        self._os_image.name = value
+        self._os_image.update(name=value)
+
     @property
     @property
     def description(self):
     def description(self):
         """
         """
@@ -280,20 +297,27 @@ class OpenStackInstance(BaseInstance):
         return self._os_instance.id
         return self._os_instance.id
 
 
     @property
     @property
-    # pylint:disable=arguments-differ
     def name(self):
     def name(self):
         """
         """
-        Get the instance name.
+        Get the instance identifier.
+        """
+        return self.id
+
+    @property
+    # pylint:disable=arguments-differ
+    def label(self):
+        """
+        Get the instance label.
         """
         """
         return self._os_instance.name
         return self._os_instance.name
 
 
-    @name.setter
+    @label.setter
     # pylint:disable=arguments-differ
     # pylint:disable=arguments-differ
-    def name(self, value):
+    def label(self, value):
         """
         """
-        Set the instance name.
+        Set the instance label.
         """
         """
-        self.assert_valid_resource_name(value)
+        self.assert_valid_resource_label(value)
 
 
         self._os_instance.name = value
         self._os_instance.name = value
         self._os_instance.update(name=value)
         self._os_instance.update(name=value)
@@ -417,22 +441,25 @@ class OpenStackInstance(BaseInstance):
         return [fw.id for fw in self.vm_firewalls]
         return [fw.id for fw in self.vm_firewalls]
 
 
     @property
     @property
-    def key_pair_name(self):
+    def key_pair_id(self):
         """
         """
-        Get the name of the key pair associated with this instance.
+        Get the id of the key pair associated with this instance.
         """
         """
         return self._os_instance.key_name
         return self._os_instance.key_name
 
 
-    def create_image(self, name):
+    def create_image(self, label=None):
         """
         """
         Create a new image based on this instance.
         Create a new image based on this instance.
         """
         """
-        log.debug("Creating OpenStack Image with the name %s", name)
-        self.assert_valid_resource_name(name)
+        log.debug("Creating OpenStack Image with the label %s", label)
+        self.assert_valid_resource_label(label)
+        name = self._generate_name_from_label(label)
 
 
         image_id = self._os_instance.create_image(name)
         image_id = self._os_instance.create_image(name)
-        return OpenStackMachineImage(
+        img = OpenStackMachineImage(
             self._provider, self._provider.compute.images.get(image_id))
             self._provider, self._provider.compute.images.get(image_id))
+        img.label = label
+        return img
 
 
     def _get_fip(self, floating_ip):
     def _get_fip(self, floating_ip):
         """Get a floating IP object based on the supplied ID."""
         """Get a floating IP object based on the supplied ID."""
@@ -508,8 +535,7 @@ class OpenStackRegion(BaseRegion):
 
 
     @property
     @property
     def name(self):
     def name(self):
-        return (self._os_region.id if type(self._os_region) == Region else
-                self._os_region)
+        return self.id
 
 
     @property
     @property
     def zones(self):
     def zones(self):
@@ -557,20 +583,24 @@ class OpenStackVolume(BaseVolume):
         return self._volume.id
         return self._volume.id
 
 
     @property
     @property
-    # pylint:disable=arguments-differ
     def name(self):
     def name(self):
+        return self.id
+
+    @property
+    # pylint:disable=arguments-differ
+    def label(self):
         """
         """
-        Get the volume name.
+        Get the volume label.
         """
         """
         return self._volume.name
         return self._volume.name
 
 
-    @name.setter
+    @label.setter
     # pylint:disable=arguments-differ
     # pylint:disable=arguments-differ
-    def name(self, value):
+    def label(self, value):
         """
         """
-        Set the volume name.
+        Set the volume label.
         """
         """
-        self.assert_valid_resource_name(value)
+        self.assert_valid_resource_label(value)
         self._volume.name = value
         self._volume.name = value
         self._volume.update(name=value)
         self._volume.update(name=value)
 
 
@@ -628,12 +658,13 @@ class OpenStackVolume(BaseVolume):
         """
         """
         self._volume.detach()
         self._volume.detach()
 
 
-    def create_snapshot(self, name, description=None):
+    def create_snapshot(self, label=None, description=None):
         """
         """
         Create a snapshot of this Volume.
         Create a snapshot of this Volume.
         """
         """
         log.debug("Creating snapchat of volume: %s with the "
         log.debug("Creating snapchat of volume: %s with the "
-                  "description: %s", name, description)
+                  "description: %s", label, description)
+        name = self._generate_name_from_label(label)
         return self._provider.storage.snapshots.create(
         return self._provider.storage.snapshots.create(
             name, self, description=description)
             name, self, description=description)
 
 
@@ -683,20 +714,24 @@ class OpenStackSnapshot(BaseSnapshot):
         return self._snapshot.id
         return self._snapshot.id
 
 
     @property
     @property
-    # pylint:disable=arguments-differ
     def name(self):
     def name(self):
+        return self.id
+
+    @property
+    # pylint:disable=arguments-differ
+    def label(self):
         """
         """
-        Get the snapshot name.
+        Get the snapshot label.
         """
         """
         return self._snapshot.name
         return self._snapshot.name
 
 
-    @name.setter
+    @label.setter
     # pylint:disable=arguments-differ
     # pylint:disable=arguments-differ
-    def name(self, value):
+    def label(self, value):
         """
         """
-        Set the snapshot name.
+        Set the snapshot label.
         """
         """
-        self.assert_valid_resource_name(value)
+        self.assert_valid_resource_label(value)
         self._snapshot.name = value
         self._snapshot.name = value
         self._snapshot.update(name=value)
         self._snapshot.update(name=value)
 
 
@@ -750,13 +785,14 @@ class OpenStackSnapshot(BaseSnapshot):
         """
         """
         Create a new Volume from this Snapshot.
         Create a new Volume from this Snapshot.
         """
         """
-        vol_name = "from_snap_{0}".format(self.id or self.name)
+        vol_label = "from_snap_{0}".format(self.id or self.label)
+        name = self._generate_name_from_label(vol_label)
         size = size if size else self._snapshot.size
         size = size if size else self._snapshot.size
         os_vol = self._provider.cinder.volumes.create(
         os_vol = self._provider.cinder.volumes.create(
-            size, name=vol_name, availability_zone=placement,
+            size, name=name, availability_zone=placement,
             snapshot_id=self._snapshot.id)
             snapshot_id=self._snapshot.id)
         cb_vol = OpenStackVolume(self._provider, os_vol)
         cb_vol = OpenStackVolume(self._provider, os_vol)
-        cb_vol.name = vol_name
+        cb_vol.label = vol_label
         return cb_vol
         return cb_vol
 
 
 
 
@@ -774,7 +810,7 @@ class OpenStackGatewayContainer(BaseGatewayContainer):
         # all available networks and perform an assignment test to infer valid
         # all available networks and perform an assignment test to infer valid
         # floating ip nets.
         # floating ip nets.
         dummy_router = self._provider.networking.routers.create(
         dummy_router = self._provider.networking.routers.create(
-            network=self._network, name='cb_conn_test_router')
+            network=self._network, label='cb_conn_test_router')
         with cb_helpers.cleanup_action(lambda: dummy_router.delete()):
         with cb_helpers.cleanup_action(lambda: dummy_router.delete()):
             try:
             try:
                 dummy_router.attach_gateway(external_net)
                 dummy_router.attach_gateway(external_net)
@@ -782,10 +818,10 @@ class OpenStackGatewayContainer(BaseGatewayContainer):
             except Exception:
             except Exception:
                 return False
                 return False
 
 
-    def get_or_create_inet_gateway(self, name=None):
+    def get_or_create_inet_gateway(self, label=None):
         """For OS, inet gtw is any net that has `external` property set."""
         """For OS, inet gtw is any net that has `external` property set."""
-        if name:
-            OpenStackInternetGateway.assert_valid_resource_name(name)
+        if label:
+            OpenStackInternetGateway.assert_valid_resource_label(label)
 
 
         external_nets = (n for n in self._provider.networking.networks
         external_nets = (n for n in self._provider.networking.networks
                          if n.external)
                          if n.external)
@@ -833,14 +869,18 @@ class OpenStackNetwork(BaseNetwork):
 
 
     @property
     @property
     def name(self):
     def name(self):
+        return self.id
+
+    @property
+    def label(self):
         return self._network.get('name', None)
         return self._network.get('name', None)
 
 
-    @name.setter
-    def name(self, value):  # pylint:disable=arguments-differ
+    @label.setter
+    def label(self, value):  # pylint:disable=arguments-differ
         """
         """
-        Set the network name.
+        Set the network label.
         """
         """
-        self.assert_valid_resource_name(value)
+        self.assert_valid_resource_label(value)
         self._provider.neutron.update_network(self.id,
         self._provider.neutron.update_network(self.id,
                                               {'network': {'name': value}})
                                               {'network': {'name': value}})
         self.refresh()
         self.refresh()
@@ -910,14 +950,18 @@ class OpenStackSubnet(BaseSubnet):
 
 
     @property
     @property
     def name(self):
     def name(self):
+        return self.id
+
+    @property
+    def label(self):
         return self._subnet.get('name', None)
         return self._subnet.get('name', None)
 
 
-    @name.setter
-    def name(self, value):  # pylint:disable=arguments-differ
+    @label.setter
+    def label(self, value):  # pylint:disable=arguments-differ
         """
         """
-        Set the subnet name.
+        Set the subnet label.
         """
         """
-        self.assert_valid_resource_name(value)
+        self.assert_valid_resource_label(value)
         self._provider.neutron.update_subnet(
         self._provider.neutron.update_subnet(
             self.id, {'subnet': {'name': value}})
             self.id, {'subnet': {'name': value}})
         self._subnet['name'] = value
         self._subnet['name'] = value
@@ -1032,14 +1076,18 @@ class OpenStackRouter(BaseRouter):
 
 
     @property
     @property
     def name(self):
     def name(self):
+        return self.id
+
+    @property
+    def label(self):
         return self._router.get('name', None)
         return self._router.get('name', None)
 
 
-    @name.setter
-    def name(self, value):  # pylint:disable=arguments-differ
+    @label.setter
+    def label(self, value):  # pylint:disable=arguments-differ
         """
         """
-        Set the router name.
+        Set the router label.
         """
         """
-        self.assert_valid_resource_name(value)
+        self.assert_valid_resource_label(value)
         self._provider.neutron.update_router(
         self._provider.neutron.update_router(
             self.id, {'router': {'name': value}})
             self.id, {'router': {'name': value}})
         self.refresh()
         self.refresh()
@@ -1112,12 +1160,16 @@ class OpenStackInternetGateway(BaseInternetGateway):
 
 
     @property
     @property
     def name(self):
     def name(self):
+        return self.id
+
+    @property
+    def label(self):
         return self._gateway_net.get('name', None)
         return self._gateway_net.get('name', None)
 
 
-    @name.setter
+    @label.setter
     # pylint:disable=arguments-differ
     # pylint:disable=arguments-differ
-    def name(self, value):
-        self.assert_valid_resource_name(value)
+    def label(self, value):
+        self.assert_valid_resource_label(value)
         self._provider.neutron.update_network(self.id,
         self._provider.neutron.update_network(self.id,
                                               {'network': {'name': value}})
                                               {'network': {'name': value}})
         self.refresh()
         self.refresh()
@@ -1173,12 +1225,19 @@ class OpenStackVMFirewall(BaseVMFirewall):
 
 
     @property
     @property
     def name(self):
     def name(self):
+        """
+        Return the name of this VM firewall.
+        """
+        return self.id
+
+    @property
+    def label(self):
         return self._vm_firewall.name
         return self._vm_firewall.name
 
 
-    @name.setter
+    @label.setter
     # pylint:disable=arguments-differ
     # pylint:disable=arguments-differ
-    def name(self, value):
-        self.assert_valid_resource_name(value)
+    def label(self, value):
+        self.assert_valid_resource_label(value)
         self._provider.os_conn.network.update_security_group(self.id,
         self._provider.os_conn.network.update_security_group(self.id,
                                                              name=value)
                                                              name=value)
         self.refresh()
         self.refresh()
@@ -1319,7 +1378,7 @@ class OpenStackBucketObject(BaseBucketObject):
     @property
     @property
     def name(self):
     def name(self):
         """Get this object's name."""
         """Get this object's name."""
-        return self._obj.get("name")
+        return self.id
 
 
     @property
     @property
     def size(self):
     def size(self):
@@ -1432,7 +1491,7 @@ class OpenStackBucket(BaseBucket):
 
 
     @property
     @property
     def name(self):
     def name(self):
-        return self._bucket.get("name")
+        return self.id
 
 
     @property
     @property
     def objects(self):
     def objects(self):

+ 67 - 75
cloudbridge/cloud/providers/openstack/services.py

@@ -47,7 +47,6 @@ from cloudbridge.cloud.providers.openstack import helpers as oshelpers
 
 
 from .resources import OpenStackBucket
 from .resources import OpenStackBucket
 from .resources import OpenStackInstance
 from .resources import OpenStackInstance
-from .resources import OpenStackInternetGateway
 from .resources import OpenStackKeyPair
 from .resources import OpenStackKeyPair
 from .resources import OpenStackMachineImage
 from .resources import OpenStackMachineImage
 from .resources import OpenStackNetwork
 from .resources import OpenStackNetwork
@@ -170,7 +169,7 @@ class OpenStackKeyPairService(BaseKeyPairService):
 
 
     def create(self, name, public_key_material=None):
     def create(self, name, public_key_material=None):
         log.debug("Creating a new key pair with the name: %s", name)
         log.debug("Creating a new key pair with the name: %s", name)
-        OpenStackKeyPair.assert_valid_resource_name(name)
+        OpenStackKeyPair.assert_valid_resource_label(name)
 
 
         existing_kp = self.find(name=name)
         existing_kp = self.find(name=name)
         if existing_kp:
         if existing_kp:
@@ -211,27 +210,27 @@ class OpenStackVMFirewallService(BaseVMFirewallService):
         return ClientPagedResultList(self.provider, firewalls,
         return ClientPagedResultList(self.provider, firewalls,
                                      limit=limit, marker=marker)
                                      limit=limit, marker=marker)
 
 
-    def create(self, name, description, network_id):
-        OpenStackVMFirewall.assert_valid_resource_name(name)
+    def create(self, description, network_id, label=None):
+        OpenStackVMFirewall.assert_valid_resource_label(label)
         log.debug("Creating OpenStack VM Firewall with the params: "
         log.debug("Creating OpenStack VM Firewall with the params: "
-                  "[name: %s network id: %s description: %s]", name,
+                  "[label: %s network id: %s description: %s]", label,
                   network_id, description)
                   network_id, description)
         sg = self.provider.os_conn.network.create_security_group(
         sg = self.provider.os_conn.network.create_security_group(
-            name=name, description=description)
+            name=label, description=description)
         if sg:
         if sg:
             return OpenStackVMFirewall(self.provider, sg)
             return OpenStackVMFirewall(self.provider, sg)
         return None
         return None
 
 
     def find(self, **kwargs):
     def find(self, **kwargs):
-        name = kwargs.pop('name', None)
+        label = kwargs.pop('label', None)
 
 
         # All kwargs should have been popped at this time.
         # All kwargs should have been popped at this time.
         if len(kwargs) > 0:
         if len(kwargs) > 0:
             raise TypeError("Unrecognised parameters for search: %s."
             raise TypeError("Unrecognised parameters for search: %s."
-                            " Supported attributes: %s" % (kwargs, 'name'))
+                            " Supported attributes: %s" % (kwargs, 'label'))
 
 
-        log.debug("Searching for %s", name)
-        sgs = [self.provider.os_conn.network.find_security_group(name)]
+        log.debug("Searching for %s", label)
+        sgs = [self.provider.os_conn.network.find_security_group(label)]
         results = [OpenStackVMFirewall(self.provider, sg)
         results = [OpenStackVMFirewall(self.provider, sg)
                    for sg in sgs if sg]
                    for sg in sgs if sg]
         return ClientPagedResultList(self.provider, results)
         return ClientPagedResultList(self.provider, results)
@@ -263,19 +262,14 @@ class OpenStackImageService(BaseImageService):
 
 
     def find(self, **kwargs):
     def find(self, **kwargs):
         name = kwargs.pop('name', None)
         name = kwargs.pop('name', None)
-
-        # All kwargs should have been popped at this time.
-        if len(kwargs) > 0:
-            raise TypeError("Unrecognised parameters for search: %s."
-                            " Supported attributes: %s" % (kwargs, 'name'))
-
-        log.debug("Searching for the OpenStack image with the name: %s", name)
-        regex = fnmatch.translate(name)
+        label = kwargs.pop('label', None)
+        log.debug("Searching for OpenStack image with label: %s", label)
+        regex = fnmatch.translate(label)
         cb_images = [
         cb_images = [
             img
             img
             for img in self
             for img in self
-            if img.name and re.search(regex, img.name)]
-
+            if ((img.label and re.search(regex, img.label))
+                or img.name == name)]
         return oshelpers.to_server_paged_list(self.provider, cb_images)
         return oshelpers.to_server_paged_list(self.provider, cb_images)
 
 
     def list(self, filter_by_owner=True, limit=None, marker=None):
     def list(self, filter_by_owner=True, limit=None, marker=None):
@@ -352,15 +346,15 @@ class OpenStackVolumeService(BaseVolumeService):
             return None
             return None
 
 
     def find(self, **kwargs):
     def find(self, **kwargs):
-        name = kwargs.pop('name', None)
+        label = kwargs.pop('label', None)
 
 
         # All kwargs should have been popped at this time.
         # All kwargs should have been popped at this time.
         if len(kwargs) > 0:
         if len(kwargs) > 0:
             raise TypeError("Unrecognised parameters for search: %s."
             raise TypeError("Unrecognised parameters for search: %s."
-                            " Supported attributes: %s" % (kwargs, 'name'))
+                            " Supported attributes: %s" % (kwargs, 'label'))
 
 
-        log.debug("Searching for an OpenStack Volume with the name %s", name)
-        search_opts = {'name': name}
+        log.debug("Searching for an OpenStack Volume with the label %s", label)
+        search_opts = {'name': label}
         cb_vols = [
         cb_vols = [
             OpenStackVolume(self.provider, vol)
             OpenStackVolume(self.provider, vol)
             for vol in self.provider.cinder.volumes.list(
             for vol in self.provider.cinder.volumes.list(
@@ -382,21 +376,21 @@ class OpenStackVolumeService(BaseVolumeService):
 
 
         return oshelpers.to_server_paged_list(self.provider, cb_vols, limit)
         return oshelpers.to_server_paged_list(self.provider, cb_vols, limit)
 
 
-    def create(self, name, size, zone, snapshot=None, description=None):
+    def create(self, size, zone, label=None, snapshot=None, description=None):
         """
         """
         Creates a new volume.
         Creates a new volume.
         """
         """
         log.debug("Creating a new volume with the params: "
         log.debug("Creating a new volume with the params: "
-                  "[name: %s size: %s zone: %s snapshot: %s description: %s]",
-                  name, size, zone, snapshot, description)
-        OpenStackVolume.assert_valid_resource_name(name)
+                  "[label: %s size: %s zone: %s snapshot: %s description: %s]",
+                  label, size, zone, snapshot, description)
+        OpenStackVolume.assert_valid_resource_label(label)
 
 
         zone_id = zone.id if isinstance(zone, PlacementZone) else zone
         zone_id = zone.id if isinstance(zone, PlacementZone) else zone
         snapshot_id = snapshot.id if isinstance(
         snapshot_id = snapshot.id if isinstance(
             snapshot, OpenStackSnapshot) and snapshot else snapshot
             snapshot, OpenStackSnapshot) and snapshot else snapshot
 
 
         os_vol = self.provider.cinder.volumes.create(
         os_vol = self.provider.cinder.volumes.create(
-            size, name=name, description=description,
+            size, name=label, description=description,
             availability_zone=zone_id, snapshot_id=snapshot_id)
             availability_zone=zone_id, snapshot_id=snapshot_id)
         return OpenStackVolume(self.provider, os_vol)
         return OpenStackVolume(self.provider, os_vol)
 
 
@@ -420,22 +414,21 @@ class OpenStackSnapshotService(BaseSnapshotService):
             return None
             return None
 
 
     def find(self, **kwargs):
     def find(self, **kwargs):
-        name = kwargs.pop('name', None)
+        label = kwargs.pop('label', None)
 
 
         # All kwargs should have been popped at this time.
         # All kwargs should have been popped at this time.
         if len(kwargs) > 0:
         if len(kwargs) > 0:
             raise TypeError("Unrecognised parameters for search: %s."
             raise TypeError("Unrecognised parameters for search: %s."
-                            " Supported attributes: %s" % (kwargs, 'name'))
+                            " Supported attributes: %s" % (kwargs, 'label'))
 
 
-        search_opts = {'name': name,  # TODO: Cinder is ignoring name
+        search_opts = {'name': label,  # TODO: Cinder is ignoring name
                        'limit': oshelpers.os_result_limit(self.provider),
                        'limit': oshelpers.os_result_limit(self.provider),
                        'marker': None}
                        'marker': None}
         log.debug("Searching for an OpenStack volume with the following "
         log.debug("Searching for an OpenStack volume with the following "
                   "params: %s", search_opts)
                   "params: %s", search_opts)
         cb_snaps = [
         cb_snaps = [
             OpenStackSnapshot(self.provider, snap) for
             OpenStackSnapshot(self.provider, snap) for
-            snap in self.provider.cinder.volume_snapshots.list(search_opts)
-            if snap.name == name]
+            snap in self.provider.cinder.volume_snapshots.list(search_opts)]
 
 
         return oshelpers.to_server_paged_list(self.provider, cb_snaps)
         return oshelpers.to_server_paged_list(self.provider, cb_snaps)
 
 
@@ -451,18 +444,18 @@ class OpenStackSnapshotService(BaseSnapshotService):
                              'marker': marker})]
                              'marker': marker})]
         return oshelpers.to_server_paged_list(self.provider, cb_snaps, limit)
         return oshelpers.to_server_paged_list(self.provider, cb_snaps, limit)
 
 
-    def create(self, name, volume, description=None):
+    def create(self, volume, label=None, description=None):
         """
         """
         Creates a new snapshot of a given volume.
         Creates a new snapshot of a given volume.
         """
         """
-        log.debug("Creating a new snapshot of the %s volume.", name)
-        OpenStackSnapshot.assert_valid_resource_name(name)
+        log.debug("Creating a new snapshot of the %s volume.", label)
+        OpenStackSnapshot.assert_valid_resource_label(label)
 
 
         volume_id = (volume.id if isinstance(volume, OpenStackVolume)
         volume_id = (volume.id if isinstance(volume, OpenStackVolume)
                      else volume)
                      else volume)
 
 
         os_snap = self.provider.cinder.volume_snapshots.create(
         os_snap = self.provider.cinder.volume_snapshots.create(
-            volume_id, name=name,
+            volume_id, name=label,
             description=description)
             description=description)
         return OpenStackSnapshot(self.provider, os_snap)
         return OpenStackSnapshot(self.provider, os_snap)
 
 
@@ -521,7 +514,7 @@ class OpenStackBucketService(BaseBucketService):
         Create a new bucket.
         Create a new bucket.
         """
         """
         log.debug("Creating a new OpenStack Bucket with the name: %s", name)
         log.debug("Creating a new OpenStack Bucket with the name: %s", name)
-        OpenStackBucket.assert_valid_resource_name(name)
+        OpenStackBucket.assert_valid_resource_label(name)
 
 
         self.provider.swift.put_container(name)
         self.provider.swift.put_container(name)
         return self.get(name)
         return self.get(name)
@@ -596,12 +589,12 @@ class OpenStackInstanceService(BaseInstanceService):
     def __init__(self, provider):
     def __init__(self, provider):
         super(OpenStackInstanceService, self).__init__(provider)
         super(OpenStackInstanceService, self).__init__(provider)
 
 
-    def create(self, name, image, vm_type, subnet, zone,
+    def create(self, image, vm_type, subnet, zone, label=None,
                key_pair=None, vm_firewalls=None, user_data=None,
                key_pair=None, vm_firewalls=None, user_data=None,
                launch_config=None,
                launch_config=None,
                **kwargs):
                **kwargs):
         """Create a new virtual machine instance."""
         """Create a new virtual machine instance."""
-        OpenStackInstance.assert_valid_resource_name(name)
+        OpenStackInstance.assert_valid_resource_label(label)
 
 
         image_id = image.id if isinstance(image, MachineImage) else image
         image_id = image.id if isinstance(image, MachineImage) else image
         vm_size = vm_type.id if \
         vm_size = vm_type.id if \
@@ -632,7 +625,7 @@ class OpenStackInstanceService(BaseInstanceService):
         nics = None
         nics = None
         if subnet_id:
         if subnet_id:
             log.debug("Creating network port for %s in subnet: %s",
             log.debug("Creating network port for %s in subnet: %s",
-                      name, subnet_id)
+                      label, subnet_id)
             sg_list = []
             sg_list = []
             if vm_firewalls:
             if vm_firewalls:
                 if isinstance(vm_firewalls, list) and \
                 if isinstance(vm_firewalls, list) and \
@@ -640,13 +633,13 @@ class OpenStackInstanceService(BaseInstanceService):
                     sg_list = vm_firewalls
                     sg_list = vm_firewalls
                 else:
                 else:
                     sg_list = (self.provider.security.vm_firewalls
                     sg_list = (self.provider.security.vm_firewalls
-                               .find(name=sg) for sg in vm_firewalls)
+                               .find(label=sg) for sg in vm_firewalls)
                     sg_list = (sg[0] for sg in sg_list if sg)
                     sg_list = (sg[0] for sg in sg_list if sg)
             sg_id_list = [sg.id for sg in sg_list]
             sg_id_list = [sg.id for sg in sg_list]
             port_def = {
             port_def = {
                 "port": {
                 "port": {
                     "admin_state_up": True,
                     "admin_state_up": True,
-                    "name": name,
+                    "name": label,
                     "network_id": net_id,
                     "network_id": net_id,
                     "fixed_ips": [{"subnet_id": subnet_id}],
                     "fixed_ips": [{"subnet_id": subnet_id}],
                     "security_groups": sg_id_list
                     "security_groups": sg_id_list
@@ -658,13 +651,13 @@ class OpenStackInstanceService(BaseInstanceService):
             if vm_firewalls:
             if vm_firewalls:
                 if isinstance(vm_firewalls, list) and \
                 if isinstance(vm_firewalls, list) and \
                         isinstance(vm_firewalls[0], VMFirewall):
                         isinstance(vm_firewalls[0], VMFirewall):
-                    sg_name_list = [sg.name for sg in vm_firewalls]
+                    sg_name_list = [sg.label for sg in vm_firewalls]
                 else:
                 else:
                     sg_name_list = vm_firewalls
                     sg_name_list = vm_firewalls
 
 
         log.debug("Launching in subnet %s", subnet_id)
         log.debug("Launching in subnet %s", subnet_id)
         os_instance = self.provider.nova.servers.create(
         os_instance = self.provider.nova.servers.create(
-            name,
+            label,
             None if self._has_root_device(launch_config) else image_id,
             None if self._has_root_device(launch_config) else image_id,
             vm_size,
             vm_size,
             min_count=1,
             min_count=1,
@@ -731,14 +724,14 @@ class OpenStackInstanceService(BaseInstanceService):
         return BaseLaunchConfig(self.provider)
         return BaseLaunchConfig(self.provider)
 
 
     def find(self, **kwargs):
     def find(self, **kwargs):
-        name = kwargs.pop('name', None)
+        label = kwargs.pop('label', None)
 
 
         # All kwargs should have been popped at this time.
         # All kwargs should have been popped at this time.
         if len(kwargs) > 0:
         if len(kwargs) > 0:
             raise TypeError("Unrecognised parameters for search: %s."
             raise TypeError("Unrecognised parameters for search: %s."
-                            " Supported attributes: %s" % (kwargs, 'name'))
+                            " Supported attributes: %s" % (kwargs, 'label'))
 
 
-        search_opts = {'name': name}
+        search_opts = {'name': label}
         cb_insts = [
         cb_insts = [
             OpenStackInstance(self.provider, inst)
             OpenStackInstance(self.provider, inst)
             for inst in self.provider.nova.servers.list(
             for inst in self.provider.nova.servers.list(
@@ -809,26 +802,25 @@ class OpenStackNetworkService(BaseNetworkService):
                                      limit=limit, marker=marker)
                                      limit=limit, marker=marker)
 
 
     def find(self, **kwargs):
     def find(self, **kwargs):
-        name = kwargs.pop('name', None)
+        label = kwargs.pop('label', None)
 
 
         # All kwargs should have been popped at this time.
         # All kwargs should have been popped at this time.
         if len(kwargs) > 0:
         if len(kwargs) > 0:
             raise TypeError("Unrecognised parameters for search: %s."
             raise TypeError("Unrecognised parameters for search: %s."
-                            " Supported attributes: %s" % (kwargs, 'name'))
+                            " Supported attributes: %s" % (kwargs, 'label'))
 
 
-        log.debug("Searching for the OpenStack Network with the "
-                  "name: %s", name)
+        log.debug("Searching for OpenStack Network with label: %s", label)
         networks = [OpenStackNetwork(self.provider, network)
         networks = [OpenStackNetwork(self.provider, network)
                     for network in self.provider.neutron.list_networks(
                     for network in self.provider.neutron.list_networks(
-                        name=name)
+                        name=label)
                     .get('networks') if network]
                     .get('networks') if network]
         return ClientPagedResultList(self.provider, networks)
         return ClientPagedResultList(self.provider, networks)
 
 
-    def create(self, name, cidr_block):
+    def create(self, cidr_block, label=None):
         log.debug("Creating OpenStack Network with the params: "
         log.debug("Creating OpenStack Network with the params: "
-                  "[name: %s Cinder Block: %s]", name, cidr_block)
-        OpenStackNetwork.assert_valid_resource_name(name)
-
+                  "[label: %s Cinder Block: %s]", label, cidr_block)
+        OpenStackNetwork.assert_valid_resource_label(label)
+        name = OpenStackNetwork._generate_name_from_label(label)
         net_info = {'name': name}
         net_info = {'name': name}
         network = self.provider.neutron.create_network({'network': net_info})
         network = self.provider.neutron.create_network({'network': net_info})
         return OpenStackNetwork(self.provider, network.get('network'))
         return OpenStackNetwork(self.provider, network.get('network'))
@@ -856,16 +848,16 @@ class OpenStackSubnetService(BaseSubnetService):
         return ClientPagedResultList(self.provider, subnets,
         return ClientPagedResultList(self.provider, subnets,
                                      limit=limit, marker=marker)
                                      limit=limit, marker=marker)
 
 
-    def create(self, name, network, cidr_block, zone):
+    def create(self, network, cidr_block, zone, label=None):
         """zone param is ignored."""
         """zone param is ignored."""
         log.debug("Creating OpenStack Subnet with the params: "
         log.debug("Creating OpenStack Subnet with the params: "
-                  "[Name: %s Network: %s Cinder Block: %s Zone: -ignored-]",
-                  name, network, cidr_block)
-        OpenStackSubnet.assert_valid_resource_name(name)
+                  "[Label: %s Network: %s Cinder Block: %s Zone: -ignored-]",
+                  label, network, cidr_block)
+        OpenStackSubnet.assert_valid_resource_label(label)
 
 
         network_id = (network.id if isinstance(network, OpenStackNetwork)
         network_id = (network.id if isinstance(network, OpenStackNetwork)
                       else network)
                       else network)
-        subnet_info = {'name': name, 'network_id': network_id,
+        subnet_info = {'name': label, 'network_id': network_id,
                        'cidr': cidr_block, 'ip_version': 4}
                        'cidr': cidr_block, 'ip_version': 4}
         subnet = (self.provider.neutron.create_subnet({'subnet': subnet_info})
         subnet = (self.provider.neutron.create_subnet({'subnet': subnet_info})
                   .get('subnet'))
                   .get('subnet'))
@@ -876,20 +868,20 @@ class OpenStackSubnetService(BaseSubnetService):
         Subnet zone is not supported by OpenStack and is thus ignored.
         Subnet zone is not supported by OpenStack and is thus ignored.
         """
         """
         try:
         try:
-            sn = self.find(name=OpenStackSubnet.CB_DEFAULT_SUBNET_NAME)
+            sn = self.find(label=OpenStackSubnet.CB_DEFAULT_SUBNET_LABEL)
             if sn:
             if sn:
                 return sn[0]
                 return sn[0]
             # No default; create one
             # No default; create one
             net = self.provider.networking.networks.create(
             net = self.provider.networking.networks.create(
-                name=OpenStackNetwork.CB_DEFAULT_NETWORK_NAME,
+                label=OpenStackNetwork.CB_DEFAULT_NETWORK_LABEL,
                 cidr_block='10.0.0.0/16')
                 cidr_block='10.0.0.0/16')
-            sn = net.create_subnet(name=OpenStackSubnet.CB_DEFAULT_SUBNET_NAME,
-                                   cidr_block='10.0.0.0/24')
+            sn = net.create_subnet(
+                label=OpenStackSubnet.CB_DEFAULT_SUBNET_LABEL,
+                cidr_block='10.0.0.0/24')
             router = self.provider.networking.routers.create(
             router = self.provider.networking.routers.create(
-                network=net, name=OpenStackRouter.CB_DEFAULT_ROUTER_NAME)
+                network=net, label=OpenStackRouter.CB_DEFAULT_ROUTER_LABEL)
             router.attach_subnet(sn)
             router.attach_subnet(sn)
-            gteway = net.gateways.get_or_create_inet_gateway(
-                        OpenStackInternetGateway.CB_DEFAULT_INET_GATEWAY_NAME)
+            gteway = net.gateways.get_or_create_inet_gateway()
             router.attach_gateway(gteway)
             router.attach_gateway(gteway)
             return sn
             return sn
         except NeutronClientException:
         except NeutronClientException:
@@ -924,11 +916,11 @@ class OpenStackRouterService(BaseRouterService):
 
 
     def find(self, **kwargs):
     def find(self, **kwargs):
         obj_list = self
         obj_list = self
-        filters = ['name']
+        filters = ['label']
         matches = cb_helpers.generic_find(filters, kwargs, obj_list)
         matches = cb_helpers.generic_find(filters, kwargs, obj_list)
         return ClientPagedResultList(self._provider, list(matches))
         return ClientPagedResultList(self._provider, list(matches))
 
 
-    def create(self, name, network):
+    def create(self, network, label=None):
         """
         """
         ``network`` is not used by OpenStack.
         ``network`` is not used by OpenStack.
 
 
@@ -936,9 +928,9 @@ class OpenStackRouterService(BaseRouterService):
         https://developer.openstack.org/api-ref/networking/v2/
         https://developer.openstack.org/api-ref/networking/v2/
             ?expanded=delete-router-detail,create-router-detail#create-router
             ?expanded=delete-router-detail,create-router-detail#create-router
         """
         """
-        log.debug("Creating OpenStack Router with the name: %s", name)
-        OpenStackRouter.assert_valid_resource_name(name)
+        log.debug("Creating OpenStack Router with the label: %s", label)
+        OpenStackRouter.assert_valid_resource_label(label)
 
 
-        body = {'router': {'name': name}} if name else None
+        body = {'router': {'name': label}} if label else None
         router = self.provider.neutron.create_router(body)
         router = self.provider.neutron.create_router(body)
         return OpenStackRouter(self.provider, router.get('router'))
         return OpenStackRouter(self.provider, router.get('router'))

+ 2 - 2
docs/api_docs/cloud/exceptions.rst

@@ -23,9 +23,9 @@ ProviderConnectionException
 .. autoclass:: cloudbridge.cloud.interfaces.exceptions.ProviderConnectionException
 .. autoclass:: cloudbridge.cloud.interfaces.exceptions.ProviderConnectionException
     :members:
     :members:
 
 
-InvalidNameException
+InvalidLabelException
 -----------------------------
 -----------------------------
-.. autoclass:: cloudbridge.cloud.interfaces.exceptions.InvalidNameException
+.. autoclass:: cloudbridge.cloud.interfaces.exceptions.InvalidLabelException
     :members:
     :members:
 
 
 InvalidValueException
 InvalidValueException

+ 11 - 11
test/helpers/__init__.py

@@ -112,14 +112,14 @@ def get_provider_test_data(provider, key):
     return None
     return None
 
 
 
 
-def create_test_network(provider, name):
+def create_test_network(provider, label):
     """
     """
     Create a network with one subnet, returning the network and subnet objects.
     Create a network with one subnet, returning the network and subnet objects.
     """
     """
-    net = provider.networking.networks.create(name=name,
+    net = provider.networking.networks.create(label=label,
                                               cidr_block='10.0.0.0/16')
                                               cidr_block='10.0.0.0/16')
     cidr_block = (net.cidr_block).split('/')[0] or '10.0.0.1'
     cidr_block = (net.cidr_block).split('/')[0] or '10.0.0.1'
-    sn = net.create_subnet(cidr_block='{0}/28'.format(cidr_block), name=name,
+    sn = net.create_subnet(cidr_block='{0}/28'.format(cidr_block), label=label,
                            zone=get_provider_test_data(provider, 'placement'))
                            zone=get_provider_test_data(provider, 'placement'))
     return net, sn
     return net, sn
 
 
@@ -134,16 +134,16 @@ def delete_test_network(network):
                 pass
                 pass
 
 
 
 
-def get_test_gateway(provider, name):
+def get_test_gateway(provider, label):
     """
     """
     Get an internet gateway for testing.
     Get an internet gateway for testing.
 
 
     This includes creating a network for the gateway, which is also returned.
     This includes creating a network for the gateway, which is also returned.
     """
     """
-    net_name = 'cb_testgwnet-{0}'.format(get_uuid())
+    net_label = 'cb_testgwnet-{0}'.format(get_uuid())
     net = provider.networking.networks.create(
     net = provider.networking.networks.create(
-        name=net_name, cidr_block='10.0.0.0/16')
-    return net, net.gateways.get_or_create_inet_gateway(name)
+        label=net_label, cidr_block='10.0.0.0/16')
+    return net, net.gateways.get_or_create_inet_gateway(label=label)
 
 
 
 
 def delete_test_gateway(network, gateway):
 def delete_test_gateway(network, gateway):
@@ -156,13 +156,13 @@ def delete_test_gateway(network, gateway):
 
 
 
 
 def create_test_instance(
 def create_test_instance(
-        provider, instance_name, subnet, launch_config=None,
+        provider, instance_label, subnet, launch_config=None,
         key_pair=None, vm_firewalls=None, user_data=None):
         key_pair=None, vm_firewalls=None, user_data=None):
 
 
     instance = provider.compute.instances.create(
     instance = provider.compute.instances.create(
-        instance_name,
         get_provider_test_data(provider, 'image'),
         get_provider_test_data(provider, 'image'),
         get_provider_test_data(provider, 'vm_type'),
         get_provider_test_data(provider, 'vm_type'),
+        label=instance_label,
         subnet=subnet,
         subnet=subnet,
         zone=get_provider_test_data(provider, 'placement'),
         zone=get_provider_test_data(provider, 'placement'),
         key_pair=key_pair,
         key_pair=key_pair,
@@ -173,12 +173,12 @@ def create_test_instance(
     return instance
     return instance
 
 
 
 
-def get_test_instance(provider, name, key_pair=None, vm_firewalls=None,
+def get_test_instance(provider, label, key_pair=None, vm_firewalls=None,
                       subnet=None, user_data=None):
                       subnet=None, user_data=None):
     launch_config = None
     launch_config = None
     instance = create_test_instance(
     instance = create_test_instance(
         provider,
         provider,
-        name,
+        label,
         subnet=subnet,
         subnet=subnet,
         key_pair=key_pair,
         key_pair=key_pair,
         vm_firewalls=vm_firewalls,
         vm_firewalls=vm_firewalls,

+ 72 - 45
test/helpers/standard_interface_tests.py

@@ -8,7 +8,8 @@ This includes:
 import uuid
 import uuid
 
 
 from cloudbridge.cloud.interfaces.exceptions \
 from cloudbridge.cloud.interfaces.exceptions \
-    import InvalidNameException
+    import InvalidLabelException
+from cloudbridge.cloud.interfaces.resources import LabeledCloudResource
 from cloudbridge.cloud.interfaces.resources import ObjectLifeCycleMixin
 from cloudbridge.cloud.interfaces.resources import ObjectLifeCycleMixin
 from cloudbridge.cloud.interfaces.resources import ResultList
 from cloudbridge.cloud.interfaces.resources import ResultList
 
 
@@ -27,12 +28,15 @@ def check_json(test, obj):
     val = obj.to_json()
     val = obj.to_json()
     test.assertEqual(val.get('id'), obj.id)
     test.assertEqual(val.get('id'), obj.id)
     test.assertEqual(val.get('name'), obj.name)
     test.assertEqual(val.get('name'), obj.name)
+    if isinstance(obj, LabeledCloudResource):
+        test.assertEqual(val.get('label'), obj.label)
 
 
 
 
 def check_obj_properties(test, obj):
 def check_obj_properties(test, obj):
     test.assertEqual(obj, obj, "Object should be equal to itself")
     test.assertEqual(obj, obj, "Object should be equal to itself")
     test.assertFalse(obj != obj, "Object inequality should be false")
     test.assertFalse(obj != obj, "Object inequality should be false")
     check_obj_name(test, obj)
     check_obj_name(test, obj)
+    check_obj_label(test, obj)
 
 
 
 
 def check_list(test, service, obj):
 def check_list(test, service, obj):
@@ -66,18 +70,24 @@ def check_iter(test, service, obj):
 
 
 def check_find(test, service, obj):
 def check_find(test, service, obj):
     # check find
     # check find
-    find_objs = service.find(name=obj.name)
+    if isinstance(obj, LabeledCloudResource):
+        find_objs = service.find(label=obj.label)
+    else:
+        find_objs = service.find(name=obj.name)
     test.assertTrue(
     test.assertTrue(
         len(find_objs) == 1,
         len(find_objs) == 1,
         "Find objects for %s does not return the expected object: %s. Got %s"
         "Find objects for %s does not return the expected object: %s. Got %s"
-        % (type(obj).__name__, obj.name, find_objs))
+        % (type(obj).__name__, getattr(obj, 'label', obj.name), find_objs))
     test.assertEqual(find_objs[0].id, obj.id)
     test.assertEqual(find_objs[0].id, obj.id)
     return find_objs
     return find_objs
 
 
 
 
-def check_find_non_existent(test, service):
+def check_find_non_existent(test, service, obj):
     # check find
     # check find
-    find_objs = service.find(name="random_imagined_obj_name")
+    if isinstance(obj, LabeledCloudResource):
+        find_objs = service.find(label="random_imagined_obj_name")
+    else:
+        find_objs = service.find(name="random_imagined_obj_name")
     test.assertTrue(
     test.assertTrue(
         len(find_objs) == 0,
         len(find_objs) == 0,
         "Find non-existent object for %s returned unexpected objects: %s"
         "Find non-existent object for %s returned unexpected objects: %s"
@@ -113,6 +123,12 @@ def check_delete(test, service, obj, perform_delete=False):
 
 
 
 
 def check_obj_name(test, obj):
 def check_obj_name(test, obj):
+    name_property = getattr(type(obj), 'name', None)
+    test.assertIsInstance(name_property, property)
+    test.assertIsNone(name_property.fset, "Name should not have a setter")
+
+
+def check_obj_label(test, obj):
     """
     """
     Cloudbridge identifiers must be 1-63 characters long, and comply with
     Cloudbridge identifiers must be 1-63 characters long, and comply with
     RFC1035. In addition, identifiers should contain only lowercase letters,
     RFC1035. In addition, identifiers should contain only lowercase letters,
@@ -120,31 +136,32 @@ def check_obj_name(test, obj):
     characters are allowed.
     characters are allowed.
     """
     """
 
 
-    # if name has a setter, make sure invalid values cannot be set
-    name_property = getattr(type(obj), 'name', None)
-    if isinstance(name_property, property) and name_property.fset:
+    # if label property exists, make sure invalid values cannot be set
+    label_property = getattr(type(obj), 'label', None)
+    if isinstance(label_property, property):
+        test.assertIsInstance(obj, LabeledCloudResource)
         # setting letters, numbers and international characters should succeed
         # setting letters, numbers and international characters should succeed
         # TODO: Unicode characters trip up Moto. Add following: \u0D85\u0200
         # TODO: Unicode characters trip up Moto. Add following: \u0D85\u0200
-        VALID_NAME = u"hello_world-123"
-        original_name = obj.name
-        obj.name = VALID_NAME
+        VALID_LABEL = u"hello_world-123"
+        original_label = obj.label
+        obj.label = VALID_LABEL
         # setting spaces should raise an exception
         # setting spaces should raise an exception
-        with test.assertRaises(InvalidNameException):
-            obj.name = "hello world"
+        with test.assertRaises(InvalidLabelException):
+            obj.label = "hello world"
         # setting upper case characters should raise an exception
         # setting upper case characters should raise an exception
-        with test.assertRaises(InvalidNameException):
-            obj.name = "helloWorld"
+        with test.assertRaises(InvalidLabelException):
+            obj.label = "helloWorld"
         # setting special characters should raise an exception
         # setting special characters should raise an exception
-        with test.assertRaises(InvalidNameException):
-            obj.name = "hello.world:how_goes_it"
+        with test.assertRaises(InvalidLabelException):
+            obj.label = "hello.world:how_goes_it"
         # setting a length > 63 should result in an exception
         # setting a length > 63 should result in an exception
-        with test.assertRaises(InvalidNameException,
-                               msg="Name of length > 64 should be disallowed"):
-            obj.name = "a" * 64
-        # refreshing should yield the last successfully set name
+        with test.assertRaises(InvalidLabelException,
+                               msg="Label of length > 64 is not allowed"):
+            obj.label = "a" * 64
+        # refreshing should yield the last successfully set label
         obj.refresh()
         obj.refresh()
-        test.assertEqual(obj.name, VALID_NAME)
-        obj.name = original_name
+        test.assertEqual(obj.label, VALID_LABEL)
+        obj.label = original_label
 
 
 
 
 def check_standard_behaviour(test, service, obj):
 def check_standard_behaviour(test, service, obj):
@@ -158,7 +175,7 @@ def check_standard_behaviour(test, service, obj):
     objs_list = check_list(test, service, obj)
     objs_list = check_list(test, service, obj)
     objs_iter = check_iter(test, service, obj)
     objs_iter = check_iter(test, service, obj)
     objs_find = check_find(test, service, obj)
     objs_find = check_find(test, service, obj)
-    check_find_non_existent(test, service)
+    check_find_non_existent(test, service, obj)
     obj_get = check_get(test, service, obj)
     obj_get = check_get(test, service, obj)
     check_get_non_existent(test, service)
     check_get_non_existent(test, service)
 
 
@@ -178,29 +195,39 @@ def check_standard_behaviour(test, service, obj):
                                            objs_find[0].id, obj_get.id,
                                            objs_find[0].id, obj_get.id,
                                            obj.id))
                                            obj.id))
 
 
+    if isinstance(obj, LabeledCloudResource):
+        test.assertTrue(
+            obj.label == objs_list[0].label == objs_iter[0].label ==
+            objs_find[0].label == obj_get.label,
+            "Labels returned by list: {0}, iter: {1}, find: {2} and get: {3} "
+            " are not as expected: {4}".format(objs_list[0].id,
+                                               objs_iter[0].id,
+                                               objs_find[0].id, obj_get.id,
+                                               obj.id))
+
 
 
 def check_create(test, service, iface, name_prefix,
 def check_create(test, service, iface, name_prefix,
                  create_func, cleanup_func):
                  create_func, cleanup_func):
-    # check create with invalid name
-    with test.assertRaises(InvalidNameException):
+    # check create with invalid label
+    with test.assertRaises(InvalidLabelException):
         # spaces should raise an exception
         # spaces should raise an exception
         create_func("hello world")
         create_func("hello world")
-    # check create with invalid name
-    with test.assertRaises(InvalidNameException):
+    # check create with invalid label
+    with test.assertRaises(InvalidLabelException):
         # uppercase characters should raise an exception
         # uppercase characters should raise an exception
         create_func("helloWorld")
         create_func("helloWorld")
     # setting special characters should raise an exception
     # setting special characters should raise an exception
-    with test.assertRaises(InvalidNameException):
+    with test.assertRaises(InvalidLabelException):
         create_func("hello.world:how_goes_it")
         create_func("hello.world:how_goes_it")
     # setting a length > 63 should result in an exception
     # setting a length > 63 should result in an exception
-    with test.assertRaises(InvalidNameException,
-                           msg="Name of length > 64 should be disallowed"):
+    with test.assertRaises(InvalidLabelException,
+                           msg="Label of length > 63 should be disallowed"):
         create_func("a" * 64)
         create_func("a" * 64)
 
 
 
 
-def check_crud(test, service, iface, name_prefix,
+def check_crud(test, service, iface, label_prefix,
                create_func, cleanup_func, extra_test_func=None,
                create_func, cleanup_func, extra_test_func=None,
-               custom_check_delete=None, skip_name_check=False):
+               custom_check_delete=None, skip_label_check=False):
     """
     """
     Checks crud behaviour of a given cloudbridge service. The create_func will
     Checks crud behaviour of a given cloudbridge service. The create_func will
     be used as a factory function to create a service object and the
     be used as a factory function to create a service object and the
@@ -219,14 +246,14 @@ def check_crud(test, service, iface, name_prefix,
     :param iface: The type to test behaviour against. This type must be a
     :param iface: The type to test behaviour against. This type must be a
                   subclass of ``CloudResource``.
                   subclass of ``CloudResource``.
 
 
-    :type  name_prefix: ``str``
-    :param name_prefix: The name to prefix all created objects with. This
-                        function will generated a new name with the
-                        specified name_prefix for each test object created
-                        and pass that name into the create_func
+    :type  label_prefix: ``str``
+    :param label_prefix: The label to prefix all created objects with. This
+                        function will generated a new label with the
+                        specified label_prefix for each test object created
+                        and pass that label into the create_func
 
 
     :type  create_func: ``func``
     :type  create_func: ``func``
-    :param create_func: The create_func must accept the name of the object to
+    :param create_func: The create_func must accept the label of the object to
                         create as a parameter and return the constructed
                         create as a parameter and return the constructed
                         object.
                         object.
 
 
@@ -246,18 +273,18 @@ def check_crud(test, service, iface, name_prefix,
                                 instead of the standard check_delete function
                                 instead of the standard check_delete function
                                 to make sure that the object has been deleted.
                                 to make sure that the object has been deleted.
 
 
-    :type  skip_name_check: ``boolean``
-    :param skip_name_check:  If True, the invalid name checking will be
+    :type  skip_label_check: ``boolean``
+    :param skip_label_check:  If True, the invalid label checking will be
                              skipped.
                              skipped.
     """
     """
 
 
     obj = None
     obj = None
     with helpers.cleanup_action(lambda: cleanup_func(obj)):
     with helpers.cleanup_action(lambda: cleanup_func(obj)):
-        if not skip_name_check:
-            check_create(test, service, iface, name_prefix,
+        if not skip_label_check:
+            check_create(test, service, iface, label_prefix,
                          create_func, cleanup_func)
                          create_func, cleanup_func)
-        name = "{0}-{1}".format(name_prefix, helpers.get_uuid())
-        obj = create_func(name)
+        label = "{0}-{1}".format(label_prefix, helpers.get_uuid())
+        obj = create_func(label)
         if issubclass(iface, ObjectLifeCycleMixin):
         if issubclass(iface, ObjectLifeCycleMixin):
             obj.wait_till_ready()
             obj.wait_till_ready()
         check_standard_behaviour(test, service, obj)
         check_standard_behaviour(test, service, obj)

+ 31 - 31
test/test_block_store_service.py

@@ -26,11 +26,11 @@ class CloudBlockStoreServiceTestCase(ProviderTestBase):
         Create a new volume, check whether the expected values are set,
         Create a new volume, check whether the expected values are set,
         and delete it
         and delete it
         """
         """
-        def create_vol(name):
+        def create_vol(label):
             return self.provider.storage.volumes.create(
             return self.provider.storage.volumes.create(
-                name,
                 1,
                 1,
-                helpers.get_provider_test_data(self.provider, "placement"))
+                helpers.get_provider_test_data(self.provider, "placement"),
+                label=label)
 
 
         def cleanup_vol(vol):
         def cleanup_vol(vol):
             if vol:
             if vol:
@@ -46,7 +46,7 @@ class CloudBlockStoreServiceTestCase(ProviderTestBase):
         """
         """
         Create a new volume, and attempt to attach it to an instance
         Create a new volume, and attempt to attach it to an instance
         """
         """
-        name = "cb_attachvol-{0}".format(helpers.get_uuid())
+        label = "cb_attachvol-{0}".format(helpers.get_uuid())
         # Declare these variables and late binding will allow
         # Declare these variables and late binding will allow
         # the cleanup method access to the most current values
         # the cleanup method access to the most current values
         net = None
         net = None
@@ -54,12 +54,12 @@ class CloudBlockStoreServiceTestCase(ProviderTestBase):
         with helpers.cleanup_action(lambda: helpers.cleanup_test_resources(
         with helpers.cleanup_action(lambda: helpers.cleanup_test_resources(
                 test_instance, net)):
                 test_instance, net)):
             net, subnet = helpers.create_test_network(
             net, subnet = helpers.create_test_network(
-                self.provider, name)
+                self.provider, label)
             test_instance = helpers.get_test_instance(
             test_instance = helpers.get_test_instance(
-                self.provider, name, subnet=subnet)
+                self.provider, label, subnet=subnet)
 
 
             test_vol = self.provider.storage.volumes.create(
             test_vol = self.provider.storage.volumes.create(
-                name, 1, test_instance.zone_id)
+                1, test_instance.zone_id, label=label)
             with helpers.cleanup_action(lambda: test_vol.delete()):
             with helpers.cleanup_action(lambda: test_vol.delete()):
                 test_vol.wait_till_ready()
                 test_vol.wait_till_ready()
                 test_vol.attach(test_instance, '/dev/sda2')
                 test_vol.attach(test_instance, '/dev/sda2')
@@ -76,7 +76,7 @@ class CloudBlockStoreServiceTestCase(ProviderTestBase):
         """
         """
         Test volume properties
         Test volume properties
         """
         """
-        name = "cb_volprops-{0}".format(helpers.get_uuid())
+        label = "cb_volprops-{0}".format(helpers.get_uuid())
         vol_desc = 'newvoldesc1'
         vol_desc = 'newvoldesc1'
         # Declare these variables and late binding will allow
         # Declare these variables and late binding will allow
         # the cleanup method access to the most current values
         # the cleanup method access to the most current values
@@ -85,12 +85,12 @@ class CloudBlockStoreServiceTestCase(ProviderTestBase):
         with helpers.cleanup_action(lambda: helpers.cleanup_test_resources(
         with helpers.cleanup_action(lambda: helpers.cleanup_test_resources(
                 test_instance, net)):
                 test_instance, net)):
             net, subnet = helpers.create_test_network(
             net, subnet = helpers.create_test_network(
-                self.provider, name)
+                self.provider, label)
             test_instance = helpers.get_test_instance(
             test_instance = helpers.get_test_instance(
-                self.provider, name, subnet=subnet)
+                self.provider, label, subnet=subnet)
 
 
             test_vol = self.provider.storage.volumes.create(
             test_vol = self.provider.storage.volumes.create(
-                name, 1, test_instance.zone_id, description=vol_desc)
+                1, test_instance.zone_id, label=label, description=vol_desc)
             with helpers.cleanup_action(lambda: test_vol.delete()):
             with helpers.cleanup_action(lambda: test_vol.delete()):
                 test_vol.wait_till_ready()
                 test_vol.wait_till_ready()
                 self.assertTrue(
                 self.assertTrue(
@@ -121,11 +121,11 @@ class CloudBlockStoreServiceTestCase(ProviderTestBase):
                     self.assertEqual(test_vol.attachments.device,
                     self.assertEqual(test_vol.attachments.device,
                                      "/dev/sda2")
                                      "/dev/sda2")
                 test_vol.detach()
                 test_vol.detach()
-                test_vol.name = 'newvolname1'
+                test_vol.label = 'newvolname1'
                 test_vol.wait_for(
                 test_vol.wait_for(
                     [VolumeState.AVAILABLE],
                     [VolumeState.AVAILABLE],
                     terminal_states=[VolumeState.ERROR, VolumeState.DELETED])
                     terminal_states=[VolumeState.ERROR, VolumeState.DELETED])
-                self.assertEqual(test_vol.name, 'newvolname1')
+                self.assertEqual(test_vol.label, 'newvolname1')
                 self.assertEqual(test_vol.description, vol_desc)
                 self.assertEqual(test_vol.description, vol_desc)
                 self.assertIsNone(test_vol.attachments)
                 self.assertIsNone(test_vol.attachments)
                 test_vol.wait_for(
                 test_vol.wait_for(
@@ -139,17 +139,17 @@ class CloudBlockStoreServiceTestCase(ProviderTestBase):
         whether list_snapshots properly detects the new snapshot.
         whether list_snapshots properly detects the new snapshot.
         Delete everything afterwards.
         Delete everything afterwards.
         """
         """
-        name = "cb_crudsnap-{0}".format(helpers.get_uuid())
+        label = "cb_crudsnap-{0}".format(helpers.get_uuid())
         test_vol = self.provider.storage.volumes.create(
         test_vol = self.provider.storage.volumes.create(
-            name,
             1,
             1,
-            helpers.get_provider_test_data(self.provider, "placement"))
+            helpers.get_provider_test_data(self.provider, "placement"),
+            label=label)
         with helpers.cleanup_action(lambda: test_vol.delete()):
         with helpers.cleanup_action(lambda: test_vol.delete()):
             test_vol.wait_till_ready()
             test_vol.wait_till_ready()
 
 
-            def create_snap(name):
-                return test_vol.create_snapshot(name=name,
-                                                description=name)
+            def create_snap(label):
+                return test_vol.create_snapshot(label=label,
+                                                description=label)
 
 
             def cleanup_snap(snap):
             def cleanup_snap(snap):
                 if snap:
                 if snap:
@@ -161,9 +161,9 @@ class CloudBlockStoreServiceTestCase(ProviderTestBase):
                            "cb_snap", create_snap, cleanup_snap)
                            "cb_snap", create_snap, cleanup_snap)
 
 
             # Test creation of a snap via SnapshotService
             # Test creation of a snap via SnapshotService
-            def create_snap2(name):
+            def create_snap2(label):
                 return self.provider.storage.snapshots.create(
                 return self.provider.storage.snapshots.create(
-                    name=name, volume=test_vol, description=name)
+                    label=label, volume=test_vol, description=label)
 
 
             if (self.provider.PROVIDER_ID == ProviderList.AWS and
             if (self.provider.PROVIDER_ID == ProviderList.AWS and
                     not isinstance(self.provider, TestMockHelperMixin)):
                     not isinstance(self.provider, TestMockHelperMixin)):
@@ -176,16 +176,16 @@ class CloudBlockStoreServiceTestCase(ProviderTestBase):
         """
         """
         Test snapshot properties
         Test snapshot properties
         """
         """
-        name = "cb_snapprop-{0}".format(uuid.uuid4())
+        label = "cb_snapprop-{0}".format(uuid.uuid4())
         test_vol = self.provider.storage.volumes.create(
         test_vol = self.provider.storage.volumes.create(
-            name,
             1,
             1,
-            helpers.get_provider_test_data(self.provider, "placement"))
+            helpers.get_provider_test_data(self.provider, "placement"),
+            label=label)
         with helpers.cleanup_action(lambda: test_vol.delete()):
         with helpers.cleanup_action(lambda: test_vol.delete()):
             test_vol.wait_till_ready()
             test_vol.wait_till_ready()
-            snap_name = "cb_snap-{0}".format(name)
-            test_snap = test_vol.create_snapshot(name=snap_name,
-                                                 description=snap_name)
+            snap_label = "cb_snap-{0}".format(label)
+            test_snap = test_vol.create_snapshot(label=snap_label,
+                                                 description=snap_label)
 
 
             def cleanup_snap(snap):
             def cleanup_snap(snap):
                 if snap:
                 if snap:
@@ -207,18 +207,18 @@ class CloudBlockStoreServiceTestCase(ProviderTestBase):
                     % test_vol.description)
                     % test_vol.description)
                 self.assertEqual(test_vol.id, test_snap.volume_id)
                 self.assertEqual(test_vol.id, test_snap.volume_id)
                 self.assertIsNotNone(test_vol.create_time)
                 self.assertIsNotNone(test_vol.create_time)
-                test_snap.name = 'snapnewname1'
+                test_snap.label = 'snapnewname1'
                 test_snap.description = 'snapnewdescription1'
                 test_snap.description = 'snapnewdescription1'
                 test_snap.refresh()
                 test_snap.refresh()
-                self.assertEqual(test_snap.name, 'snapnewname1')
+                self.assertEqual(test_snap.label, 'snapnewname1')
                 self.assertEqual(test_snap.description, 'snapnewdescription1')
                 self.assertEqual(test_snap.description, 'snapnewdescription1')
 
 
                 # Test volume creation from a snapshot (via VolumeService)
                 # Test volume creation from a snapshot (via VolumeService)
-                sv_name = "cb_snapvol_{0}".format(test_snap.name)
+                sv_label = "cb_snapvol_{0}".format(test_snap.name)
                 snap_vol = self.provider.storage.volumes.create(
                 snap_vol = self.provider.storage.volumes.create(
-                    sv_name,
                     1,
                     1,
                     helpers.get_provider_test_data(self.provider, "placement"),
                     helpers.get_provider_test_data(self.provider, "placement"),
+                    label=sv_label,
                     snapshot=test_snap)
                     snapshot=test_snap)
                 with helpers.cleanup_action(lambda: snap_vol.delete()):
                 with helpers.cleanup_action(lambda: snap_vol.delete()):
                     snap_vol.wait_till_ready()
                     snap_vol.wait_till_ready()

+ 26 - 26
test/test_compute_service.py

@@ -21,16 +21,16 @@ class CloudComputeServiceTestCase(ProviderTestBase):
 
 
     @helpers.skipIfNoService(['compute.instances', 'networking.networks'])
     @helpers.skipIfNoService(['compute.instances', 'networking.networks'])
     def test_crud_instance(self):
     def test_crud_instance(self):
-        name = "cb_instcrud-{0}".format(helpers.get_uuid())
+        label = "cb_instcrud-{0}".format(helpers.get_uuid())
         # Declare these variables and late binding will allow
         # Declare these variables and late binding will allow
         # the cleanup method access to the most current values
         # the cleanup method access to the most current values
         net = None
         net = None
         subnet = None
         subnet = None
 
 
-        def create_inst(name):
+        def create_inst(label):
             # Also test whether sending in an empty_dict for user_data
             # Also test whether sending in an empty_dict for user_data
             # results in an automatic conversion to string.
             # results in an automatic conversion to string.
-            return helpers.get_test_instance(self.provider, name,
+            return helpers.get_test_instance(self.provider, label,
                                              subnet=subnet, user_data={})
                                              subnet=subnet, user_data={})
 
 
         def cleanup_inst(inst):
         def cleanup_inst(inst):
@@ -46,11 +46,11 @@ class CloudComputeServiceTestCase(ProviderTestBase):
                     InstanceState.DELETED,
                     InstanceState.DELETED,
                     InstanceState.UNKNOWN),
                     InstanceState.UNKNOWN),
                 "Instance %s should have been deleted but still exists." %
                 "Instance %s should have been deleted but still exists." %
-                name)
+                label)
 
 
         with helpers.cleanup_action(lambda: helpers.cleanup_test_resources(
         with helpers.cleanup_action(lambda: helpers.cleanup_test_resources(
                                                network=net)):
                                                network=net)):
-            net, subnet = helpers.create_test_network(self.provider, name)
+            net, subnet = helpers.create_test_network(self.provider, label)
 
 
             sit.check_crud(self, self.provider.compute.instances, Instance,
             sit.check_crud(self, self.provider.compute.instances, Instance,
                            "cb_instcrud", create_inst, cleanup_inst,
                            "cb_instcrud", create_inst, cleanup_inst,
@@ -67,7 +67,7 @@ class CloudComputeServiceTestCase(ProviderTestBase):
                               'security.vm_firewalls',
                               'security.vm_firewalls',
                               'security.key_pairs'])
                               'security.key_pairs'])
     def test_instance_properties(self):
     def test_instance_properties(self):
-        name = "cb_inst_props-{0}".format(helpers.get_uuid())
+        label = "cb_inst_props-{0}".format(helpers.get_uuid())
 
 
         # Declare these variables and late binding will allow
         # Declare these variables and late binding will allow
         # the cleanup method access to the most current values
         # the cleanup method access to the most current values
@@ -77,18 +77,18 @@ class CloudComputeServiceTestCase(ProviderTestBase):
         kp = None
         kp = None
         with helpers.cleanup_action(lambda: helpers.cleanup_test_resources(
         with helpers.cleanup_action(lambda: helpers.cleanup_test_resources(
                 test_instance, net, fw, kp)):
                 test_instance, net, fw, kp)):
-            net, subnet = helpers.create_test_network(self.provider, name)
-            kp = self.provider.security.key_pairs.create(name=name)
+            net, subnet = helpers.create_test_network(self.provider, label)
+            kp = self.provider.security.key_pairs.create(name=label)
             fw = self.provider.security.vm_firewalls.create(
             fw = self.provider.security.vm_firewalls.create(
-                name=name, description=name, network_id=net.id)
+                label=label, description=label, network_id=net.id)
             test_instance = helpers.get_test_instance(self.provider,
             test_instance = helpers.get_test_instance(self.provider,
-                                                      name, key_pair=kp,
+                                                      label, key_pair=kp,
                                                       vm_firewalls=[fw],
                                                       vm_firewalls=[fw],
                                                       subnet=subnet)
                                                       subnet=subnet)
             self.assertEqual(
             self.assertEqual(
-                test_instance.name, name,
-                "Instance name {0} is not equal to the expected name"
-                " {1}".format(test_instance.name, name))
+                test_instance.label, label,
+                "Instance label {0} is not equal to the expected label"
+                " {1}".format(test_instance.label, label))
             image_id = helpers.get_provider_test_data(self.provider, "image")
             image_id = helpers.get_provider_test_data(self.provider, "image")
             self.assertEqual(test_instance.image_id, image_id,
             self.assertEqual(test_instance.image_id, image_id,
                              "Image id {0} is not equal to the expected id"
                              "Image id {0} is not equal to the expected id"
@@ -217,21 +217,21 @@ class CloudComputeServiceTestCase(ProviderTestBase):
     @helpers.skipIfNoService(['compute.instances', 'compute.images',
     @helpers.skipIfNoService(['compute.instances', 'compute.images',
                               'compute.vm_types', 'storage.volumes'])
                               'compute.vm_types', 'storage.volumes'])
     def test_block_device_mapping_attachments(self):
     def test_block_device_mapping_attachments(self):
-        name = "cb_blkattch-{0}".format(helpers.get_uuid())
+        label = "cb_blkattch-{0}".format(helpers.get_uuid())
 
 
         if self.provider.PROVIDER_ID == ProviderList.OPENSTACK:
         if self.provider.PROVIDER_ID == ProviderList.OPENSTACK:
             raise self.skipTest("Not running BDM tests because OpenStack is"
             raise self.skipTest("Not running BDM tests because OpenStack is"
                                 " not stable enough yet")
                                 " not stable enough yet")
 
 
         test_vol = self.provider.storage.volumes.create(
         test_vol = self.provider.storage.volumes.create(
-           name,
            1,
            1,
            helpers.get_provider_test_data(self.provider,
            helpers.get_provider_test_data(self.provider,
-                                          "placement"))
+                                          "placement"),
+           label=label)
         with helpers.cleanup_action(lambda: test_vol.delete()):
         with helpers.cleanup_action(lambda: test_vol.delete()):
             test_vol.wait_till_ready()
             test_vol.wait_till_ready()
-            test_snap = test_vol.create_snapshot(name=name,
-                                                 description=name)
+            test_snap = test_vol.create_snapshot(label=label,
+                                                 description=label)
 
 
             def cleanup_snap(snap):
             def cleanup_snap(snap):
                 if snap:
                 if snap:
@@ -277,14 +277,14 @@ class CloudComputeServiceTestCase(ProviderTestBase):
                 for _ in range(vm_type.num_ephemeral_disks):
                 for _ in range(vm_type.num_ephemeral_disks):
                     lc.add_ephemeral_device()
                     lc.add_ephemeral_device()
 
 
-                net, subnet = helpers.create_test_network(self.provider, name)
+                net, subnet = helpers.create_test_network(self.provider, label)
 
 
                 with helpers.cleanup_action(lambda:
                 with helpers.cleanup_action(lambda:
                                             helpers.delete_test_network(net)):
                                             helpers.delete_test_network(net)):
 
 
                     inst = helpers.create_test_instance(
                     inst = helpers.create_test_instance(
                         self.provider,
                         self.provider,
-                        name,
+                        label,
                         subnet=subnet,
                         subnet=subnet,
                         launch_config=lc)
                         launch_config=lc)
 
 
@@ -302,7 +302,7 @@ class CloudComputeServiceTestCase(ProviderTestBase):
     @helpers.skipIfNoService(['compute.instances', 'networking.networks',
     @helpers.skipIfNoService(['compute.instances', 'networking.networks',
                               'security.vm_firewalls'])
                               'security.vm_firewalls'])
     def test_instance_methods(self):
     def test_instance_methods(self):
-        name = "cb_instmethods-{0}".format(helpers.get_uuid())
+        label = "cb_instmethods-{0}".format(helpers.get_uuid())
 
 
         # Declare these variables and late binding will allow
         # Declare these variables and late binding will allow
         # the cleanup method access to the most current values
         # the cleanup method access to the most current values
@@ -311,11 +311,11 @@ class CloudComputeServiceTestCase(ProviderTestBase):
         fw = None
         fw = None
         with helpers.cleanup_action(lambda: helpers.cleanup_test_resources(
         with helpers.cleanup_action(lambda: helpers.cleanup_test_resources(
                 test_inst, net, fw)):
                 test_inst, net, fw)):
-            net, subnet = helpers.create_test_network(self.provider, name)
-            test_inst = helpers.get_test_instance(self.provider, name,
+            net, subnet = helpers.create_test_network(self.provider, label)
+            test_inst = helpers.get_test_instance(self.provider, label,
                                                   subnet=subnet)
                                                   subnet=subnet)
             fw = self.provider.security.vm_firewalls.create(
             fw = self.provider.security.vm_firewalls.create(
-                name=name, description=name, network_id=net.id)
+                label=label, description=label, network_id=net.id)
 
 
             # Check adding a VM firewall to a running instance
             # Check adding a VM firewall to a running instance
             test_inst.add_vm_firewall(fw)
             test_inst.add_vm_firewall(fw)
@@ -334,7 +334,7 @@ class CloudComputeServiceTestCase(ProviderTestBase):
                 (fw, test_inst.vm_firewalls))
                 (fw, test_inst.vm_firewalls))
 
 
             # check floating ips
             # check floating ips
-            router = self.provider.networking.routers.create(name, net)
+            router = self.provider.networking.routers.create(net, label=label)
             gateway = None
             gateway = None
 
 
             def cleanup_router(router, gateway):
             def cleanup_router(router, gateway):
@@ -346,7 +346,7 @@ class CloudComputeServiceTestCase(ProviderTestBase):
             with helpers.cleanup_action(lambda: cleanup_router(router,
             with helpers.cleanup_action(lambda: cleanup_router(router,
                                                                gateway)):
                                                                gateway)):
                 router.attach_subnet(subnet)
                 router.attach_subnet(subnet)
-                gateway = net.gateways.get_or_create_inet_gateway(name)
+                gateway = net.gateways.get_or_create_inet_gateway(label=label)
                 router.attach_gateway(gateway)
                 router.attach_gateway(gateway)
                 # check whether adding an elastic ip works
                 # check whether adding an elastic ip works
                 fip = gateway.floating_ips.create()
                 fip = gateway.floating_ips.create()

+ 6 - 6
test/test_image_service.py

@@ -16,9 +16,9 @@ class CloudImageServiceTestCase(ProviderTestBase):
         """
         """
         Create a new image and check whether that image can be listed.
         Create a new image and check whether that image can be listed.
         This covers waiting till the image is ready, checking that the image
         This covers waiting till the image is ready, checking that the image
-        name is the expected one and whether list_images is functional.
+        label is the expected one and whether list_images is functional.
         """
         """
-        instance_name = "cb_crudimage-{0}".format(helpers.get_uuid())
+        instance_label = "cb_crudimage-{0}".format(helpers.get_uuid())
 
 
         # Declare these variables and late binding will allow
         # Declare these variables and late binding will allow
         # the cleanup method access to the most current values
         # the cleanup method access to the most current values
@@ -26,8 +26,8 @@ class CloudImageServiceTestCase(ProviderTestBase):
         net = None
         net = None
         subnet = None
         subnet = None
 
 
-        def create_img(name):
-            return test_instance.create_image(name)
+        def create_img(label):
+            return test_instance.create_image(label=label)
 
 
         def cleanup_img(img):
         def cleanup_img(img):
             if img:
             if img:
@@ -44,9 +44,9 @@ class CloudImageServiceTestCase(ProviderTestBase):
         with helpers.cleanup_action(lambda: helpers.cleanup_test_resources(
         with helpers.cleanup_action(lambda: helpers.cleanup_test_resources(
                 test_instance, net)):
                 test_instance, net)):
             net, subnet = helpers.create_test_network(
             net, subnet = helpers.create_test_network(
-                self.provider, instance_name)
+                self.provider, instance_label)
             test_instance = helpers.get_test_instance(
             test_instance = helpers.get_test_instance(
-                self.provider, instance_name, subnet=subnet)
+                self.provider, instance_label, subnet=subnet)
             sit.check_crud(self, self.provider.compute.images, MachineImage,
             sit.check_crud(self, self.provider.compute.images, MachineImage,
                            "cb_listimg", create_img, cleanup_img,
                            "cb_listimg", create_img, cleanup_img,
                            extra_test_func=extra_tests)
                            extra_test_func=extra_tests)

+ 17 - 17
test/test_network_service.py

@@ -16,9 +16,9 @@ class CloudNetworkServiceTestCase(ProviderTestBase):
     @helpers.skipIfNoService(['networking.networks'])
     @helpers.skipIfNoService(['networking.networks'])
     def test_crud_network(self):
     def test_crud_network(self):
 
 
-        def create_net(name):
+        def create_net(label):
             return self.provider.networking.networks.create(
             return self.provider.networking.networks.create(
-                name=name, cidr_block='10.0.0.0/16')
+                label=label, cidr_block='10.0.0.0/16')
 
 
         def cleanup_net(net):
         def cleanup_net(net):
             if net:
             if net:
@@ -29,10 +29,10 @@ class CloudNetworkServiceTestCase(ProviderTestBase):
 
 
     @helpers.skipIfNoService(['networking.networks'])
     @helpers.skipIfNoService(['networking.networks'])
     def test_network_properties(self):
     def test_network_properties(self):
-        name = 'cb_propnetwork-{0}'.format(helpers.get_uuid())
-        subnet_name = 'cb_propsubnet-{0}'.format(helpers.get_uuid())
+        label = 'cb_propnetwork-{0}'.format(helpers.get_uuid())
+        subnet_label = 'cb_propsubnet-{0}'.format(helpers.get_uuid())
         net = self.provider.networking.networks.create(
         net = self.provider.networking.networks.create(
-            name=name, cidr_block='10.0.0.0/16')
+            label=label, cidr_block='10.0.0.0/16')
         with helpers.cleanup_action(
         with helpers.cleanup_action(
             lambda: net.delete()
             lambda: net.delete()
         ):
         ):
@@ -50,7 +50,7 @@ class CloudNetworkServiceTestCase(ProviderTestBase):
 
 
             cidr = '10.0.1.0/24'
             cidr = '10.0.1.0/24'
             sn = net.create_subnet(
             sn = net.create_subnet(
-                name=subnet_name, cidr_block=cidr,
+                label=subnet_label, cidr_block=cidr,
                 zone=helpers.get_provider_test_data(self.provider,
                 zone=helpers.get_provider_test_data(self.provider,
                                                     'placement'))
                                                     'placement'))
             with helpers.cleanup_action(lambda: sn.delete()):
             with helpers.cleanup_action(lambda: sn.delete()):
@@ -84,9 +84,9 @@ class CloudNetworkServiceTestCase(ProviderTestBase):
         # correct value
         # correct value
         net = None
         net = None
 
 
-        def create_subnet(name):
+        def create_subnet(label):
             return self.provider.networking.subnets.create(
             return self.provider.networking.subnets.create(
-                network=net, cidr_block="10.0.0.0/24", name=name,
+                network=net, cidr_block="10.0.0.0/24", label=label,
                 zone=helpers.get_provider_test_data(
                 zone=helpers.get_provider_test_data(
                     self.provider, 'placement'))
                     self.provider, 'placement'))
 
 
@@ -94,9 +94,9 @@ class CloudNetworkServiceTestCase(ProviderTestBase):
             if subnet:
             if subnet:
                 self.provider.networking.subnets.delete(subnet=subnet)
                 self.provider.networking.subnets.delete(subnet=subnet)
 
 
-        net_name = 'cb_crudsubnet-{0}'.format(helpers.get_uuid())
+        net_label = 'cb_crudsubnet-{0}'.format(helpers.get_uuid())
         net = self.provider.networking.networks.create(
         net = self.provider.networking.networks.create(
-            name=net_name, cidr_block='10.0.0.0/16')
+            label=net_label, cidr_block='10.0.0.0/16')
         with helpers.cleanup_action(
         with helpers.cleanup_action(
             lambda:
             lambda:
                 self.provider.networking.networks.delete(network_id=net.id)
                 self.provider.networking.networks.delete(network_id=net.id)
@@ -108,7 +108,7 @@ class CloudNetworkServiceTestCase(ProviderTestBase):
         net, gw = helpers.get_test_gateway(
         net, gw = helpers.get_test_gateway(
             self.provider, 'cb_crudfipgw-{0}'.format(helpers.get_uuid()))
             self.provider, 'cb_crudfipgw-{0}'.format(helpers.get_uuid()))
 
 
-        def create_fip(name):
+        def create_fip(label):
             fip = gw.floating_ips.create()
             fip = gw.floating_ips.create()
             return fip
             return fip
 
 
@@ -120,7 +120,7 @@ class CloudNetworkServiceTestCase(ProviderTestBase):
                 lambda: helpers.delete_test_gateway(net, gw)):
                 lambda: helpers.delete_test_gateway(net, gw)):
             sit.check_crud(self, gw.floating_ips, FloatingIP,
             sit.check_crud(self, gw.floating_ips, FloatingIP,
                            "cb_crudfip", create_fip, cleanup_fip,
                            "cb_crudfip", create_fip, cleanup_fip,
-                           skip_name_check=True)
+                           skip_label_check=True)
 
 
     def test_floating_ip_properties(self):
     def test_floating_ip_properties(self):
         # Check floating IP address
         # Check floating IP address
@@ -157,7 +157,7 @@ class CloudNetworkServiceTestCase(ProviderTestBase):
                             router.detach_subnet(subnet)
                             router.detach_subnet(subnet)
                             router.detach_gateway(gateway)
                             router.detach_gateway(gateway)
 
 
-        name = 'cb_crudrouter-{0}'.format(helpers.get_uuid())
+        label = 'cb_crudrouter-{0}'.format(helpers.get_uuid())
         # Declare these variables and late binding will allow
         # Declare these variables and late binding will allow
         # the cleanup method access to the most current values
         # the cleanup method access to the most current values
         net = None
         net = None
@@ -166,11 +166,11 @@ class CloudNetworkServiceTestCase(ProviderTestBase):
         gteway = None
         gteway = None
         with helpers.cleanup_action(lambda: _cleanup(net, sn, router, gteway)):
         with helpers.cleanup_action(lambda: _cleanup(net, sn, router, gteway)):
             net = self.provider.networking.networks.create(
             net = self.provider.networking.networks.create(
-                name=name, cidr_block='10.0.0.0/16')
+                label=label, cidr_block='10.0.0.0/16')
             router = self.provider.networking.routers.create(network=net,
             router = self.provider.networking.routers.create(network=net,
-                                                             name=name)
+                                                             label=label)
             cidr = '10.0.1.0/24'
             cidr = '10.0.1.0/24'
-            sn = net.create_subnet(name=name, cidr_block=cidr,
+            sn = net.create_subnet(label=label, cidr_block=cidr,
                                    zone=helpers.get_provider_test_data(
                                    zone=helpers.get_provider_test_data(
                                        self.provider, 'placement'))
                                        self.provider, 'placement'))
 
 
@@ -188,7 +188,7 @@ class CloudNetworkServiceTestCase(ProviderTestBase):
 #                     router.id, router.network_id))
 #                     router.id, router.network_id))
 
 
             router.attach_subnet(sn)
             router.attach_subnet(sn)
-            gteway = net.gateways.get_or_create_inet_gateway(name)
+            gteway = net.gateways.get_or_create_inet_gateway(label=label)
             router.attach_gateway(gteway)
             router.attach_gateway(gteway)
             # TODO: add a check for routes after that's been implemented
             # TODO: add a check for routes after that's been implemented
 
 

+ 3 - 3
test/test_object_life_cycle.py

@@ -14,11 +14,11 @@ class CloudObjectLifeCycleTestCase(ProviderTestBase):
         """
         """
         Test object life cycle methods by using a volume.
         Test object life cycle methods by using a volume.
         """
         """
-        name = "cb_objlifecycle-{0}".format(helpers.get_uuid())
+        label = "cb_objlifecycle-{0}".format(helpers.get_uuid())
         test_vol = self.provider.storage.volumes.create(
         test_vol = self.provider.storage.volumes.create(
-            name,
             1,
             1,
-            helpers.get_provider_test_data(self.provider, "placement"))
+            helpers.get_provider_test_data(self.provider, "placement"),
+            label=label)
 
 
         # Waiting for an invalid timeout should raise an exception
         # Waiting for an invalid timeout should raise an exception
         with self.assertRaises(AssertionError):
         with self.assertRaises(AssertionError):

+ 7 - 7
test/test_object_store_service.py

@@ -8,7 +8,7 @@ from unittest import skip
 
 
 import requests
 import requests
 
 
-from cloudbridge.cloud.interfaces.exceptions import InvalidNameException
+from cloudbridge.cloud.interfaces.exceptions import InvalidLabelException
 from cloudbridge.cloud.interfaces.provider import TestMockHelperMixin
 from cloudbridge.cloud.interfaces.provider import TestMockHelperMixin
 from cloudbridge.cloud.interfaces.resources import Bucket
 from cloudbridge.cloud.interfaces.resources import Bucket
 from cloudbridge.cloud.interfaces.resources import BucketObject
 from cloudbridge.cloud.interfaces.resources import BucketObject
@@ -36,25 +36,25 @@ class CloudObjectStoreServiceTestCase(ProviderTestBase):
             if bucket:
             if bucket:
                 bucket.delete()
                 bucket.delete()
 
 
-        with self.assertRaises(InvalidNameException):
+        with self.assertRaises(InvalidLabelException):
             # underscores are not allowed in bucket names
             # underscores are not allowed in bucket names
             create_bucket("cb_bucket")
             create_bucket("cb_bucket")
 
 
-        with self.assertRaises(InvalidNameException):
+        with self.assertRaises(InvalidLabelException):
             # names of length less than 3 should raise an exception
             # names of length less than 3 should raise an exception
             create_bucket("cb")
             create_bucket("cb")
 
 
-        with self.assertRaises(InvalidNameException):
+        with self.assertRaises(InvalidLabelException):
             # names of length greater than 63 should raise an exception
             # names of length greater than 63 should raise an exception
             create_bucket("a" * 64)
             create_bucket("a" * 64)
 
 
-        with self.assertRaises(InvalidNameException):
+        with self.assertRaises(InvalidLabelException):
             # bucket name cannot be an IP address
             # bucket name cannot be an IP address
             create_bucket("197.10.100.42")
             create_bucket("197.10.100.42")
 
 
         sit.check_crud(self, self.provider.storage.buckets, Bucket,
         sit.check_crud(self, self.provider.storage.buckets, Bucket,
                        "cb-crudbucket", create_bucket, cleanup_bucket,
                        "cb-crudbucket", create_bucket, cleanup_bucket,
-                       skip_name_check=True)
+                       skip_label_check=True)
 
 
     @helpers.skipIfNoService(['storage.buckets'])
     @helpers.skipIfNoService(['storage.buckets'])
     def test_crud_bucket_object(self):
     def test_crud_bucket_object(self):
@@ -79,7 +79,7 @@ class CloudObjectStoreServiceTestCase(ProviderTestBase):
 
 
             sit.check_crud(self, test_bucket.objects, BucketObject,
             sit.check_crud(self, test_bucket.objects, BucketObject,
                            "cb_bucketobj", create_bucket_obj,
                            "cb_bucketobj", create_bucket_obj,
-                           cleanup_bucket_obj, skip_name_check=True)
+                           cleanup_bucket_obj, skip_label_check=True)
 
 
     @helpers.skipIfNoService(['storage.buckets'])
     @helpers.skipIfNoService(['storage.buckets'])
     def test_crud_bucket_object_properties(self):
     def test_crud_bucket_object_properties(self):

+ 27 - 27
test/test_security_service.py

@@ -60,15 +60,15 @@ class CloudSecurityServiceTestCase(ProviderTestBase):
 
 
     @helpers.skipIfNoService(['security.vm_firewalls'])
     @helpers.skipIfNoService(['security.vm_firewalls'])
     def test_crud_vm_firewall(self):
     def test_crud_vm_firewall(self):
-        name = 'cb_crudfw-{0}'.format(helpers.get_uuid())
+        label = 'cb_crudfw-{0}'.format(helpers.get_uuid())
 
 
         # Declare these variables and late binding will allow
         # Declare these variables and late binding will allow
         # the cleanup method access to the most current values
         # the cleanup method access to the most current values
         net = None
         net = None
 
 
-        def create_fw(name):
+        def create_fw(label):
             return self.provider.security.vm_firewalls.create(
             return self.provider.security.vm_firewalls.create(
-                name=name, description=name, network_id=net.id)
+                label=label, description=label, network_id=net.id)
 
 
         def cleanup_fw(fw):
         def cleanup_fw(fw):
             if fw:
             if fw:
@@ -76,14 +76,14 @@ class CloudSecurityServiceTestCase(ProviderTestBase):
 
 
         with helpers.cleanup_action(lambda: helpers.cleanup_test_resources(
         with helpers.cleanup_action(lambda: helpers.cleanup_test_resources(
                 network=net)):
                 network=net)):
-            net, _ = helpers.create_test_network(self.provider, name)
+            net, _ = helpers.create_test_network(self.provider, label)
 
 
             sit.check_crud(self, self.provider.security.vm_firewalls,
             sit.check_crud(self, self.provider.security.vm_firewalls,
                            VMFirewall, "cb_crudfw", create_fw, cleanup_fw)
                            VMFirewall, "cb_crudfw", create_fw, cleanup_fw)
 
 
     @helpers.skipIfNoService(['security.vm_firewalls'])
     @helpers.skipIfNoService(['security.vm_firewalls'])
     def test_vm_firewall_properties(self):
     def test_vm_firewall_properties(self):
-        name = 'cb_propfw-{0}'.format(helpers.get_uuid())
+        label = 'cb_propfw-{0}'.format(helpers.get_uuid())
 
 
         # Declare these variables and late binding will allow
         # Declare these variables and late binding will allow
         # the cleanup method access to the most current values
         # the cleanup method access to the most current values
@@ -91,29 +91,29 @@ class CloudSecurityServiceTestCase(ProviderTestBase):
         fw = None
         fw = None
         with helpers.cleanup_action(lambda: helpers.cleanup_test_resources(
         with helpers.cleanup_action(lambda: helpers.cleanup_test_resources(
                 network=net, vm_firewall=fw)):
                 network=net, vm_firewall=fw)):
-            net, _ = helpers.create_test_network(self.provider, name)
+            net, _ = helpers.create_test_network(self.provider, label)
             fw = self.provider.security.vm_firewalls.create(
             fw = self.provider.security.vm_firewalls.create(
-                name=name, description=name, network_id=net.id)
+                label=label, description=label, network_id=net.id)
 
 
-            self.assertEqual(name, fw.description)
+            self.assertEqual(label, fw.description)
 
 
     @helpers.skipIfNoService(['security.vm_firewalls'])
     @helpers.skipIfNoService(['security.vm_firewalls'])
     def test_crud_vm_firewall_rules(self):
     def test_crud_vm_firewall_rules(self):
-        name = 'cb_crudfw_rules-{0}'.format(helpers.get_uuid())
+        label = 'cb_crudfw_rules-{0}'.format(helpers.get_uuid())
 
 
         # Declare these variables and late binding will allow
         # Declare these variables and late binding will allow
         # the cleanup method access to the most current values
         # the cleanup method access to the most current values
         net = None
         net = None
         with helpers.cleanup_action(lambda: helpers.cleanup_test_resources(
         with helpers.cleanup_action(lambda: helpers.cleanup_test_resources(
                 network=net)):
                 network=net)):
-            net, _ = helpers.create_test_network(self.provider, name)
+            net, _ = helpers.create_test_network(self.provider, label)
 
 
             fw = None
             fw = None
             with helpers.cleanup_action(lambda: fw.delete()):
             with helpers.cleanup_action(lambda: fw.delete()):
                 fw = self.provider.security.vm_firewalls.create(
                 fw = self.provider.security.vm_firewalls.create(
-                    name=name, description=name, network_id=net.id)
+                    label=label, description=label, network_id=net.id)
 
 
-                def create_fw_rule(name):
+                def create_fw_rule(label):
                     return fw.rules.create(
                     return fw.rules.create(
                         direction=TrafficDirection.INBOUND, protocol='tcp',
                         direction=TrafficDirection.INBOUND, protocol='tcp',
                         from_port=1111, to_port=1111, cidr='0.0.0.0/0')
                         from_port=1111, to_port=1111, cidr='0.0.0.0/0')
@@ -124,11 +124,11 @@ class CloudSecurityServiceTestCase(ProviderTestBase):
 
 
                 sit.check_crud(self, fw.rules, VMFirewallRule, "cb_crudfwrule",
                 sit.check_crud(self, fw.rules, VMFirewallRule, "cb_crudfwrule",
                                create_fw_rule, cleanup_fw_rule,
                                create_fw_rule, cleanup_fw_rule,
-                               skip_name_check=True)
+                               skip_label_check=True)
 
 
     @helpers.skipIfNoService(['security.vm_firewalls'])
     @helpers.skipIfNoService(['security.vm_firewalls'])
     def test_vm_firewall_rule_properties(self):
     def test_vm_firewall_rule_properties(self):
-        name = 'cb_propfwrule-{0}'.format(helpers.get_uuid())
+        label = 'cb_propfwrule-{0}'.format(helpers.get_uuid())
 
 
         # Declare these variables and late binding will allow
         # Declare these variables and late binding will allow
         # the cleanup method access to the most current values
         # the cleanup method access to the most current values
@@ -136,9 +136,9 @@ class CloudSecurityServiceTestCase(ProviderTestBase):
         fw = None
         fw = None
         with helpers.cleanup_action(lambda: helpers.cleanup_test_resources(
         with helpers.cleanup_action(lambda: helpers.cleanup_test_resources(
                 network=net, vm_firewall=fw)):
                 network=net, vm_firewall=fw)):
-            net, _ = helpers.create_test_network(self.provider, name)
+            net, _ = helpers.create_test_network(self.provider, label)
             fw = self.provider.security.vm_firewalls.create(
             fw = self.provider.security.vm_firewalls.create(
-                name=name, description=name, network_id=net.id)
+                label=label, description=label, network_id=net.id)
 
 
             rule = fw.rules.create(
             rule = fw.rules.create(
                 direction=TrafficDirection.INBOUND, protocol='tcp',
                 direction=TrafficDirection.INBOUND, protocol='tcp',
@@ -151,7 +151,7 @@ class CloudSecurityServiceTestCase(ProviderTestBase):
 
 
     @helpers.skipIfNoService(['security.vm_firewalls'])
     @helpers.skipIfNoService(['security.vm_firewalls'])
     def test_vm_firewall_rule_add_twice(self):
     def test_vm_firewall_rule_add_twice(self):
-        name = 'cb_fwruletwice-{0}'.format(helpers.get_uuid())
+        label = 'cb_fwruletwice-{0}'.format(helpers.get_uuid())
 
 
         # Declare these variables and late binding will allow
         # Declare these variables and late binding will allow
         # the cleanup method access to the most current values
         # the cleanup method access to the most current values
@@ -160,9 +160,9 @@ class CloudSecurityServiceTestCase(ProviderTestBase):
         with helpers.cleanup_action(lambda: helpers.cleanup_test_resources(
         with helpers.cleanup_action(lambda: helpers.cleanup_test_resources(
                 network=net, vm_firewall=fw)):
                 network=net, vm_firewall=fw)):
 
 
-            net, _ = helpers.create_test_network(self.provider, name)
+            net, _ = helpers.create_test_network(self.provider, label)
             fw = self.provider.security.vm_firewalls.create(
             fw = self.provider.security.vm_firewalls.create(
-                name=name, description=name, network_id=net.id)
+                label=label, description=label, network_id=net.id)
 
 
             rule = fw.rules.create(
             rule = fw.rules.create(
                 direction=TrafficDirection.INBOUND, protocol='tcp',
                 direction=TrafficDirection.INBOUND, protocol='tcp',
@@ -175,7 +175,7 @@ class CloudSecurityServiceTestCase(ProviderTestBase):
 
 
     @helpers.skipIfNoService(['security.vm_firewalls'])
     @helpers.skipIfNoService(['security.vm_firewalls'])
     def test_vm_firewall_group_rule(self):
     def test_vm_firewall_group_rule(self):
-        name = 'cb_fwrule-{0}'.format(helpers.get_uuid())
+        label = 'cb_fwrule-{0}'.format(helpers.get_uuid())
 
 
         # Declare these variables and late binding will allow
         # Declare these variables and late binding will allow
         # the cleanup method access to the most current values
         # the cleanup method access to the most current values
@@ -183,9 +183,9 @@ class CloudSecurityServiceTestCase(ProviderTestBase):
         fw = None
         fw = None
         with helpers.cleanup_action(lambda: helpers.cleanup_test_resources(
         with helpers.cleanup_action(lambda: helpers.cleanup_test_resources(
                 network=net, vm_firewall=fw)):
                 network=net, vm_firewall=fw)):
-            net, _ = helpers.create_test_network(self.provider, name)
+            net, _ = helpers.create_test_network(self.provider, label)
             fw = self.provider.security.vm_firewalls.create(
             fw = self.provider.security.vm_firewalls.create(
-                name=name, description=name, network_id=net.id)
+                label=label, description=label, network_id=net.id)
             rules = list(fw.rules)
             rules = list(fw.rules)
             self.assertTrue(
             self.assertTrue(
                 # TODO: This should be made consistent across all providers.
                 # TODO: This should be made consistent across all providers.
@@ -200,9 +200,9 @@ class CloudSecurityServiceTestCase(ProviderTestBase):
                 direction=TrafficDirection.INBOUND, src_dest_fw=fw,
                 direction=TrafficDirection.INBOUND, src_dest_fw=fw,
                 protocol='tcp', from_port=1, to_port=65535)
                 protocol='tcp', from_port=1, to_port=65535)
             self.assertTrue(
             self.assertTrue(
-                rule.src_dest_fw.name == name,
-                "Expected VM firewall rule name {0}. Got {1}."
-                .format(name, rule.src_dest_fw.name))
+                rule.src_dest_fw.label == label,
+                "Expected VM firewall rule label {0}. Got {1}."
+                .format(label, rule.src_dest_fw.label))
             for r in fw.rules:
             for r in fw.rules:
                 r.delete()
                 r.delete()
             fw = self.provider.security.vm_firewalls.get(fw.id)  # update
             fw = self.provider.security.vm_firewalls.get(fw.id)  # update
@@ -211,8 +211,8 @@ class CloudSecurityServiceTestCase(ProviderTestBase):
                 "Deleting VMFirewallRule should delete it: {0}".format(
                 "Deleting VMFirewallRule should delete it: {0}".format(
                     fw.rules))
                     fw.rules))
         fwl = self.provider.security.vm_firewalls.list()
         fwl = self.provider.security.vm_firewalls.list()
-        found_fw = [f for f in fwl if f.name == name]
+        found_fw = [f for f in fwl if f.label == label]
         self.assertTrue(
         self.assertTrue(
             len(found_fw) == 0,
             len(found_fw) == 0,
             "VM firewall {0} should have been deleted but still exists."
             "VM firewall {0} should have been deleted but still exists."
-            .format(name))
+            .format(label))