blob: 50d0779ae32d16e540a1c04268df09fe2b8509ae [file] [log] [blame]
ZhiQiang Fan39f97222013-09-20 04:49:44 +08001# Copyright 2012 OpenStack Foundation
Attila Fazekasa23f5002012-10-23 19:32:45 +02002# All Rights Reserved.
3#
4# Licensed under the Apache License, Version 2.0 (the "License"); you may
5# not use this file except in compliance with the License. You may obtain
6# a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13# License for the specific language governing permissions and limitations
14# under the License.
15
Attila Fazekas1aed6202013-02-11 14:47:45 +010016import ConfigParser
17import contextlib
Masayuki Igawabfa07602015-01-20 18:47:17 +090018from tempest_lib import exceptions as lib_exc
Attila Fazekas1aed6202013-02-11 14:47:45 +010019import types
Attila Fazekasa23f5002012-10-23 19:32:45 +020020import urlparse
21
Matthew Treinish684d8992014-01-30 16:27:40 +000022from tempest import config
Attila Fazekas1aed6202013-02-11 14:47:45 +010023from tempest import exceptions
Matthew Treinisha83a16e2012-12-07 13:44:02 -050024
Attila Fazekas1aed6202013-02-11 14:47:45 +010025import boto
26import boto.ec2
27import boto.s3.connection
28
Matthew Treinish684d8992014-01-30 16:27:40 +000029CONF = config.CONF
30
Attila Fazekas1aed6202013-02-11 14:47:45 +010031
32class BotoClientBase(object):
33
34 ALLOWED_METHODS = set()
35
Matthew Treinish684d8992014-01-30 16:27:40 +000036 def __init__(self, username=None, password=None,
Attila Fazekas1aed6202013-02-11 14:47:45 +010037 auth_url=None, tenant_name=None,
38 *args, **kwargs):
Andrea Frittolif9cde7e2014-02-18 09:57:04 +000039 # FIXME(andreaf) replace credentials and auth_url with auth_provider
Attila Fazekas1aed6202013-02-11 14:47:45 +010040
Rob Crittendenaead3c22014-04-13 23:58:56 -040041 insecure_ssl = CONF.identity.disable_ssl_certificate_validation
Rob Crittendena7db6692014-11-23 18:44:38 -050042 ca_cert = CONF.identity.ca_certificates_file
Rob Crittendenaead3c22014-04-13 23:58:56 -040043
Matthew Treinish684d8992014-01-30 16:27:40 +000044 self.connection_timeout = str(CONF.boto.http_socket_timeout)
45 self.num_retries = str(CONF.boto.num_retries)
46 self.build_timeout = CONF.boto.build_timeout
Attila Fazekas1aed6202013-02-11 14:47:45 +010047 self.ks_cred = {"username": username,
48 "password": password,
49 "auth_url": auth_url,
Rob Crittendenaead3c22014-04-13 23:58:56 -040050 "tenant_name": tenant_name,
Rob Crittendena7db6692014-11-23 18:44:38 -050051 "insecure": insecure_ssl,
52 "cacert": ca_cert}
Attila Fazekas1aed6202013-02-11 14:47:45 +010053
54 def _keystone_aws_get(self):
Andrea Frittolif9cde7e2014-02-18 09:57:04 +000055 # FIXME(andreaf) Move EC2 credentials to AuthProvider
Attila Fazekas1aed6202013-02-11 14:47:45 +010056 import keystoneclient.v2_0.client
57
58 keystone = keystoneclient.v2_0.client.Client(**self.ks_cred)
59 ec2_cred_list = keystone.ec2.list(keystone.auth_user_id)
60 ec2_cred = None
61 for cred in ec2_cred_list:
62 if cred.tenant_id == keystone.auth_tenant_id:
63 ec2_cred = cred
64 break
65 else:
66 ec2_cred = keystone.ec2.create(keystone.auth_user_id,
67 keystone.auth_tenant_id)
68 if not all((ec2_cred, ec2_cred.access, ec2_cred.secret)):
Masayuki Igawabfa07602015-01-20 18:47:17 +090069 raise lib_exc.NotFound("Unable to get access and secret keys")
Attila Fazekas1aed6202013-02-11 14:47:45 +010070 return ec2_cred
71
72 def _config_boto_timeout(self, timeout, retries):
73 try:
74 boto.config.add_section("Boto")
75 except ConfigParser.DuplicateSectionError:
76 pass
77 boto.config.set("Boto", "http_socket_timeout", timeout)
78 boto.config.set("Boto", "num_retries", retries)
79
80 def __getattr__(self, name):
81 """Automatically creates methods for the allowed methods set."""
82 if name in self.ALLOWED_METHODS:
83 def func(self, *args, **kwargs):
84 with contextlib.closing(self.get_connection()) as conn:
85 return getattr(conn, name)(*args, **kwargs)
86
87 func.__name__ = name
88 setattr(self, name, types.MethodType(func, self, self.__class__))
89 setattr(self.__class__, name,
90 types.MethodType(func, None, self.__class__))
91 return getattr(self, name)
92 else:
93 raise AttributeError(name)
94
95 def get_connection(self):
96 self._config_boto_timeout(self.connection_timeout, self.num_retries)
97 if not all((self.connection_data["aws_access_key_id"],
98 self.connection_data["aws_secret_access_key"])):
Rob Crittendenaead3c22014-04-13 23:58:56 -040099 if all([self.ks_cred.get('auth_url'),
100 self.ks_cred.get('username'),
101 self.ks_cred.get('tenant_name'),
102 self.ks_cred.get('password')]):
Attila Fazekas1aed6202013-02-11 14:47:45 +0100103 ec2_cred = self._keystone_aws_get()
104 self.connection_data["aws_access_key_id"] = \
105 ec2_cred.access
106 self.connection_data["aws_secret_access_key"] = \
107 ec2_cred.secret
108 else:
109 raise exceptions.InvalidConfiguration(
Sean Dague14c68182013-04-14 15:34:30 -0400110 "Unable to get access and secret keys")
Attila Fazekas1aed6202013-02-11 14:47:45 +0100111 return self.connect_method(**self.connection_data)
Matthew Treinisha83a16e2012-12-07 13:44:02 -0500112
Attila Fazekasa23f5002012-10-23 19:32:45 +0200113
114class APIClientEC2(BotoClientBase):
115
116 def connect_method(self, *args, **kwargs):
117 return boto.connect_ec2(*args, **kwargs)
118
Matthew Treinish684d8992014-01-30 16:27:40 +0000119 def __init__(self, *args, **kwargs):
120 super(APIClientEC2, self).__init__(*args, **kwargs)
Rob Crittendenaead3c22014-04-13 23:58:56 -0400121 insecure_ssl = CONF.identity.disable_ssl_certificate_validation
Matthew Treinish684d8992014-01-30 16:27:40 +0000122 aws_access = CONF.boto.aws_access
123 aws_secret = CONF.boto.aws_secret
124 purl = urlparse.urlparse(CONF.boto.ec2_url)
Attila Fazekasa23f5002012-10-23 19:32:45 +0200125
Matthew Treinish684d8992014-01-30 16:27:40 +0000126 region_name = CONF.compute.region
Arata Notsu8f440392013-09-13 16:14:20 +0900127 if not region_name:
Matthew Treinish684d8992014-01-30 16:27:40 +0000128 region_name = CONF.identity.region
Arata Notsu8f440392013-09-13 16:14:20 +0900129 region = boto.ec2.regioninfo.RegionInfo(name=region_name,
Attila Fazekas1aed6202013-02-11 14:47:45 +0100130 endpoint=purl.hostname)
Attila Fazekasa23f5002012-10-23 19:32:45 +0200131 port = purl.port
132 if port is None:
133 if purl.scheme is not "https":
134 port = 80
135 else:
136 port = 443
137 else:
138 port = int(port)
139 self.connection_data = {"aws_access_key_id": aws_access,
140 "aws_secret_access_key": aws_secret,
141 "is_secure": purl.scheme == "https",
Rob Crittendenaead3c22014-04-13 23:58:56 -0400142 "validate_certs": not insecure_ssl,
Attila Fazekasa23f5002012-10-23 19:32:45 +0200143 "region": region,
144 "host": purl.hostname,
145 "port": port,
146 "path": purl.path}
147
148 ALLOWED_METHODS = set(('create_key_pair', 'get_key_pair',
149 'delete_key_pair', 'import_key_pair',
150 'get_all_key_pairs',
Burt Holzmanbb575e12013-07-14 00:23:30 -0500151 'get_all_tags',
Attila Fazekasa23f5002012-10-23 19:32:45 +0200152 'create_image', 'get_image',
153 'register_image', 'deregister_image',
154 'get_all_images', 'get_image_attribute',
155 'modify_image_attribute', 'reset_image_attribute',
156 'get_all_kernels',
157 'create_volume', 'delete_volume',
158 'get_all_volume_status', 'get_all_volumes',
159 'get_volume_attribute', 'modify_volume_attribute'
160 'bundle_instance', 'cancel_spot_instance_requests',
161 'confirm_product_instanc',
162 'get_all_instance_status', 'get_all_instances',
163 'get_all_reserved_instances',
164 'get_all_spot_instance_requests',
165 'get_instance_attribute', 'monitor_instance',
166 'monitor_instances', 'unmonitor_instance',
167 'unmonitor_instances',
168 'purchase_reserved_instance_offering',
169 'reboot_instances', 'request_spot_instances',
170 'reset_instance_attribute', 'run_instances',
171 'start_instances', 'stop_instances',
172 'terminate_instances',
173 'attach_network_interface', 'attach_volume',
174 'detach_network_interface', 'detach_volume',
175 'get_console_output',
176 'delete_network_interface', 'create_subnet',
177 'create_network_interface', 'delete_subnet',
178 'get_all_network_interfaces',
179 'allocate_address', 'associate_address',
180 'disassociate_address', 'get_all_addresses',
181 'release_address',
182 'create_snapshot', 'delete_snapshot',
183 'get_all_snapshots', 'get_snapshot_attribute',
184 'modify_snapshot_attribute',
185 'reset_snapshot_attribute', 'trim_snapshots',
186 'get_all_regions', 'get_all_zones',
187 'get_all_security_groups', 'create_security_group',
188 'delete_security_group', 'authorize_security_group',
189 'authorize_security_group_egress',
190 'revoke_security_group',
191 'revoke_security_group_egress'))
192
Attila Fazekasa23f5002012-10-23 19:32:45 +0200193
194class ObjectClientS3(BotoClientBase):
195
196 def connect_method(self, *args, **kwargs):
197 return boto.connect_s3(*args, **kwargs)
198
Matthew Treinish684d8992014-01-30 16:27:40 +0000199 def __init__(self, *args, **kwargs):
200 super(ObjectClientS3, self).__init__(*args, **kwargs)
Rob Crittendenaead3c22014-04-13 23:58:56 -0400201 insecure_ssl = CONF.identity.disable_ssl_certificate_validation
Matthew Treinish684d8992014-01-30 16:27:40 +0000202 aws_access = CONF.boto.aws_access
203 aws_secret = CONF.boto.aws_secret
204 purl = urlparse.urlparse(CONF.boto.s3_url)
Attila Fazekasa23f5002012-10-23 19:32:45 +0200205 port = purl.port
206 if port is None:
207 if purl.scheme is not "https":
208 port = 80
209 else:
210 port = 443
211 else:
212 port = int(port)
213 self.connection_data = {"aws_access_key_id": aws_access,
214 "aws_secret_access_key": aws_secret,
215 "is_secure": purl.scheme == "https",
Rob Crittendenaead3c22014-04-13 23:58:56 -0400216 "validate_certs": not insecure_ssl,
Attila Fazekasa23f5002012-10-23 19:32:45 +0200217 "host": purl.hostname,
218 "port": port,
Attila Fazekas1aed6202013-02-11 14:47:45 +0100219 "calling_format": boto.s3.connection.
220 OrdinaryCallingFormat()}
Attila Fazekasa23f5002012-10-23 19:32:45 +0200221
222 ALLOWED_METHODS = set(('create_bucket', 'delete_bucket', 'generate_url',
223 'get_all_buckets', 'get_bucket', 'delete_key',
224 'lookup'))