blob: 803d56460a784d19e58677cdffb0edac653ef627 [file] [log] [blame]
#!/usr/bin/env python3
# Copyright 2021 Canonical Ltd.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
# For those usages not covered by the Apache License, Version 2.0 please
# contact: legal@canonical.com
#
# To get in touch with the maintainers, please contact:
# osm-charmers@lists.launchpad.net
#
#
# This file populates the Actions tab on Charmhub.
# See https://juju.is/docs/some-url-to-be-determined/ for a checklist and guidance.
"""Module that takes take of the charm configuration."""
import re
from typing import Any, Dict, Optional
from config_validator import ConfigValidator, ValidationError
from ops.model import ConfigData
class MysqlConnectionData:
"""Mysql Connection Data class."""
_compiled_regex = re.compile(
r"^mysql\:\/\/{}@{}\/{}?$".format(
r"(?P<username>[_\w]+):(?P<password>[\w\W]+)",
r"(?P<host>[\-\.\w]+):(?P<port>\d+)",
r"(?P<database>[_\w]+)",
)
)
def __init__(self, mysql_uri: str):
match = self._compiled_regex.search(mysql_uri)
if not match:
raise ValidationError("mysql_uri is not properly formed")
mysql_data = match.groupdict()
self.host = mysql_data.get("host")
self.port = int(mysql_data.get("port"))
self.username = mysql_data.get("username")
self.password = mysql_data.get("password")
self.database = mysql_data.get("database")
self.uri = mysql_uri
def validate_config(config: ConfigData):
"""Validate charm configuration.
Args:
config (ConfigData): Charm configuration.
Raises:
config_validator.ValidationError if the validation failed.
"""
kwargs: Dict[str, Any] = config
ConfigModel(**kwargs)
ConfigLdapModel(**kwargs)
def get_environment(
service_name: str, config: ConfigData, mysql_data: MysqlConnectionData
) -> Dict[str, Any]:
"""Get environment variables.
Args:
service_name (str): Cluster IP service name.
config (ConfigData): Charm configuration.
Returns:
Dict[str, Any]: Dictionary with the environment variables for Keystone service.
"""
kwargs: Dict[str, Any] = config
config = ConfigModel(**kwargs)
config_ldap = ConfigLdapModel(**kwargs)
environment = {
"DB_HOST": mysql_data.host,
"DB_PORT": mysql_data.port,
"ROOT_DB_USER": mysql_data.username,
"ROOT_DB_PASSWORD": mysql_data.password,
"REGION_ID": config.region_id,
"KEYSTONE_HOST": service_name,
"KEYSTONE_DB_PASSWORD": config.keystone_db_password,
"ADMIN_USERNAME": config.admin_username,
"ADMIN_PASSWORD": config.admin_password,
"ADMIN_PROJECT": config.admin_project,
"SERVICE_USERNAME": config.service_username,
"SERVICE_PASSWORD": config.service_password,
"SERVICE_PROJECT": config.service_project,
}
if config_ldap.ldap_enabled:
environment.update(
{
"LDAP_AUTHENTICATION_DOMAIN_NAME": config_ldap.ldap_authentication_domain_name,
"LDAP_URL": config_ldap.ldap_url,
"LDAP_PAGE_SIZE": str(config_ldap.ldap_page_size),
"LDAP_USER_OBJECTCLASS": config_ldap.ldap_user_objectclass,
"LDAP_USER_ID_ATTRIBUTE": config_ldap.ldap_user_id_attribute,
"LDAP_USER_NAME_ATTRIBUTE": config_ldap.ldap_user_name_attribute,
"LDAP_USER_PASS_ATTRIBUTE": config_ldap.ldap_user_pass_attribute,
"LDAP_USER_ENABLED_MASK": str(config_ldap.ldap_user_enabled_mask),
"LDAP_USER_ENABLED_DEFAULT": config_ldap.ldap_user_enabled_default,
"LDAP_USER_ENABLED_INVERT": str(config_ldap.ldap_user_enabled_invert),
"LDAP_GROUP_OBJECTCLASS": config_ldap.ldap_group_objectclass,
}
)
if config_ldap.ldap_use_starttls:
environment.update(
{
"LDAP_USE_STARTTLS": str(config_ldap.ldap_use_starttls),
"LDAP_TLS_CACERT_BASE64": config_ldap.ldap_tls_cacert_base64,
"LDAP_TLS_REQ_CERT": config_ldap.ldap_tls_req_cert,
}
)
optional_ldap_configs = {
"LDAP_BIND_USER": config_ldap.ldap_bind_user,
"LDAP_BIND_PASSWORD": config_ldap.ldap_bind_password,
"LDAP_USER_TREE_DN": config_ldap.ldap_user_tree_dn,
"LDAP_USER_FILTER": config_ldap.ldap_user_filter,
"LDAP_USER_ENABLED_ATTRIBUTE": config_ldap.ldap_user_enabled_attribute,
"LDAP_CHASE_REFERRALS": config_ldap.ldap_chase_referrals,
"LDAP_GROUP_TREE_DN": config_ldap.ldap_group_tree_dn,
"LDAP_TLS_CACERT_BASE64": config_ldap.ldap_tls_cacert_base64,
}
for env, value in optional_ldap_configs.items():
if value:
environment[env] = value
return environment
class ConfigModel(ConfigValidator):
"""Keystone Configuration."""
region_id: str
keystone_db_password: str
admin_username: str
admin_password: str
admin_project: str
service_username: str
service_password: str
service_project: str
user_domain_name: str
project_domain_name: str
token_expiration: int
mysql_uri: Optional[str]
class ConfigLdapModel(ConfigValidator):
"""LDAP Configuration."""
ldap_enabled: bool
ldap_authentication_domain_name: Optional[str]
ldap_url: Optional[str]
ldap_bind_user: Optional[str]
ldap_bind_password: Optional[str]
ldap_chase_referrals: Optional[str]
ldap_page_size: Optional[int]
ldap_user_tree_dn: Optional[str]
ldap_user_objectclass: Optional[str]
ldap_user_id_attribute: Optional[str]
ldap_user_name_attribute: Optional[str]
ldap_user_pass_attribute: Optional[str]
ldap_user_filter: Optional[str]
ldap_user_enabled_attribute: Optional[str]
ldap_user_enabled_mask: Optional[int]
ldap_user_enabled_default: Optional[str]
ldap_user_enabled_invert: Optional[bool]
ldap_group_objectclass: Optional[str]
ldap_group_tree_dn: Optional[str]
ldap_use_starttls: Optional[bool]
ldap_tls_cacert_base64: Optional[str]
ldap_tls_req_cert: Optional[str]