def session(self): """Get an instance of ``requests.Session``. By default, the session will not use certificate verification. To enable certificate verification: - set ``CN_COUCHBASE_VERIFY`` environment variable to ``true`` (default to ``false``) - ensure ``CN_COUCHBASE_CERT_FILE`` pointed to valid Couchbase cluster certificate (default to ``/etc/certs/couchbase.crt``) - optionally, set ``CN_COUCHBASE_HOST_HEADER`` to match Common Name or any of SubjectAltName defined in certificate (default to ``localhost``) """ suppress_verification_warning() if not self._session: self._session = requests.Session() self._session.verify = False verify = as_boolean(os.environ.get("CN_COUCHBASE_VERIFY", False)) if verify: self._session.mount("https://", HostHeaderSSLAdapter()) self._session.verify = os.environ.get("CN_COUCHBASE_CERT_FILE") or "/etc/certs/couchbase.crt" self._session.headers["Host"] = os.environ.get("CN_COUCHBASE_HOST_HEADER") or "localhost" return self._session
def render_ldap_properties(manager, src: str, dest: str) -> None: """Render file contains properties to connect to LDAP server. :params manager: An instance of :class:`~jans.pycloudlib.manager._Manager`. :params src: Absolute path to the template. :params dest: Absolute path where generated file is located. """ ldap_url = os.environ.get("CN_LDAP_URL", "localhost:1636") ldap_hostname = extract_ldap_host(ldap_url) ldaps_port = resolve_ldap_port() with open(src) as f: txt = f.read() with open(dest, "w") as f: rendered_txt = txt % { "ldap_binddn": manager.config.get("ldap_binddn"), "encoded_ox_ldap_pw": manager.secret.get("encoded_ox_ldap_pw"), "ldap_hostname": ldap_hostname, "ldaps_port": ldaps_port, "ldapTrustStoreFn": manager.config.get("ldapTrustStoreFn"), "encoded_ldapTrustStorePass": manager.secret.get( "encoded_ldapTrustStorePass" ), "ssl_enabled": str(as_boolean( os.environ.get("CN_LDAP_USE_SSL", True) )).lower(), } f.write(rendered_txt)
def main(): sync_enabled = as_boolean( os.environ.get("CN_SYNC_JKS_ENABLED", False) ) if not sync_enabled: logger.warning("JKS sync is disabled") return # delay between JKS sync (in seconds) sync_interval = os.environ.get("CN_SYNC_JKS_INTERVAL", 30) try: sync_interval = int(sync_interval) # if value is lower than 1, use default if sync_interval < 1: sync_interval = 30 except ValueError: sync_interval = 30 try: while True: try: if should_sync_jks(): sync_jks() sync_jwks() except Exception as exc: logger.warning(f"Got unhandled error; reason={exc}") # sane interval time.sleep(sync_interval) except KeyboardInterrupt: logger.warning("Canceled by user; exiting ...")
def __init__(self, manager, dry_run, **opts): super().__init__(manager, dry_run, **opts) persistence_type = os.environ.get("CN_PERSISTENCE_TYPE", "ldap") ldap_mapping = os.environ.get("CN_PERSISTENCE_LDAP_MAPPING", "default") if persistence_type in ("ldap", "couchbase", "sql", "spanner"): backend_type = persistence_type else: # persistence_type is hybrid if ldap_mapping == "default": backend_type = "ldap" else: backend_type = "couchbase" # resolve backend self.backend = _backend_classes[backend_type](manager) self.rotation_interval = opts.get("interval", 48) self.push_keys = as_boolean(opts.get("push-to-container", True)) self.key_strategy = opts.get("key-strategy", "OLDER") self.privkey_push_delay = opts.get("privkey-push-delay", 0) self.privkey_push_strategy = opts.get("privkey-push-strategy", "OLDER") self.sig_keys = resolve_sig_keys(opts.get("sig-keys", SIG_KEYS)) self.enc_keys = resolve_enc_keys(opts.get("enc-keys", ENC_KEYS)) metadata = os.environ.get("CN_CONTAINER_METADATA", "docker") if metadata == "kubernetes": self.meta_client = KubernetesMeta() else: self.meta_client = DockerMeta()
def initialize(self): def is_initialized(): persistence_type = os.environ.get("CN_PERSISTENCE_TYPE", "ldap") ldap_mapping = os.environ.get("CN_PERSISTENCE_LDAP_MAPPING", "default") # a minimum service stack is having oxTrust, hence check whether entry # for oxTrust exists in LDAP default_search = ("ou=jans-auth,ou=configuration,o=jans", "(objectClass=jansAppConf)") if persistence_type == "hybrid": # `cache` and `token` mapping only have base entries search_mapping = { "default": default_search, "user": ("inum=60B7,ou=groups,o=jans", "(objectClass=jansGrp)"), "site": ("ou=cache-refresh,o=site", "(ou=people)"), "cache": ("o=jans", "(ou=cache)"), "token": ("ou=tokens,o=jans", "(ou=tokens)"), "session": ("ou=sessions,o=jans", "(ou=sessions)"), } search = search_mapping[ldap_mapping] else: search = default_search return self.client.search(search[0], search[1], attributes=["objectClass"], limit=1) should_skip = as_boolean( os.environ.get("CN_PERSISTENCE_SKIP_INITIALIZED", False), ) if should_skip and is_initialized(): logger.info("LDAP backend already initialized") return self.import_ldif()
def configure_serf(): conf_fn = pathlib.Path("/etc/jans/conf/serf.json") # skip if config exists if conf_fn.is_file(): return advertise = guess_serf_addr() conf = { "node_name": advertise.split(":")[0], "tags": { "role": "ldap", "admin_port": os.environ.get("CN_LDAP_ADVERTISE_ADMIN_PORT", "4444"), "replication_port": os.environ.get("CN_LDAP_ADVERTISE_REPLICATION_PORT", "8989"), "ldaps_port": os.environ.get("CN_LDAP_ADVERTISE_LDAPS_PORT", "1636"), }, "log_level": os.environ.get("CN_SERF_LOG_LEVEL", "warn"), "profile": os.environ.get("CN_SERF_PROFILE", "lan"), "encrypt_key": resolve_serf_key(), "advertise": advertise, } mcast = as_boolean(os.environ.get("CN_SERF_MULTICAST_DISCOVER", False)) if mcast: conf["discover"] = "jans-ldap" conf_fn.write_text(json.dumps(conf))
def resolve_ldap_port() -> int: """Determine port being used based on selected SSL or non-SSL connection.""" use_ssl = as_boolean(os.environ.get("CN_LDAP_USE_SSL", True)) if use_ssl: port = 1636 else: port = 1389 return port
def client(self): """Lazy-loaded client to interact with Kubernetes API. """ if not self._client: if as_boolean( self.settings["CN_CONFIG_KUBERNETES_USE_KUBE_CONFIG"]): kubernetes.config.load_kube_config(self.kubeconfig_file) else: kubernetes.config.load_incluster_config() self._client = kubernetes.client.CoreV1Api() return self._client
def main(): auto_repl = as_boolean(os.environ.get("CN_LDAP_AUTO_REPLICATE", True)) if not auto_repl: logger.warning("Auto replication is disabled; skipping replication check") return server = get_server_info() ldap_user = manager.config.get("ldap_binddn") interval = get_repl_interval() max_retries = get_repl_max_retries() retry = 0 while retry < max_retries: logger.info(f"Checking replicated backends (attempt {retry + 1})") peers = peers_from_serf_membership() for peer in peers: if peer["name"] == server["name"]: continue datasources = get_datasources(ldap_user, interval) # if there's no backend that need to be replicated, skip the rest of the process; # note, in some cases the Generation ID will be different due to mismatched data structure # to fix this issue we can re-init replication manually; please refer to # https://backstage.forgerock.com/knowledge/kb/article/a36616593 for details if not datasources: logger.info("All required backends have been replicated") return logger.info(f"Found peer at {peer['name']}") for dn, _ in datasources.items(): _, err, code = check_required_entry( peer["name"], peer["tags"]["ldaps_port"], ldap_user, dn, ) if code != 0: logger.warning( f"Unable to get required entry at LDAP server {peer['name']}; reason={err.decode()}" ) continue # replicate from server that has data; note: can't assume the # whole replication process is succeed, hence subsequence checks # will be executed replicate_from(peer, server, dn) # delay between next check time.sleep(interval) retry += 1
def wait_for_config(manager, **kwargs): """Wait for readiness/availability of config backend. If ``conn_only`` keyword argument is set to ``True``, this function only checks its connection status; if set to ``False`` or omitted, this function will check config entry. :param manager: An instance of :class:`~jans.pycloudlib.manager._Manager`. """ conn_only = as_boolean(kwargs.get("conn_only", False)) hostname = manager.config.get("hostname") if not conn_only and not hostname: raise WaitError("Config 'hostname' is not available")
def wait_for_secret(manager, **kwargs): """Wait for readiness/availability of secret backend. If ``conn_only`` keyword argument is set to ``True``, this function only checks its connection status; if set to ``False`` or omitted, this function will check config entry. :param manager: An instance of :class:`~jans.pycloudlib.manager._Manager`. """ conn_only = as_boolean(kwargs.get("conn_only", False)) ssl_cert = manager.secret.get("ssl_cert") if not conn_only and not ssl_cert: raise WaitError("Secret 'ssl_cert' is not available")
def wait_for_oxd(manager, **kwargs): """Wait for readiness/availability of oxd server. This function makes a request to specific URL in oxd. :param manager: An instance of :class:`~jans.pycloudlib.manager._Manager`. """ import urllib3 urllib3.disable_warnings() addr = os.environ.get("CN_OXD_SERVER_URL", "localhost:8443") verify = as_boolean(os.environ.get("CN_OXD_SERVER_VERIFY", False)) url = f"https://{addr}/health-check" req = requests.get(url, verify=verify) if not req.ok: raise WaitError(req.reason)
def load(generate_file, config_file, secret_file): """Loads config and secret from JSON files (generate if not exist). """ deps = ["config_conn", "secret_conn"] wait_for(manager, deps=deps) # check whether config and secret in backend have been initialized should_skip = as_boolean( os.environ.get("CN_CONFIGURATION_SKIP_INITIALIZED", False)) if should_skip and manager.config.get("hostname") and manager.secret.get( "ssl_cert"): # config and secret may have been initialized logger.info("Config and secret have been initialized") return # there's no config and secret in backend, check whether to load from files if os.path.isfile(config_file) and os.path.isfile(secret_file): # load from existing files logger.info( f"Re-using config and secret from {config_file} and {secret_file}") _load_from_file(manager, config_file, "config") _load_from_file(manager, secret_file, "secret") return # no existing files, hence generate new config and secret from parameters logger.info(f"Loading parameters from {generate_file}") params, err, code = params_from_file(generate_file) if code != 0: logger.error(f"Unable to load parameters; reason={err}") raise click.Abort() logger.info("Generating new config and secret") ctx_generator = CtxGenerator(manager, params) ctx = ctx_generator.generate() # save config to its backend and file _save_generated_ctx(manager, ctx["config"], "config") _dump_to_file(manager, config_file, "config") # save secret to its backend and file _save_generated_ctx(manager, ctx["secret"], "secret") _dump_to_file(manager, secret_file, "secret")
def main(): manager = get_manager() for addr in peers_from_file(): register_serf_peer(manager, addr) addr = guess_serf_addr() register_serf_peer(manager, addr) mcast = as_boolean(os.environ.get("CN_SERF_MULTICAST_DISCOVER", False)) if mcast: # join Serf cluster using multicast (no extra code needed) return # join Serf cluster manually peers = " ".join(get_serf_peers(manager)) out, err, code = exec_cmd(f"serf join {peers}") err = err or out if code != 0: logger.warning(f"Unable to join Serf cluster; reason={err}")
def __init__(self, manager, host="", user="", password=""): """ Initialize instance. :params manager: An instance of :class:`~pygluu.containerlib.manager._Manager`. """ host = host or os.environ.get("CN_LDAP_URL", "localhost:1636") # we only need host part as port will be resolved from env that controls # SSL or non-SSL connetion host = extract_ldap_host(host) user = user or manager.config.get("ldap_binddn") password = password or decode_text( manager.secret.get("encoded_ox_ldap_pw"), manager.secret.get("encoded_salt") ) use_ssl = as_boolean(os.environ.get("CN_LDAP_USE_SSL", True)) port = resolve_ldap_port() self.server = Server(host, port=port, use_ssl=use_ssl) self.conn = Connection(self.server, user, password)
def _verify_cert(self, scheme, verify, cacert_file, cert_file, key_file) -> Tuple[Union[None, tuple], Union[bool, str]]: """Verify client cert and key. :params scheme: Scheme of Consul address. :params verify: Mark whether client needs to verify the address. :params cacert_file: Path to CA cert file. :params cert_file: Path to client's cert file. :params key_file: Path to client's key file. :returns: A pair of cert key files (if exist) and verification. """ cert = None if scheme == "https": verify = as_boolean(verify) # verify using CA cert (if any) if all([verify, os.path.isfile(cacert_file)]): verify = cacert_file if all([os.path.isfile(cert_file), os.path.isfile(key_file)]): cert = (cert_file, key_file) return cert, verify
def scheme(self): """Scheme used when connecting to Couchbase server. """ if as_boolean(os.environ.get("CN_COUCHBASE_TRUSTSTORE_ENABLE", True)): return "https" return "http"
def get_base_ctx(manager): redis_pw = manager.secret.get("redis_pw") or "" redis_pw_encoded = "" if redis_pw: redis_pw_encoded = encode_text( redis_pw, manager.secret.get("encoded_salt"), ).decode() doc_store_type = os.environ.get("CN_DOCUMENT_STORE_TYPE", "LOCAL") jca_user, jca_pw = get_jackrabbit_creds() jca_pw_encoded = encode_text( jca_pw, manager.secret.get("encoded_salt"), ).decode() cache_type = os.environ.get("CN_CACHE_TYPE", "NATIVE_PERSISTENCE") redis_url = os.environ.get('CN_REDIS_URL', 'localhost:6379') redis_type = os.environ.get('CN_REDIS_TYPE', 'STANDALONE') redis_use_ssl = os.environ.get("CN_REDIS_USE_SSL", False) redis_ssl_truststore = os.environ.get("CN_REDIS_SSL_TRUSTSTORE", "") redis_sentinel_group = os.environ.get("CN_REDIS_SENTINEL_GROUP", "") memcached_url = os.environ.get('CN_MEMCACHED_URL', 'localhost:11211') oxtrust_config_generation = os.environ.get("CN_OXTRUST_CONFIG_GENERATION", True) passport_enabled = os.environ.get("CN_PASSPORT_ENABLED", False) radius_enabled = os.environ.get("CN_RADIUS_ENABLED", False) casa_enabled = os.environ.get("CN_CASA_ENABLED", False) saml_enabled = os.environ.get("CN_SAML_ENABLED", False) scim_enabled = os.environ.get("CN_SCIM_ENABLED", False) ctx = { 'cache_provider_type': cache_type, 'redis_url': redis_url, 'redis_type': redis_type, 'redis_pw': redis_pw, 'redis_pw_encoded': redis_pw_encoded, "redis_use_ssl": "{}".format(as_boolean(redis_use_ssl)).lower(), "redis_ssl_truststore": redis_ssl_truststore, "redis_sentinel_group": redis_sentinel_group, 'memcached_url': memcached_url, "document_store_type": doc_store_type, "jca_server_url": get_jackrabbit_rmi_url(), "jca_username": jca_user, "jca_pw": jca_pw, "jca_pw_encoded": jca_pw_encoded, 'ldap_hostname': manager.config.get('ldap_init_host'), 'ldaps_port': manager.config.get('ldap_init_port'), 'ldap_binddn': manager.config.get('ldap_binddn'), "ldap_use_ssl": str(as_boolean(os.environ.get("CN_LDAP_USE_SSL", True))).lower(), 'encoded_ox_ldap_pw': manager.secret.get('encoded_ox_ldap_pw'), 'jetty_base': manager.config.get('jetty_base'), 'orgName': manager.config.get('orgName'), 'hostname': manager.config.get('hostname'), 'idp_client_id': manager.config.get('idp_client_id'), 'idpClient_encoded_pw': manager.secret.get('idpClient_encoded_pw'), 'auth_openid_key_base64': manager.secret.get('auth_openid_key_base64'), # 'passport_rs_client_id': manager.config.get('passport_rs_client_id'), # 'passport_rs_client_base64_jwks': manager.secret.get('passport_rs_client_base64_jwks'), # 'passport_rs_client_cert_alias': manager.config.get('passport_rs_client_cert_alias'), # 'passport_rp_client_id': manager.config.get('passport_rp_client_id'), # 'passport_rp_client_base64_jwks': manager.secret.get('passport_rp_client_base64_jwks'), # "passport_rp_client_jks_fn": manager.config.get("passport_rp_client_jks_fn"), # "passport_rp_client_jks_pass": manager.secret.get("passport_rp_client_jks_pass"), # "encoded_ldap_pw": manager.secret.get('encoded_ldap_pw'), "encoded_admin_password": manager.secret.get('encoded_admin_password'), # 'passport_rp_ii_client_id': manager.config.get("passport_rp_ii_client_id"), 'admin_email': manager.config.get('admin_email'), 'shibJksFn': manager.config.get('shibJksFn'), 'shibJksPass': manager.secret.get('shibJksPass'), 'oxTrustConfigGeneration': str(as_boolean(oxtrust_config_generation)).lower(), 'encoded_shib_jks_pw': manager.secret.get('encoded_shib_jks_pw'), 'passport_rs_client_jks_fn': manager.config.get('passport_rs_client_jks_fn'), 'passport_rs_client_jks_pass_encoded': manager.secret.get('passport_rs_client_jks_pass_encoded'), 'shibboleth_version': manager.config.get('shibboleth_version'), 'idp3Folder': manager.config.get('idp3Folder'), 'ldap_site_binddn': manager.config.get('ldap_site_binddn'), "passport_resource_id": manager.config.get("passport_resource_id"), "gluu_radius_client_id": manager.config.get("gluu_radius_client_id"), "gluu_ro_encoded_pw": manager.secret.get("gluu_ro_encoded_pw"), # "super_gluu_ro_session_script": manager.config.get("super_gluu_ro_session_script"), # "super_gluu_ro_script": manager.config.get("super_gluu_ro_script"), # "enableRadiusScripts": "false", # @TODO: enable it? # "gluu_ro_client_base64_jwks": manager.secret.get("gluu_ro_client_base64_jwks"), "jansPassportEnabled": str(as_boolean(passport_enabled)).lower(), "jansRadiusEnabled": str(as_boolean(radius_enabled)).lower(), "jansSamlEnabled": str(as_boolean(saml_enabled)).lower(), "jansScimEnabled": str(as_boolean(scim_enabled)).lower(), "pairwiseCalculationKey": manager.secret.get("pairwiseCalculationKey"), "pairwiseCalculationSalt": manager.secret.get("pairwiseCalculationSalt"), "default_openid_jks_dn_name": manager.config.get("default_openid_jks_dn_name"), "auth_openid_jks_pass": manager.secret.get("auth_openid_jks_pass"), "auth_legacyIdTokenClaims": manager.config.get("auth_legacyIdTokenClaims"), "passportSpTLSCert": manager.config.get("passportSpTLSCert"), "passportSpTLSKey": manager.config.get("passportSpTLSKey"), "auth_openidScopeBackwardCompatibility": manager.config.get("auth_openidScopeBackwardCompatibility"), "fido2ConfigFolder": manager.config.get("fido2ConfigFolder"), "admin_inum": manager.config.get("admin_inum"), "enable_scim_access_policy": str(as_boolean(scim_enabled) or as_boolean(passport_enabled)).lower(), "scim_client_id": manager.config.get("scim_client_id"), "scim_client_encoded_pw": manager.secret.get("scim_client_encoded_pw"), "casa_enable_script": str(as_boolean(casa_enabled)).lower(), # "oxd_hostname": "localhost", # "oxd_port": "8443", "jca_client_id": manager.config.get("jca_client_id"), "jca_client_encoded_pw": manager.secret.get("jca_client_encoded_pw"), } # JWKS URI jwks_uri = f"https://{ctx['hostname']}/jans-auth/restv1/jwks" auth_openid_jks_fn = manager.config.get("auth_openid_jks_fn") ext_jwks_uri = os.environ.get("CN_OB_EXT_SIGNING_JWKS_URI", "") if ext_jwks_uri: jwks_uri = ext_jwks_uri auth_openid_jks_fn = "/etc/certs/ob-ext-signing.jks" ctx["jwks_uri"] = jwks_uri ctx["auth_openid_jks_fn"] = auth_openid_jks_fn # static kid ctx["staticKid"] = os.environ.get("CN_OB_STATIC_KID", "") # admin-ui plugins ctx["admin_ui_client_id"] = manager.config.get("admin_ui_client_id") if not ctx["admin_ui_client_id"]: ctx["admin_ui_client_id"] = f"1901.{uuid4()}" manager.config.set("admin_ui_client_id", ctx["admin_ui_client_id"]) ctx["admin_ui_client_pw"] = manager.secret.get("admin_ui_client_pw") if not ctx["admin_ui_client_pw"]: ctx["admin_ui_client_pw"] = get_random_chars() manager.secret.set("admin_ui_client_pw", ctx["admin_ui_client_pw"]) ctx["admin_ui_client_encoded_pw"] = manager.secret.get( "admin_ui_client_encoded_pw") if not ctx["admin_ui_client_encoded_pw"]: ctx["admin_ui_client_encoded_pw"] = encode_text( ctx["admin_ui_client_pw"], manager.secret.get("encoded_salt")).decode() manager.secret.set( "admin_ui_client_encoded_pw", ctx["admin_ui_client_encoded_pw"], ) # token server client ctx["token_server_admin_ui_client_id"] = manager.config.get( "token_server_admin_ui_client_id") if not ctx["token_server_admin_ui_client_id"]: ctx["token_server_admin_ui_client_id"] = f"1901.{uuid4()}" manager.config.set("token_server_admin_ui_client_id", ctx["token_server_admin_ui_client_id"]) ctx["token_server_admin_ui_client_pw"] = manager.secret.get( "token_server_admin_ui_client_pw") if not ctx["token_server_admin_ui_client_pw"]: ctx["token_server_admin_ui_client_pw"] = get_random_chars() manager.secret.set("token_server_admin_ui_client_pw", ctx["token_server_admin_ui_client_pw"]) ctx["token_server_admin_ui_client_encoded_pw"] = manager.secret.get( "token_server_admin_ui_client_encoded_pw") if not ctx["token_server_admin_ui_client_encoded_pw"]: ctx["token_server_admin_ui_client_encoded_pw"] = encode_text( ctx["token_server_admin_ui_client_pw"], manager.secret.get("encoded_salt"), ).decode() manager.secret.set( "token_server_admin_ui_client_encoded_pw", ctx["token_server_admin_ui_client_encoded_pw"], ) # finalize ctx return ctx
def test_as_boolean(val, expected): from jans.pycloudlib.utils import as_boolean assert as_boolean(val) == expected
def suppress_verification_warning(): import urllib3 if as_boolean(os.environ.get("CN_COUCHBASE_SUPPRESS_VERIFICATION", True)): urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
def port(self): """Port where REST server is bind to. """ if as_boolean(os.environ.get("CN_COUCHBASE_TRUSTSTORE_ENABLE", True)): return 18091 return 8091
def render_couchbase_properties(manager, src: str, dest: str) -> None: """Render file contains properties to connect to Couchbase server, i.e. ``/etc/jans/conf/jans-couchbase.properties``. :params manager: An instance of :class:`~jans.pycloudlib.manager._Manager`. :params src: Absolute path to the template. :params dest: Absolute path where generated file is located. """ persistence_type = os.environ.get("CN_PERSISTENCE_TYPE", "couchbase") ldap_mapping = os.environ.get("CN_PERSISTENCE_LDAP_MAPPING", "default") hostname = os.environ.get("CN_COUCHBASE_URL", "localhost") bucket_prefix = os.environ.get("CN_COUCHBASE_BUCKET_PREFIX", "jans") _couchbase_mappings = get_couchbase_mappings(persistence_type, ldap_mapping) couchbase_buckets = [] couchbase_mappings = [] for _, mapping in _couchbase_mappings.items(): couchbase_buckets.append(mapping["bucket"]) if not mapping["mapping"]: continue couchbase_mappings.append( f"bucket.{mapping['bucket']}.mapping: {mapping['mapping']}" ) # always have _default_ bucket if bucket_prefix not in couchbase_buckets: couchbase_buckets.insert(0, bucket_prefix) with open(src) as fr: txt = fr.read() with open(dest, "w") as fw: rendered_txt = txt % { "hostname": hostname, "couchbase_server_user": get_couchbase_user(manager), "encoded_couchbase_server_pw": encode_text( get_couchbase_password(manager), manager.secret.get("encoded_salt"), ).decode(), "couchbase_buckets": ", ".join(couchbase_buckets), "default_bucket": bucket_prefix, "couchbase_mappings": "\n".join(couchbase_mappings), "encryption_method": "SSHA-256", "ssl_enabled": str(as_boolean( os.environ.get("CN_COUCHBASE_TRUSTSTORE_ENABLE", True) )).lower(), "couchbaseTrustStoreFn": manager.config.get("couchbaseTrustStoreFn") or "/etc/certs/couchbase.pkcs12", "encoded_couchbaseTrustStorePass": encode_text( CN_COUCHBASE_TRUSTSTORE_PASSWORD, manager.secret.get("encoded_salt"), ).decode(), "couchbase_conn_timeout": get_couchbase_conn_timeout(), "couchbase_conn_max_wait": get_couchbase_conn_max_wait(), "couchbase_scan_consistency": get_couchbase_scan_consistency(), "couchbase_keepalive_interval": get_couchbase_keepalive_interval(), "couchbase_keepalive_timeout": get_couchbase_keepalive_timeout(), } fw.write(rendered_txt)