1111# under the License.
1212import importlib
1313import os
14- import types
15- import warnings
1614
1715from openstack import _log
18- from openstack import connection
19- from openstack import service_description
2016from openstack import utils
2117
2218
8177 'dns' : {
8278 'service_type' : 'dns' ,
8379 'replace_system' : True ,
84- # 'append_project_id': True,
8580 },
8681 'kms' : {
8782 'service_type' : 'kms' ,
9186 'service_type' : 'obs' ,
9287 'require_ak' : True ,
9388 'endpoint_service_type' : 'object' ,
89+ 'set_endpoint_override' : True
9490 },
9591 'rds' : {
9692 'service_type' : 'rds' ,
9793 # 'additional_headers': {'content-type': 'application/json'},
9894 'append_project_id' : True ,
9995 },
10096 'volume_backup' : {
101- 'service_type' : 'vbs ' ,
97+ 'service_type' : 'volume_backup ' ,
10298 'append_project_id' : True ,
99+ 'endpoint_service_type' : 'vbs' ,
103100 },
104101}
105102
@@ -115,8 +112,8 @@ def _get_descriptor(service_name):
115112 desc_class = _find_service_description_class (service_type )
116113 # _logger.debug('descriptor class %s' % desc_class)
117114 descriptor_args = {
118- 'service_type' : service .get ('endpoint_service_type' , service_type )
119- # 'service_type': service_type
115+ 'service_type' : service .get ('endpoint_service_type' , service_type ),
116+ 'aliases' : [ service . get ( 'service_type' , service_type )]
120117 }
121118
122119 if not desc_class .supported_versions :
@@ -155,121 +152,95 @@ def _find_service_description_class(service_type):
155152 module_name = service_type .replace ('-' , '_' ) + '_service'
156153 class_name = '' .join (
157154 [part .capitalize () for part in module_name .split ('_' )])
158- try :
159- import_name = '.' .join ([package_name , module_name ])
160- service_description_module = importlib .import_module (import_name )
161- except ImportError as e :
162- # ImportWarning is ignored by default. This warning is here
163- # as an opt-in for people trying to figure out why something
164- # didn't work.
165- warnings .warn (
166- "Could not import {service_type} service description: {e}" .format (
167- service_type = service_type , e = str (e )),
168- ImportWarning )
169- return service_description .ServiceDescription
155+ # try:
156+ import_name = '.' .join ([package_name , module_name ])
157+ service_description_module = importlib .import_module (import_name )
158+ # except ImportError as e:
159+ # # ImportWarning is ignored by default. This warning is here
160+ # # as an opt-in for people trying to figure out why something
161+ # # didn't work.
162+ # _logger .warn("Could not import {service_type} "
163+ # " service description: {e}".format(
164+ # service_type=service_type, e=str(e)),
165+ # ImportWarning)
166+ # return service_description.ServiceDescription
170167 # There are no cases in which we should have a module but not the class
171168 # inside it.
172169 service_description_class = getattr (service_description_module , class_name )
173170 return service_description_class
174171
175172
176- def patch_connection (target ):
177- # descriptors are not working out of box for runtime attributes
178- # So we need to inject them. Additionally we need to override some
179- # properties of the proxy
180-
181- def get_otc_proxy (self , service_name = None , service = None ):
182- _logger .debug ('get_otc_proxy is %s, %s, %s' %
183- (self , service_name , service ))
184-
185- if service ['service_type' ] not in self ._proxies :
186- # Initialize proxy and inject required properties
187- descriptor = _get_descriptor (service_name )
188- if not descriptor :
189- _logger .error ('descriptor for service %s is missing' %
190- service_name )
191- return
192-
193- proxy = descriptor .__get__ (self , descriptor )
194-
195- # Set additional_headers into the proxy
196- if 'additional_headers' in service :
197- proxy .additional_headers = service .get ('additional_headers' )
198-
199- # If service requires AK/SK - inject them
200- if service .get ('require_ak' , False ):
201- _logger .debug ('during registration found that ak is required' )
202- config = self .config .config
203-
204- ak = config .get ('ak' , None )
205- sk = config .get ('sk' , None )
206-
207- if not ak :
208- ak = os .getenv ('S3_ACCESS_KEY_ID' , None )
209- if not sk :
210- sk = os .getenv ('S3_SECRET_ACCESS_KEY' , None )
211-
212- if ak and sk :
213- proxy ._set_ak (ak = ak , sk = sk )
214- else :
215- _logger .error ('AK/SK pair is not available' )
216- return
217-
218- # Set endpoint_override
219- endpoint_override = service .get ('endpoint_override' , None )
220- if endpoint_override :
221- _logger .debug ('Setting endpoint_override into the %s.Proxy' %
222- service_name )
223- proxy .endpoint_override = endpoint_override
224-
225- # Ensure EP contain %project_id
226- append_project_id = service .get ('append_project_id' , False )
227- if append_project_id :
228- ep = proxy .get_endpoint_data ().catalog_url
229- project_id = proxy .get_project_id ()
230- if ep and not ep .rstrip ('/' ).endswith ('\\ %(project_id)s' ) \
231- and not ep .rstrip ('/' ).endswith ('$(tenant_id)s' ) \
232- and not ep .rstrip ('/' ).endswith (project_id ):
233- proxy .endpoint_override = \
234- utils .urljoin (ep , '%(project_id)s' )
235- else :
236- proxy = self ._proxies [service ['service_type' ]]
237-
238- return proxy
239-
240- connection .Connection .get_otc_proxy = types .MethodType (
241- get_otc_proxy , target )
242-
243-
244- def inject_service_to_sdk (conn , service_name , service ):
245- """Inject service into the SDK space
246-
247- For some reason it should be a separate function
248- """
249- setattr (
250- conn .__class__ ,
251- service_name ,
252- property (
253- fget = lambda self : self .get_otc_proxy (service_name , service )
254- )
255- )
256-
257-
258- def register_otc_extensions (conn , ** kwargs ):
173+ def load (conn , ** kwargs ):
259174 """Register supported OTC services and make them known to the OpenStackSDK
260175
261176 :param conn: An established OpenStack cloud connection
262177
263178 :returns: none
264179 """
265- patch_connection (conn )
180+ conn .authorize ()
181+ project_id = conn ._get_project_info ().id
266182
267183 for (service_name , service ) in OTC_SERVICES .items ():
268184 _logger .debug ('trying to register service %s' % service_name )
269185
270186 if service .get ('replace_system' , False ):
271- conn ._proxies .pop (service_name , None )
272-
273- inject_service_to_sdk (conn , service_name , service )
187+ # system_proxy = getattr(conn, service['service_type'])
188+ # for service_type in system_proxy.all_types:
189+ if service ['service_type' ] in conn ._proxies :
190+ del conn ._proxies [service ['service_type' ]]
191+ # print(hasattr(conn, service_name))
192+ # delattr(conn, service['service_type'])
193+
194+ sd = _get_descriptor (service_name )
195+
196+ conn .add_service (sd )
197+
198+ if service .get ('append_project_id' , False ):
199+ # If service requires project_id, but it is not present in the
200+ # service catalog - set endpoint_override
201+ ep = conn .endpoint_for (sd .service_type )
202+ if ep and not ep .rstrip ('/' ).endswith ('\\ %(project_id)s' ) \
203+ and not ep .rstrip ('/' ).endswith ('$(tenant_id)s' ) \
204+ and not ep .rstrip ('/' ).endswith (project_id ):
205+ conn .config .config [
206+ '_' .join ([
207+ sd .service_type .lower ().replace ('-' , '_' ),
208+ 'endpoint_override'
209+ ])
210+ ] = utils .urljoin (ep , '%(project_id)s' )
211+ elif service .get ('set_endpoint_override' , False ):
212+ # We need to set endpoint_override for OBS, since otherwise it
213+ # fails dramatically
214+ ep = conn .endpoint_for (sd .service_type )
215+ conn .config .config [
216+ '_' .join ([
217+ sd .service_type .lower ().replace ('-' , '_' ),
218+ 'endpoint_override'
219+ ])
220+ ] = utils .urljoin (ep )
221+
222+ # If service requires AK/SK - inject them
223+ if service .get ('require_ak' , False ):
224+ _logger .debug ('during registration found that ak is required' )
225+ config = conn .config .config
226+
227+ proxy = getattr (conn , service_name )
228+
229+ ak = config .get ('ak' , None )
230+ sk = config .get ('sk' , None )
231+
232+ if not ak :
233+ ak = os .getenv ('S3_ACCESS_KEY_ID' , None )
234+ if not sk :
235+ sk = os .getenv ('S3_SECRET_ACCESS_KEY' , None )
236+
237+ if ak and sk :
238+ proxy ._set_ak (ak = ak , sk = sk )
239+ else :
240+ _logger .error ('AK/SK pair is not available' )
241+ # return
274242
275243 return None
244+
245+
246+ register_otc_extensions = load
0 commit comments