blob: e2e080ba339597633f1b443aa9ac450e8353b843 [file] [log] [blame]
Maru Newbyb096d9f2015-03-09 18:54:54 +00001# Copyright 2012 OpenStack Foundation
2# 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
16import ConfigParser
17import contextlib
18from tempest_lib import exceptions as lib_exc
19import types
20import urlparse
21
22from neutron.tests.tempest import config
23from neutron.tests.tempest import exceptions
24
25import boto
26import boto.ec2
27import boto.s3.connection
28
29CONF = config.CONF
30
31
32class BotoClientBase(object):
33
34 ALLOWED_METHODS = set()
35
36 def __init__(self, username=None, password=None,
37 auth_url=None, tenant_name=None,
38 *args, **kwargs):
39 # FIXME(andreaf) replace credentials and auth_url with auth_provider
40
41 insecure_ssl = CONF.identity.disable_ssl_certificate_validation
42 self.ca_cert = CONF.identity.ca_certificates_file
43
44 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
47 self.ks_cred = {"username": username,
48 "password": password,
49 "auth_url": auth_url,
50 "tenant_name": tenant_name,
51 "insecure": insecure_ssl,
52 "cacert": self.ca_cert}
53
54 def _keystone_aws_get(self):
55 # FIXME(andreaf) Move EC2 credentials to AuthProvider
56 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)):
69 raise lib_exc.NotFound("Unable to get access and secret keys")
70 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 _config_boto_ca_certificates_file(self, ca_cert):
81 if ca_cert is None:
82 return
83
84 try:
85 boto.config.add_section("Boto")
86 except ConfigParser.DuplicateSectionError:
87 pass
88 boto.config.set("Boto", "ca_certificates_file", ca_cert)
89
90 def __getattr__(self, name):
91 """Automatically creates methods for the allowed methods set."""
92 if name in self.ALLOWED_METHODS:
93 def func(self, *args, **kwargs):
94 with contextlib.closing(self.get_connection()) as conn:
95 return getattr(conn, name)(*args, **kwargs)
96
97 func.__name__ = name
98 setattr(self, name, types.MethodType(func, self, self.__class__))
99 setattr(self.__class__, name,
100 types.MethodType(func, None, self.__class__))
101 return getattr(self, name)
102 else:
103 raise AttributeError(name)
104
105 def get_connection(self):
106 self._config_boto_timeout(self.connection_timeout, self.num_retries)
107 self._config_boto_ca_certificates_file(self.ca_cert)
108 if not all((self.connection_data["aws_access_key_id"],
109 self.connection_data["aws_secret_access_key"])):
110 if all([self.ks_cred.get('auth_url'),
111 self.ks_cred.get('username'),
112 self.ks_cred.get('tenant_name'),
113 self.ks_cred.get('password')]):
114 ec2_cred = self._keystone_aws_get()
115 self.connection_data["aws_access_key_id"] = \
116 ec2_cred.access
117 self.connection_data["aws_secret_access_key"] = \
118 ec2_cred.secret
119 else:
120 raise exceptions.InvalidConfiguration(
121 "Unable to get access and secret keys")
122 return self.connect_method(**self.connection_data)
123
124
125class APIClientEC2(BotoClientBase):
126
127 def connect_method(self, *args, **kwargs):
128 return boto.connect_ec2(*args, **kwargs)
129
130 def __init__(self, *args, **kwargs):
131 super(APIClientEC2, self).__init__(*args, **kwargs)
132 insecure_ssl = CONF.identity.disable_ssl_certificate_validation
133 aws_access = CONF.boto.aws_access
134 aws_secret = CONF.boto.aws_secret
135 purl = urlparse.urlparse(CONF.boto.ec2_url)
136
137 region_name = CONF.compute.region
138 if not region_name:
139 region_name = CONF.identity.region
140 region = boto.ec2.regioninfo.RegionInfo(name=region_name,
141 endpoint=purl.hostname)
142 port = purl.port
143 if port is None:
144 if purl.scheme is not "https":
145 port = 80
146 else:
147 port = 443
148 else:
149 port = int(port)
150 self.connection_data = {"aws_access_key_id": aws_access,
151 "aws_secret_access_key": aws_secret,
152 "is_secure": purl.scheme == "https",
153 "validate_certs": not insecure_ssl,
154 "region": region,
155 "host": purl.hostname,
156 "port": port,
157 "path": purl.path}
158
159 ALLOWED_METHODS = set(('create_key_pair', 'get_key_pair',
160 'delete_key_pair', 'import_key_pair',
161 'get_all_key_pairs',
162 'get_all_tags',
163 'create_image', 'get_image',
164 'register_image', 'deregister_image',
165 'get_all_images', 'get_image_attribute',
166 'modify_image_attribute', 'reset_image_attribute',
167 'get_all_kernels',
168 'create_volume', 'delete_volume',
169 'get_all_volume_status', 'get_all_volumes',
170 'get_volume_attribute', 'modify_volume_attribute'
171 'bundle_instance', 'cancel_spot_instance_requests',
172 'confirm_product_instanc',
173 'get_all_instance_status', 'get_all_instances',
174 'get_all_reserved_instances',
175 'get_all_spot_instance_requests',
176 'get_instance_attribute', 'monitor_instance',
177 'monitor_instances', 'unmonitor_instance',
178 'unmonitor_instances',
179 'purchase_reserved_instance_offering',
180 'reboot_instances', 'request_spot_instances',
181 'reset_instance_attribute', 'run_instances',
182 'start_instances', 'stop_instances',
183 'terminate_instances',
184 'attach_network_interface', 'attach_volume',
185 'detach_network_interface', 'detach_volume',
186 'get_console_output',
187 'delete_network_interface', 'create_subnet',
188 'create_network_interface', 'delete_subnet',
189 'get_all_network_interfaces',
190 'allocate_address', 'associate_address',
191 'disassociate_address', 'get_all_addresses',
192 'release_address',
193 'create_snapshot', 'delete_snapshot',
194 'get_all_snapshots', 'get_snapshot_attribute',
195 'modify_snapshot_attribute',
196 'reset_snapshot_attribute', 'trim_snapshots',
197 'get_all_regions', 'get_all_zones',
198 'get_all_security_groups', 'create_security_group',
199 'delete_security_group', 'authorize_security_group',
200 'authorize_security_group_egress',
201 'revoke_security_group',
202 'revoke_security_group_egress'))
203
204
205class ObjectClientS3(BotoClientBase):
206
207 def connect_method(self, *args, **kwargs):
208 return boto.connect_s3(*args, **kwargs)
209
210 def __init__(self, *args, **kwargs):
211 super(ObjectClientS3, self).__init__(*args, **kwargs)
212 insecure_ssl = CONF.identity.disable_ssl_certificate_validation
213 aws_access = CONF.boto.aws_access
214 aws_secret = CONF.boto.aws_secret
215 purl = urlparse.urlparse(CONF.boto.s3_url)
216 port = purl.port
217 if port is None:
218 if purl.scheme is not "https":
219 port = 80
220 else:
221 port = 443
222 else:
223 port = int(port)
224 self.connection_data = {"aws_access_key_id": aws_access,
225 "aws_secret_access_key": aws_secret,
226 "is_secure": purl.scheme == "https",
227 "validate_certs": not insecure_ssl,
228 "host": purl.hostname,
229 "port": port,
230 "calling_format": boto.s3.connection.
231 OrdinaryCallingFormat()}
232
233 ALLOWED_METHODS = set(('create_bucket', 'delete_bucket', 'generate_url',
234 'get_all_buckets', 'get_bucket', 'delete_key',
235 'lookup'))