1# Licensed to the Apache Software Foundation (ASF) under one or more 2# contributor license agreements. See the NOTICE file distributed with 3# this work for additional information regarding copyright ownership. 4# The ASF licenses this file to You under the Apache License, Version 2.0 5# (the "License"); you may not use this file except in compliance with 6# the License. You may obtain 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, 12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13# See the License for the specific language governing permissions and 14# limitations under the License. 15 16""" 17Common methods for obtaining a reference to the provider driver class. 18""" 19 20__all__ = [ 21 'get_driver', 22 'set_driver' 23] 24 25 26def get_driver(drivers, provider, deprecated_providers=None, 27 deprecated_constants=None): 28 """ 29 Get a driver. 30 31 :param drivers: Dictionary containing valid providers. 32 :type drivers: ``dict`` 33 34 :param provider: Id (constant) of provider to get the driver for. 35 :type provider: :class:`libcloud.types.Provider` 36 37 :param: deprecated_providers: Dictionary with information about the 38 deprecated drivers. 39 :type deprecated_providers: ``dict`` 40 41 :param: deprecated_constants: Dictionary with information about the 42 deprecated provider constants. 43 :type deprecated_constants: ``dict`` 44 """ 45 # Those providers have been shut down or similar. 46 deprecated_providers = deprecated_providers or {} 47 if provider in deprecated_providers: 48 url = deprecated_providers[provider]['url'] 49 reason = deprecated_providers[provider]['reason'] 50 msg = ('Provider no longer supported: %s, please visit: %s' % 51 (url, reason)) 52 raise Exception(msg) 53 54 # Those drivers have moved to "region" constructor argument model 55 deprecated_constants = deprecated_constants or {} 56 if provider in deprecated_constants: 57 old_name = provider.upper() 58 new_name = deprecated_constants[provider].upper() 59 60 url = 'https://s.apache.org/lc0140un' 61 msg = ('Provider constant "%s" has been removed. New constant ' 62 'is now called "%s".\n' 63 'For more information on this change and how to modify your ' 64 'code to work with it, please visit: %s' % 65 (old_name, new_name, url)) 66 raise Exception(msg) 67 68 if provider in drivers: 69 mod_name, driver_name = drivers[provider] 70 _mod = __import__(mod_name, globals(), locals(), [driver_name]) 71 return getattr(_mod, driver_name) 72 73 # NOTE: This is for backward compatibility reasons where user could use 74 # a string value instead of a Provider.FOO enum constant and this function 75 # would still work 76 for provider_name, (mod_name, driver_name) in drivers.items(): 77 # NOTE: This works because Provider enum class overloads __eq__ 78 if provider.lower() == provider_name.lower(): 79 _mod = __import__(mod_name, globals(), locals(), [driver_name]) 80 return getattr(_mod, driver_name) 81 82 raise AttributeError('Provider %s does not exist' % (provider)) 83 84 85def set_driver(drivers, provider, module, klass): 86 """ 87 Sets a driver. 88 89 :param drivers: Dictionary to store providers. 90 :param provider: Id of provider to set driver for 91 92 :type provider: :class:`libcloud.types.Provider` 93 :param module: The module which contains the driver 94 95 :type module: L 96 :param klass: The driver class name 97 98 :type klass: 99 """ 100 101 if provider in drivers: 102 raise AttributeError('Provider %s already registered' % (provider)) 103 104 drivers[provider] = (module, klass) 105 106 # Check if this driver is valid 107 try: 108 driver = get_driver(drivers, provider) 109 except (ImportError, AttributeError) as exp: 110 drivers.pop(provider) 111 raise exp 112 113 return driver 114