def test_loading_a_file(): # --- setup config = yaml.safe_load(''' sources: - type: service_broker config: brokers: - https://hello ''') with open('test_file.yaml', 'w+') as f: yaml.dump(config, f) # --- load data = load('file://./test_file.yaml') # --- cleanup os.remove('test_file.yaml') # --- test expected = { 'sources': [{ 'config': { 'brokers': ['https://hello'] }, 'type': 'service_broker' }] } assert data == expected
def test_loading_a_file_over_http_with_json(): data = load( 'https+json://bitbucket.org' '/!api/2.0/snippets/vsyrakis/qebL6z/' '52450800bf05434831f9f702aedaeca0a1b42122/files/controlplane_test.json' ) expected = {'sources': [{'config': {}, 'type': 'service_broker'}]} assert data == expected
def source(self) -> str: if 'jinja' in self.path: # The Jinja2 template serializer does not properly set a name # for the loaded template. # The repr for the template prints out as the memory address # This makes it really hard to generate a consistent version_info string # in rendered configuration. # For this reason, we re-load the template as a string instead, and create a checksum. path = self.path.replace('+jinja', '+string') return load(path) elif self.is_python_source: # If the template specified is a python source file, # we can simply read and return the source of it. path = self.path.replace('python', 'file+string') return load(path) else: # The only other supported serializers are string, yaml, and json # So it should be safe to create this checksum off return str(self.content)
class SovereignAsgiConfig(BaseModel): host: str = load('env://SOVEREIGN_HOST', '0.0.0.0') port: int = load('env://SOVEREIGN_PORT', 8080) keepalive: int = load('env://SOVEREIGN_KEEPALIVE', 5) workers: int = load('env://SOVEREIGN_WORKERS', (multiprocessing.cpu_count() * 2) + 1) reuse_port: bool = True log_level: str = 'warning' worker_class: str = 'uvicorn.workers.UvicornWorker' def as_gunicorn_conf(self): return { 'bind': ':'.join(map(str, [self.host, self.port])), 'keepalive': self.keepalive, 'reuse_port': self.reuse_port, 'loglevel': self.log_level, 'workers': self.workers, 'worker_class': self.worker_class }
def test_loading_a_file_over_http(): data = load( 'https://bitbucket.org' '/!api/2.0/snippets/vsyrakis/Ee9yjo/' '54ae1495ab113cc669623e538691106c7de313c9/files/controlplane_test.yaml' ) expected = { 'sources': [{ 'config': { 'brokers': ['https://google.com/'] }, 'type': 'service_broker' }] } assert data == expected
def parse_raw_configuration(path: str): ret = dict() for p in path.split(','): ret = merge(obj_a=ret, obj_b=config_loader.load(p), merge_lists=True) return ret
def template_context_refresh(): """ Modifies template_context in-place with new values """ for k, v in config.template_context.items(): template_context[k] = load(v)
def test_loading_python_packaged_resources(): data = load('pkgdata+string://sovereign:static/style.css') assert 'font-family:' in data
def test_loading_a_non_parseable_line_returns_a_string(): data = load('helloworld') assert data == 'helloworld'
def test_loading_environment_variable_with_json(): data = load('env+json://CONFIG_LOADER_TEST') assert data == {'hello': 'world'}
def get(self): """ Uses the file config loader to load the given path """ return load(self.path)
def content(self) -> Template: return load(self.path)
def code(self): return load(self.path)
def loaded_tags(self): return {k: load(v) for k, v in self.tags.items()}
class SovereignConfig(BaseModel): sources: List[ConfiguredSource] templates: dict template_context: dict = {} eds_priority_matrix: dict = {} modifiers: List[str] = [] global_modifiers: List[str] = [] regions: List[str] = [] statsd: StatsdConfig = StatsdConfig() auth_enabled: StrictBool = load('env://SOVEREIGN_AUTH_ENABLED', False) auth_passwords: str = load('env://SOVEREIGN_AUTH_PASSWORDS', '') encryption_key: str = load('env://SOVEREIGN_ENCRYPTION_KEY', '') or load( 'env://FERNET_ENCRYPTION_KEY', '') environment: str = load('env://SOVEREIGN_ENVIRONMENT_TYPE', '') or load( 'env://MICROS_ENVTYPE', 'local') debug_enabled: StrictBool = load('env://SOVEREIGN_DEBUG', False) sentry_dsn: str = load('env://SOVEREIGN_SENTRY_DSN', '') node_match_key: str = load('env://SOVEREIGN_NODE_MATCH_KEY', 'cluster') node_matching: StrictBool = load('env://SOVEREIGN_MATCHING_ENABLED', True) source_match_key: str = load('env://SOVEREIGN_SOURCE_MATCH_KEY', 'service_clusters') sources_refresh_rate: int = load('env://SOVEREIGN_SOURCES_REFRESH_RATE', 30) cache_strategy: CacheStrategy = load('env://SOVEREIGN_CACHE_STRATEGY', 'context') refresh_context: StrictBool = load('env://SOVEREIGN_REFRESH_CONTEXT', False) context_refresh_rate: int = load('env://SOVEREIGN_CONTEXT_REFRESH_RATE', 3600) dns_hard_fail: StrictBool = load('env://SOVEREIGN_DNS_HARD_FAIL', False) enable_access_logs: StrictBool = load('env://SOVEREIGN_ENABLE_ACCESS_LOGS', True) class Config: keep_untouched = (cached_property, ) @property def passwords(self): return self.auth_passwords.split(',') or [] @cached_property def xds_templates(self): ret = { '__any__': {} # Special key to hold templates from all versions } for version, templates in self.templates.items(): loaded_templates = { _type: XdsTemplate(path=path) for _type, path in templates.items() } ret[version] = loaded_templates ret['__any__'].update(loaded_templates) return ret def __str__(self): return self.__repr__() def __repr__(self): kwargs = [f'{k}={v}' for k, v in self.show().items()] return f'SovereignConfig({kwargs})' def show(self): safe_items = dict() for key, value in self.__dict__.items(): if key in [ 'auth_passwords', 'encryption_key', 'passwords', 'sentry_dsn' ]: value = 'redacted' safe_items[key] = value return safe_items