Merge "Fix 'if' in the clear_isolated_creds"
diff --git a/HACKING.rst b/HACKING.rst
index fed4130..a546f8c 100644
--- a/HACKING.rst
+++ b/HACKING.rst
@@ -153,10 +153,25 @@
kwarg2=dict_of_numbers)
+openstack-common
+----------------
+
+A number of modules from openstack-common are imported into the project.
+
+These modules are "incubating" in openstack-common and are kept in sync
+with the help of openstack-common's update.py script. See:
+
+ http://wiki.openstack.org/CommonLibrary#Incubation
+
+The copy of the code should never be directly modified here. Please
+always update openstack-common first and then run the script to copy
+the changes across.
+
+
OpenStack Trademark
-------------------
-OpenStack is a registered trademark of OpenStack, LLC, and uses the
+OpenStack is a registered trademark of the OpenStack Foundation, and uses the
following capitalization:
OpenStack
diff --git a/tempest/clients.py b/tempest/clients.py
index 150cf67..aa9b558 100644
--- a/tempest/clients.py
+++ b/tempest/clients.py
@@ -19,8 +19,7 @@
from tempest import config
from tempest import exceptions
-from tempest.services.boto.clients import APIClientEC2
-from tempest.services.boto.clients import ObjectClientS3
+from tempest.services import botoclients
from tempest.services.compute.json.extensions_client import \
ExtensionsClientJSON
from tempest.services.compute.json.flavors_client import FlavorsClientJSON
@@ -205,8 +204,8 @@
self.image_client = ImageClientJSON(*client_args)
self.container_client = ContainerClient(*client_args)
self.object_client = ObjectClient(*client_args)
- self.ec2api_client = APIClientEC2(*client_args)
- self.s3_client = ObjectClientS3(*client_args)
+ self.ec2api_client = botoclients.APIClientEC2(*client_args)
+ self.s3_client = botoclients.ObjectClientS3(*client_args)
self.custom_object_client = ObjectClientCustomizedHeader(*client_args)
self.custom_account_client = \
AccountClientCustomizedHeader(*client_args)
diff --git a/tempest/services/boto/__init__.py b/tempest/services/boto/__init__.py
deleted file mode 100644
index f744d9d..0000000
--- a/tempest/services/boto/__init__.py
+++ /dev/null
@@ -1,99 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2012 OpenStack, LLC
-# All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-from ConfigParser import DuplicateSectionError
-from contextlib import closing
-import re
-from types import MethodType
-
-import boto
-
-from tempest.exceptions import InvalidConfiguration
-from tempest.exceptions import NotFound
-
-
-class BotoClientBase(object):
-
- ALLOWED_METHODS = set()
-
- def __init__(self, config,
- username=None, password=None,
- auth_url=None, tenant_name=None,
- *args, **kwargs):
-
- self.connection_timeout = str(config.boto.http_socket_timeout)
- self.num_retries = str(config.boto.num_retries)
- self.build_timeout = config.boto.build_timeout
- self.ks_cred = {"username": username,
- "password": password,
- "auth_url": auth_url,
- "tenant_name": tenant_name}
-
- def _keystone_aws_get(self):
- import keystoneclient.v2_0.client
-
- keystone = keystoneclient.v2_0.client.Client(**self.ks_cred)
- ec2_cred_list = keystone.ec2.list(keystone.auth_user_id)
- ec2_cred = None
- for cred in ec2_cred_list:
- if cred.tenant_id == keystone.auth_tenant_id:
- ec2_cred = cred
- break
- else:
- ec2_cred = keystone.ec2.create(keystone.auth_user_id,
- keystone.auth_tenant_id)
- if not all((ec2_cred, ec2_cred.access, ec2_cred.secret)):
- raise NotFound("Unable to get access and secret keys")
- return ec2_cred
-
- def _config_boto_timeout(self, timeout, retries):
- try:
- boto.config.add_section("Boto")
- except DuplicateSectionError:
- pass
- boto.config.set("Boto", "http_socket_timeout", timeout)
- boto.config.set("Boto", "num_retries", retries)
-
- def __getattr__(self, name):
- """Automatically creates methods for the allowed methods set."""
- if name in self.ALLOWED_METHODS:
- def func(self, *args, **kwargs):
- with closing(self.get_connection()) as conn:
- return getattr(conn, name)(*args, **kwargs)
-
- func.__name__ = name
- setattr(self, name, MethodType(func, self, self.__class__))
- setattr(self.__class__, name,
- MethodType(func, None, self.__class__))
- return getattr(self, name)
- else:
- raise AttributeError(name)
-
- def get_connection(self):
- self._config_boto_timeout(self.connection_timeout, self.num_retries)
- if not all((self.connection_data["aws_access_key_id"],
- self.connection_data["aws_secret_access_key"])):
- if all(self.ks_cred.itervalues()):
- ec2_cred = self._keystone_aws_get()
- self.connection_data["aws_access_key_id"] = \
- ec2_cred.access
- self.connection_data["aws_secret_access_key"] = \
- ec2_cred.secret
- else:
- raise InvalidConfiguration(
- "Unable to get access and secret keys")
- return self.connect_method(**self.connection_data)
diff --git a/tempest/services/boto/clients.py b/tempest/services/botoclients.py
similarity index 63%
rename from tempest/services/boto/clients.py
rename to tempest/services/botoclients.py
index 228e826..143257a 100644
--- a/tempest/services/boto/clients.py
+++ b/tempest/services/botoclients.py
@@ -15,13 +15,90 @@
# License for the specific language governing permissions and limitations
# under the License.
+import ConfigParser
+import contextlib
+import re
+import types
import urlparse
-import boto
-from boto.ec2.regioninfo import RegionInfo
-from boto.s3.connection import OrdinaryCallingFormat
+from tempest import exceptions
-from tempest.services.boto import BotoClientBase
+import boto
+import boto.ec2
+import boto.s3.connection
+
+
+class BotoClientBase(object):
+
+ ALLOWED_METHODS = set()
+
+ def __init__(self, config,
+ username=None, password=None,
+ auth_url=None, tenant_name=None,
+ *args, **kwargs):
+
+ self.connection_timeout = str(config.boto.http_socket_timeout)
+ self.num_retries = str(config.boto.num_retries)
+ self.build_timeout = config.boto.build_timeout
+ self.ks_cred = {"username": username,
+ "password": password,
+ "auth_url": auth_url,
+ "tenant_name": tenant_name}
+
+ def _keystone_aws_get(self):
+ import keystoneclient.v2_0.client
+
+ keystone = keystoneclient.v2_0.client.Client(**self.ks_cred)
+ ec2_cred_list = keystone.ec2.list(keystone.auth_user_id)
+ ec2_cred = None
+ for cred in ec2_cred_list:
+ if cred.tenant_id == keystone.auth_tenant_id:
+ ec2_cred = cred
+ break
+ else:
+ ec2_cred = keystone.ec2.create(keystone.auth_user_id,
+ keystone.auth_tenant_id)
+ if not all((ec2_cred, ec2_cred.access, ec2_cred.secret)):
+ raise exceptions.NotFound("Unable to get access and secret keys")
+ return ec2_cred
+
+ def _config_boto_timeout(self, timeout, retries):
+ try:
+ boto.config.add_section("Boto")
+ except ConfigParser.DuplicateSectionError:
+ pass
+ boto.config.set("Boto", "http_socket_timeout", timeout)
+ boto.config.set("Boto", "num_retries", retries)
+
+ def __getattr__(self, name):
+ """Automatically creates methods for the allowed methods set."""
+ if name in self.ALLOWED_METHODS:
+ def func(self, *args, **kwargs):
+ with contextlib.closing(self.get_connection()) as conn:
+ return getattr(conn, name)(*args, **kwargs)
+
+ func.__name__ = name
+ setattr(self, name, types.MethodType(func, self, self.__class__))
+ setattr(self.__class__, name,
+ types.MethodType(func, None, self.__class__))
+ return getattr(self, name)
+ else:
+ raise AttributeError(name)
+
+ def get_connection(self):
+ self._config_boto_timeout(self.connection_timeout, self.num_retries)
+ if not all((self.connection_data["aws_access_key_id"],
+ self.connection_data["aws_secret_access_key"])):
+ if all(self.ks_cred.itervalues()):
+ ec2_cred = self._keystone_aws_get()
+ self.connection_data["aws_access_key_id"] = \
+ ec2_cred.access
+ self.connection_data["aws_secret_access_key"] = \
+ ec2_cred.secret
+ else:
+ raise exceptions.InvalidConfiguration(
+ "Unable to get access and secret keys")
+ return self.connect_method(**self.connection_data)
class APIClientEC2(BotoClientBase):
@@ -35,8 +112,8 @@
aws_secret = config.boto.aws_secret
purl = urlparse.urlparse(config.boto.ec2_url)
- region = RegionInfo(name=config.identity.region,
- endpoint=purl.hostname)
+ region = boto.ec2.regioninfo.RegionInfo(name=config.identity.region,
+ endpoint=purl.hostname)
port = purl.port
if port is None:
if purl.scheme is not "https":
@@ -134,7 +211,8 @@
"is_secure": purl.scheme == "https",
"host": purl.hostname,
"port": port,
- "calling_format": OrdinaryCallingFormat()}
+ "calling_format": boto.s3.connection.
+ OrdinaryCallingFormat()}
ALLOWED_METHODS = set(('create_bucket', 'delete_bucket', 'generate_url',
'get_all_buckets', 'get_bucket', 'delete_key',
diff --git a/tempest/tests/compute/servers/test_servers_negative.py b/tempest/tests/compute/servers/test_servers_negative.py
index 09d2a9c..9b528f6 100644
--- a/tempest/tests/compute/servers/test_servers_negative.py
+++ b/tempest/tests/compute/servers/test_servers_negative.py
@@ -273,3 +273,17 @@
self.assertRaises(exceptions.NotFound, self.client.delete_server,
sys.maxint + 1)
+
+ @attr(type='negative')
+ def test_create_with_nonexistent_security_group(self):
+ # Create a server with a nonexistent security group
+ try:
+ security_groups = [{'name': 'does_not_exist'}]
+ self.create_server_with_extras('fail',
+ self.image_ref,
+ self.flavor_ref,
+ security_groups=security_groups)
+ except exceptions.BadRequest:
+ pass
+ else:
+ self.fail('Server was created with nonexistent security group')