Add "region" config for each service
Added config items are:
compute.region
image.region
network.region
volume.region
object_storage.region
orchestration.region
RestClient decides target endpoints according to these values. If
these values are not set, the value of identity.region is used
instead.
Fixes bug 1210039
Change-Id: If2a01fae2893ee5740a94e97389164eb000538d7
diff --git a/etc/tempest.conf.sample b/etc/tempest.conf.sample
index cd57354..2ecace0 100644
--- a/etc/tempest.conf.sample
+++ b/etc/tempest.conf.sample
@@ -28,7 +28,8 @@
uri = http://127.0.0.1:5000/v2.0/
# URL for where to find the OpenStack V3 Identity API endpoint (Keystone)
uri_v3 = http://127.0.0.1:5000/v3/
-# The identity region
+# The identity region. Also used as the other services' region name unless
+# they are set explicitly.
region = RegionOne
# This should be the username of a user WITHOUT administrative privileges
@@ -137,6 +138,11 @@
# this value as "compute"
catalog_type = compute
+# The name of a region for compute. If empty or commented-out, the value of
+# identity.region is used instead. If no such region is found in the service
+# catalog, the first found one is used.
+#region = RegionOne
+
# Does the Compute API support creation of images?
create_image_enabled = true
@@ -186,6 +192,11 @@
# this value as "image"
catalog_type = image
+# The name of a region for image. If empty or commented-out, the value of
+# identity.region is used instead. If no such region is found in the service
+# catalog, the first found one is used.
+#region = RegionOne
+
# The version of the OpenStack Images API to use
api_version = 1
@@ -201,6 +212,11 @@
# Catalog type of the Neutron Service
catalog_type = network
+# The name of a region for network. If empty or commented-out, the value of
+# identity.region is used instead. If no such region is found in the service
+# catalog, the first found one is used.
+#region = RegionOne
+
# A large private cidr block from which to allocate smaller blocks for
# tenant networks.
tenant_network_cidr = 10.100.0.0/16
@@ -230,6 +246,10 @@
# Unless you have a custom Keystone service catalog implementation, you
# probably want to leave this value as "volume"
catalog_type = volume
+# The name of a region for volume. If empty or commented-out, the value of
+# identity.region is used instead. If no such region is found in the service
+# catalog, the first found one is used.
+#region = RegionOne
# The disk format to use when copying a volume to image
disk_format = raw
# Number of seconds to wait while looping to check the status of a
@@ -260,6 +280,11 @@
# this value as "object-store"
catalog_type = object-store
+# The name of a region for object storage. If empty or commented-out, the
+# value of identity.region is used instead. If no such region is found in
+# the service catalog, the first found one is used.
+#region = RegionOne
+
# Number of seconds to time on waiting for a container to container
# synchronization complete
container_sync_timeout = 120
@@ -318,6 +343,16 @@
build_interval = 1
[orchestration]
+# The type of endpoint for an Orchestration API service. Unless you have a
+# custom Keystone service catalog implementation, you probably want to leave
+# this value as "orchestration"
+catalog_type = orchestration
+
+# The name of a region for orchestration. If empty or commented-out, the value
+# of identity.region is used instead. If no such region is found in the service
+# catalog, the first found one is used.
+#region = RegionOne
+
# Status change wait interval
build_interval = 1
diff --git a/tempest/cli/simple_read_only/test_cinder.py b/tempest/cli/simple_read_only/test_cinder.py
index 21acae8..3ff997a 100644
--- a/tempest/cli/simple_read_only/test_cinder.py
+++ b/tempest/cli/simple_read_only/test_cinder.py
@@ -114,4 +114,7 @@
self.cinder('list', flags='--retries 3')
def test_cinder_region_list(self):
- self.cinder('list', flags='--os-region-name ' + self.identity.region)
+ region = self.config.volume.region
+ if not region:
+ region = self.config.identity.region
+ self.cinder('list', flags='--os-region-name ' + region)
diff --git a/tempest/common/rest_client.py b/tempest/common/rest_client.py
index 8dfff6e..81393a9 100644
--- a/tempest/common/rest_client.py
+++ b/tempest/common/rest_client.py
@@ -49,7 +49,17 @@
self.service = None
self.token = None
self.base_url = None
- self.region = {'compute': self.config.identity.region}
+ self.region = {}
+ for cfgname in dir(self.config):
+ # Find all config.FOO.catalog_type and assume FOO is a service.
+ cfg = getattr(self.config, cfgname)
+ catalog_type = getattr(cfg, 'catalog_type', None)
+ if not catalog_type:
+ continue
+ service_region = getattr(cfg, 'region', None)
+ if not service_region:
+ service_region = self.config.identity.region
+ self.region[catalog_type] = service_region
self.endpoint_url = 'publicURL'
self.headers = {'Content-Type': 'application/%s' % self.TYPE,
'Accept': 'application/%s' % self.TYPE}
diff --git a/tempest/config.py b/tempest/config.py
index b386968..1b52f5e 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -44,7 +44,10 @@
help='Full URI of the OpenStack Identity API (Keystone), v3'),
cfg.StrOpt('region',
default='RegionOne',
- help="The identity region name to use."),
+ help="The identity region name to use. Also used as the other "
+ "services' region name unless they are set explicitly. "
+ "If no such region is found in the service catalog, the "
+ "first found one is used."),
cfg.StrOpt('username',
default='demo',
help="Username to use for Nova API requests."),
@@ -200,6 +203,12 @@
cfg.StrOpt('catalog_type',
default='compute',
help="Catalog type of the Compute service."),
+ cfg.StrOpt('region',
+ default='',
+ help="The compute region name to use. If empty, the value "
+ "of identity.region is used instead. If no such region "
+ "is found in the service catalog, the first found one is "
+ "used."),
cfg.StrOpt('path_to_private_key',
default=None,
help="Path to a private key file for SSH access to remote "
@@ -255,6 +264,12 @@
cfg.StrOpt('catalog_type',
default='image',
help='Catalog type of the Image service.'),
+ cfg.StrOpt('region',
+ default='',
+ help="The image region name to use. If empty, the value "
+ "of identity.region is used instead. If no such region "
+ "is found in the service catalog, the first found one is "
+ "used."),
cfg.StrOpt('http_image',
default='http://download.cirros-cloud.net/0.3.1/'
'cirros-0.3.1-x86_64-uec.tar.gz',
@@ -275,6 +290,12 @@
cfg.StrOpt('catalog_type',
default='network',
help='Catalog type of the Neutron service.'),
+ cfg.StrOpt('region',
+ default='',
+ help="The network region name to use. If empty, the value "
+ "of identity.region is used instead. If no such region "
+ "is found in the service catalog, the first found one is "
+ "used."),
cfg.StrOpt('tenant_network_cidr',
default="10.100.0.0/16",
help="The cidr block to allocate tenant networks from"),
@@ -315,6 +336,12 @@
cfg.StrOpt('catalog_type',
default='Volume',
help="Catalog type of the Volume Service"),
+ cfg.StrOpt('region',
+ default='',
+ help="The volume region name to use. If empty, the value "
+ "of identity.region is used instead. If no such region "
+ "is found in the service catalog, the first found one is "
+ "used."),
cfg.BoolOpt('multi_backend_enabled',
default=False,
help="Runs Cinder multi-backend test (requires 2 backends)"),
@@ -349,6 +376,12 @@
cfg.StrOpt('catalog_type',
default='object-store',
help="Catalog type of the Object-Storage service."),
+ cfg.StrOpt('region',
+ default='',
+ help="The object-storage region name to use. If empty, the "
+ "value of identity.region is used instead. If no such "
+ "region is found in the service catalog, the first found "
+ "one is used."),
cfg.StrOpt('container_sync_timeout',
default=120,
help="Number of seconds to time on waiting for a container"
@@ -380,6 +413,12 @@
cfg.StrOpt('catalog_type',
default='orchestration',
help="Catalog type of the Orchestration service."),
+ cfg.StrOpt('region',
+ default='',
+ help="The orchestration region name to use. If empty, the "
+ "value of identity.region is used instead. If no such "
+ "region is found in the service catalog, the first found "
+ "one is used."),
cfg.BoolOpt('allow_tenant_isolation',
default=False,
help="Allows test cases to create/destroy tenants and "
diff --git a/tempest/services/botoclients.py b/tempest/services/botoclients.py
index 66fb7af..a689c89 100644
--- a/tempest/services/botoclients.py
+++ b/tempest/services/botoclients.py
@@ -111,7 +111,10 @@
aws_secret = config.boto.aws_secret
purl = urlparse.urlparse(config.boto.ec2_url)
- region = boto.ec2.regioninfo.RegionInfo(name=config.identity.region,
+ region_name = config.compute.region
+ if not region_name:
+ region_name = config.identity.region
+ region = boto.ec2.regioninfo.RegionInfo(name=region_name,
endpoint=purl.hostname)
port = purl.port
if port is None: