Coverage for /usr/local/lib/python3.10/site-packages/opal_common-0.0.0-py3.10.egg/opal_common/config.py: 100%

49 statements  

« prev     ^ index     » next       coverage.py v7.15.2, created at 2026-10-10 11:54 +0000

1from pathlib import Path 

2from sys import prefix 

3 

4from opal_common.authentication.types import EncryptionKeyFormat, JWTAlgorithm 

5from opal_common.confi import Confi, confi 

6 

7_LOG_FORMAT_WITHOUT_PID = "<green>{time}</green> | <blue>{name: <40}</blue>|<level>{level:^6} | {message}</level>\n{exception}" 

8_LOG_FORMAT_WITH_PID = "<green>{time}</green> | {process} | <blue>{name: <40}</blue>|<level>{level:^6} | {message}</level>\n{exception}" 

9 

10 

11class OpalCommonConfig(Confi): 

12 ALLOWED_ORIGINS = confi.list( 

13 "ALLOWED_ORIGINS", ["*"], description="List of allowed origins for CORS" 

14 ) 

15 # Process name to show in logs - Not confi-controlable on purpose 

16 PROCESS_NAME = "" 

17 # Logging 

18 # - Log formatting 

19 LOG_FORMAT_INCLUDE_PID = confi.bool( 

20 "LOG_FORMAT_INCLUDE_PID", False, description="Include process ID in log format" 

21 ) 

22 LOG_FORMAT = confi.str( 

23 "LOG_FORMAT", 

24 confi.delay( 

25 lambda LOG_FORMAT_INCLUDE_PID=False: ( 

26 _LOG_FORMAT_WITH_PID 

27 if LOG_FORMAT_INCLUDE_PID 

28 else _LOG_FORMAT_WITHOUT_PID 

29 ) 

30 ), 

31 description="The format of the log messages", 

32 ) 

33 LOG_TRACEBACK = confi.bool( 

34 "LOG_TRACEBACK", True, description="Include traceback in log messages" 

35 ) 

36 LOG_DIAGNOSE = confi.bool( 

37 "LOG_DIAGNOSE", 

38 False, 

39 description="Include diagnosis (local variable values) in tracebacks. " 

40 "Off by default because loguru renders raw variable values, which can " 

41 "leak credentials (e.g. auth headers/tokens) into logs - only enable for " 

42 "local debugging. Also gates verbose git SSH protocol tracing " 

43 "(GIT_TRACE/GIT_CURL_VERBOSE on SSH clones), which adds noisy protocol/" 

44 "host disclosure to logs.", 

45 ) 

46 LOG_COLORIZE = confi.bool("LOG_COLORIZE", True, description="Colorize log messages") 

47 LOG_SERIALIZE = confi.bool( 

48 "LOG_SERIALIZE", False, description="Serialize log messages" 

49 ) 

50 LOG_PIPE_TO_STDERR = confi.bool( 

51 "LOG_PIPE_TO_STDERR", 

52 True, 

53 description="Should we send logs to stderr? otherwise to stdout", 

54 ) 

55 LOG_SHOW_CODE_LINE = confi.bool( 

56 "LOG_SHOW_CODE_LINE", True, description="Show code line in log messages" 

57 ) 

58 # - log level 

59 LOG_LEVEL = confi.str("LOG_LEVEL", "INFO", description="The log level to show") 

60 # - Which modules should be logged 

61 LOG_MODULE_EXCLUDE_LIST = confi.list( 

62 "LOG_MODULE_EXCLUDE_LIST", 

63 [ 

64 "uvicorn", 

65 # NOTE: the env var LOG_MODULE_EXCLUDE_OPA affects this list 

66 ], 

67 description="List of modules to exclude from logging", 

68 ) 

69 LOG_MODULE_INCLUDE_LIST = confi.list( 

70 "LOG_MODULE_INCLUDE_LIST", 

71 ["uvicorn.protocols.http"], 

72 description="List of modules to include in logging", 

73 ) 

74 LOG_PATCH_UVICORN_LOGS = confi.bool( 

75 "LOG_PATCH_UVICORN_LOGS", 

76 True, 

77 description="Should we takeover UVICORN's logs so they appear in the main logger", 

78 ) 

79 # - Log to file as well ( @see https://github.com/Delgan/loguru#easier-file-logging-with-rotation--retention--compression) 

80 LOG_TO_FILE = confi.bool( 

81 "LOG_TO_FILE", False, description="Should we log to a file" 

82 ) 

83 

84 LOG_FILE_PATH = confi.str( 

85 "LOG_FILE_PATH", 

86 f"opal_{PROCESS_NAME}{{time}}.log", 

87 description="path to save log file", 

88 ) 

89 LOG_FILE_ROTATION = confi.str( 

90 "LOG_FILE_ROTATION", "250 MB", description="Log file rotation size" 

91 ) 

92 LOG_FILE_RETENTION = confi.str( 

93 "LOG_FILE_RETENTION", "10 days", description="Log file retention time" 

94 ) 

95 LOG_FILE_COMPRESSION = confi.str( 

96 "LOG_FILE_COMPRESSION", None, description="Log file compression format" 

97 ) 

98 LOG_FILE_SERIALIZE = confi.str( 

99 "LOG_FILE_SERIALIZE", True, description="Serialize log messages in file" 

100 ) 

101 LOG_FILE_LEVEL = confi.str( 

102 "LOG_FILE_LEVEL", "INFO", description="The log level to show in file" 

103 ) 

104 

105 STATISTICS_ENABLED = confi.bool( 

106 "STATISTICS_ENABLED", 

107 False, 

108 description="Set if OPAL server will collect statistics about OPAL clients may cause a small performance hit", 

109 ) 

110 STATISTICS_ADD_CLIENT_CHANNEL = confi.str( 

111 "STATISTICS_ADD_CLIENT_CHANNEL", 

112 "__opal_stats_add", 

113 description="The topic to update about new OPAL clients connection", 

114 ) 

115 STATISTICS_REMOVE_CLIENT_CHANNEL = confi.str( 

116 "STATISTICS_REMOVE_CLIENT_CHANNEL", 

117 "__opal_stats_rm", 

118 description="The topic to update about OPAL clients disconnection", 

119 ) 

120 

121 # Fetching Providers 

122 # - where to load providers from 

123 FETCH_PROVIDER_MODULES = confi.list( 

124 "FETCH_PROVIDER_MODULES", 

125 ["opal_common.fetcher.providers"], 

126 description="List of modules to load fetch providers from", 

127 ) 

128 

129 # Fetching engine 

130 # Max number of worker tasks handling fetch events concurrently 

131 FETCHING_WORKER_COUNT = confi.int( 

132 "FETCHING_WORKER_COUNT", 

133 6, 

134 description="Max number of worker tasks handling fetch events concurrently", 

135 ) 

136 # Time in seconds to wait on the queued fetch task. 

137 FETCHING_CALLBACK_TIMEOUT = confi.int( 

138 "FETCHING_CALLBACK_TIMEOUT", 

139 10, 

140 description="Time in seconds to wait on the queued fetch task", 

141 ) 

142 # Time in seconds to wait for queuing a new task (if the queue is full) 

143 FETCHING_ENQUEUE_TIMEOUT = confi.int( 

144 "FETCHING_ENQUEUE_TIMEOUT", 

145 10, 

146 description="Time in seconds to wait for queuing a new task (if the queue is full)", 

147 ) 

148 

149 GIT_SSH_KEY_FILE = confi.str( 

150 "GIT_SSH_KEY_FILE", 

151 str(Path.home() / ".ssh/opal_repo_ssh_key"), 

152 description="Path to the SSH key file for Git", 

153 ) 

154 

155 # Trust self signed certificates (Advanced Usage - only affects OPAL client) ----------------------------- 

156 # DO NOT change these defaults unless you absolutely know what you are doing! 

