Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1# This file is part of daf_butler. 

2# 

3# Developed for the LSST Data Management System. 

4# This product includes software developed by the LSST Project 

5# (http://www.lsst.org). 

6# See the COPYRIGHT file at the top-level directory of this distribution 

7# for details of code ownership. 

8# 

9# This program is free software: you can redistribute it and/or modify 

10# it under the terms of the GNU General Public License as published by 

11# the Free Software Foundation, either version 3 of the License, or 

12# (at your option) any later version. 

13# 

14# This program is distributed in the hope that it will be useful, 

15# but WITHOUT ANY WARRANTY; without even the implied warranty of 

16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 

17# GNU General Public License for more details. 

18# 

19# You should have received a copy of the GNU General Public License 

20# along with this program. If not, see <http://www.gnu.org/licenses/>. 

21 

22__all__ = ("DB_AUTH_ENVVAR", "DB_AUTH_PATH", "ConnectionStringFactory") 

23 

24from sqlalchemy.engine import url 

25from ._dbAuth import DbAuth, DbAuthNotFoundError 

26 

27DB_AUTH_ENVVAR = "LSST_DB_AUTH" 

28"""Default name of the environmental variable that will be used to locate DB 

29credentials configuration file. """ 

30 

31DB_AUTH_PATH = "~/.lsst/db-auth.yaml" 

32"""Default path at which it is expected that DB credentials are found.""" 

33 

34 

35class ConnectionStringFactory: 

36 """Factory for `sqlalchemy.engine.url.URL` instances. 

37 

38 The factory constructs a connection string URL object by parsing the 

39 connection string, the 'db' key in the registry configuration. 

40 Username, password, host, port or database can be specified as keys in the 

41 config explicitly. If username or password are missing a matching DB is 

42 found in the credentials file pointed to by `DB_AUTH_ENVVAR` or 

43 `DB_AUTH_PATH` values. 

44 """ 

45 

46 keys = ('username', 'password', 'host', 'port', 'database') 

47 

48 @classmethod 

49 def fromConfig(cls, registryConfig): 

50 """Parses the 'db' key in the config, and if they exist username, 

51 password, host, port and database keys, and returns an connection 

52 string object. 

53 

54 If no username and password are found in the connection string, or in 

55 the config, they are retrieved from a file at `DB_AUTH_PATH` or 

56 `DB_AUTH_ENVVAR`. Sqlite dialect does not require a password. 

57 

58 Parameters 

59 ---------- 

60 config : `ButlerConfig`, `RegistryConfig`, `Config` or `str` 

61 Registry configuration 

62 

63 Returns 

64 ------- 

65 connectionString : `sqlalchemy.engine.url.URL` 

66 URL object representing the connection string. 

67 

68 Raises 

69 ------ 

70 DbAuthPermissionsError 

71 If the credentials file has incorrect permissions. 

72 DbAuthError 

73 A problem occured when retrieving DB authentication. 

74 """ 

75 # this import can not live on the top because of circular import issue 

76 from lsst.daf.butler.registry import RegistryConfig 

77 regConf = RegistryConfig(registryConfig) 

78 conStr = url.make_url(regConf['db']) 

79 

80 for key in cls.keys: 

81 if getattr(conStr, key) is None: 

82 setattr(conStr, key, regConf.get(key)) 

83 

84 # when host is None we cross our fingers and return 

85 if conStr.host is None: 

86 return conStr 

87 

88 # allow other mechanisms to insert username and password by not forcing 

89 # the credentials to exist. If other mechanisms are used it's possible 

90 # that credentials were never set-up, or that there would be no match 

91 # in the credentials file. Both need to be ignored. 

92 try: 

93 dbAuth = DbAuth(DB_AUTH_PATH, DB_AUTH_ENVVAR) 

94 auth = dbAuth.getAuth(conStr.drivername, conStr.username, conStr.host, 

95 conStr.port, conStr.database) 

96 except DbAuthNotFoundError: 

97 # credentials file doesn't exist or no matches were found 

98 pass 

99 else: 

100 # only assign auth when *no* errors were raised, otherwise assume 

101 # connection string was correct 

102 conStr.username = auth[0] 

103 conStr.password = auth[1] 

104 

105 return conStr