157 # By default, OPAL client only trusts SSL certificates that are signed by a public recognized CA (certificate authority). 

158 # However, sometimes (mostly in on-prem setups or in dev environments) users setup their own self-signed certificates. 

159 # We allow OPAL client to trust these certificates, by changing the following config vars. 

160 CLIENT_SELF_SIGNED_CERTIFICATES_ALLOWED = confi.bool( 

161 "CLIENT_SELF_SIGNED_CERTIFICATES_ALLOWED", 

162 False, 

163 description="Whether or not OPAL Client will trust HTTPs connections protected by self signed certificates. DO NOT USE THIS IN PRODUCTION!", 

164 ) 

165 CLIENT_SSL_CONTEXT_TRUSTED_CA_FILE = confi.str( 

166 "CLIENT_SSL_CONTEXT_TRUSTED_CA_FILE", 

167 None, 

168 description="A path to your own CA public certificate file (usually a .crt or a .pem file). Certificates signed by this issuer will be trusted by OPAL Client. DO NOT USE THIS IN PRODUCTION!", 

169 ) 

170 

171 # security 

172 AUTH_PUBLIC_KEY_FORMAT = confi.enum( 

173 "AUTH_PUBLIC_KEY_FORMAT", 

174 EncryptionKeyFormat, 

175 EncryptionKeyFormat.ssh, 

176 description="Format of the public key for authentication", 

177 ) 

178 AUTH_PUBLIC_KEY = confi.delay( 

179 lambda AUTH_PUBLIC_KEY_FORMAT=None: confi.public_key( 

180 "AUTH_PUBLIC_KEY", 

181 default=None, 

182 key_format=AUTH_PUBLIC_KEY_FORMAT, 

183 description="Public key for authentication", 

184 ) 

185 ) 

186 AUTH_JWT_ALGORITHM = confi.enum( 

187 "AUTH_JWT_ALGORITHM", 

188 JWTAlgorithm, 

189 getattr(JWTAlgorithm, "RS256"), 

190 description="jwt algorithm, possible values: see: https://pyjwt.readthedocs.io/en/stable/algorithms.html", 

191 ) 

192 AUTH_JWT_AUDIENCE = confi.str( 

193 "AUTH_JWT_AUDIENCE", 

194 "https://api.opal.ac/v1/", 

195 description="Audience for JWT authentication", 

196 ) 

197 AUTH_JWT_ISSUER = confi.str( 

198 "AUTH_JWT_ISSUER", 

199 f"https://opal.ac/", 

200 description="Issuer for JWT authentication", 

201 ) 

202 POLICY_REPO_POLICY_EXTENSIONS = confi.list( 

203 "POLICY_REPO_POLICY_EXTENSIONS", 

204 [".rego"], 

205 description="List of extensions to serve as policy modules", 

206 ) 

207 

208 ENABLE_METRICS = confi.bool( 

209 "ENABLE_METRICS", False, description="Enable metrics collection" 

210 ) 

211 

212 # optional APM tracing with datadog 

213 ENABLE_DATADOG_APM = confi.bool( 

214 "ENABLE_DATADOG_APM", 

215 False, 

216 description="Set if OPAL server should enable tracing with datadog APM", 

217 ) 

218 HTTP_FETCHER_PROVIDER_CLIENT = confi.str( 

219 "HTTP_FETCHER_PROVIDER_CLIENT", 

220 "aiohttp", 

221 description="The client to use for fetching data, can be either aiohttp or httpx." 

222 "if provided different value, aiohttp will be used.", 

223 ) 

224 HTTP_FETCHER_TIMEOUT = confi.float( 

225 "HTTP_FETCHER_TIMEOUT", 

226 5, 

227 description="The timeout for the httpx or aiohttp fetcher provider, in seconds. " 

228 "if provided different value, 5 seconds will be used.", 

229 ) 

230 

231 

232opal_common_config = OpalCommonConfig(prefix="OPAL_")