| Patricia Reinoso | d5b463c | 2023-05-31 08:37:18 +0000 | [diff] [blame] | 1 | #!/usr/bin/env python3 |
| 2 | # Copyright 2021 Canonical Ltd. |
| 3 | # |
| 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may |
| 5 | # not use this file except in compliance with the License. You may obtain |
| 6 | # a copy of the License at |
| 7 | # |
| 8 | # http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | # |
| 10 | # Unless required by applicable law or agreed to in writing, software |
| 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| 13 | # License for the specific language governing permissions and limitations |
| 14 | # under the License. |
| 15 | # |
| 16 | # For those usages not covered by the Apache License, Version 2.0 please |
| 17 | # contact: legal@canonical.com |
| 18 | # |
| 19 | # To get in touch with the maintainers, please contact: |
| 20 | # osm-charmers@lists.launchpad.net |
| 21 | # |
| 22 | # |
| 23 | # This file populates the Actions tab on Charmhub. |
| 24 | # See https://juju.is/docs/some-url-to-be-determined/ for a checklist and guidance. |
| 25 | |
| 26 | """Module that takes take of the charm configuration.""" |
| 27 | |
| 28 | import re |
| 29 | from typing import Any, Dict, Optional |
| 30 | |
| 31 | from config_validator import ConfigValidator, ValidationError |
| 32 | from ops.model import ConfigData |
| 33 | |
| 34 | |
| 35 | class MysqlConnectionData: |
| 36 | """Mysql Connection Data class.""" |
| 37 | |
| 38 | _compiled_regex = re.compile( |
| 39 | r"^mysql\:\/\/{}@{}\/{}?$".format( |
| 40 | r"(?P<username>[_\w]+):(?P<password>[\w\W]+)", |
| 41 | r"(?P<host>[\-\.\w]+):(?P<port>\d+)", |
| 42 | r"(?P<database>[_\w]+)", |
| 43 | ) |
| 44 | ) |
| 45 | |
| 46 | def __init__(self, mysql_uri: str): |
| 47 | match = self._compiled_regex.search(mysql_uri) |
| 48 | if not match: |
| 49 | raise ValidationError("mysql_uri is not properly formed") |
| 50 | mysql_data = match.groupdict() |
| 51 | self.host = mysql_data.get("host") |
| 52 | self.port = int(mysql_data.get("port")) |
| 53 | self.username = mysql_data.get("username") |
| 54 | self.password = mysql_data.get("password") |
| 55 | self.database = mysql_data.get("database") |
| 56 | self.uri = mysql_uri |
| 57 | |
| 58 | |
| 59 | def validate_config(config: ConfigData): |
| 60 | """Validate charm configuration. |
| 61 | |
| 62 | Args: |
| 63 | config (ConfigData): Charm configuration. |
| 64 | |
| 65 | Raises: |
| 66 | config_validator.ValidationError if the validation failed. |
| 67 | """ |
| 68 | kwargs: Dict[str, Any] = config |
| 69 | ConfigModel(**kwargs) |
| 70 | ConfigLdapModel(**kwargs) |
| 71 | |
| 72 | |
| 73 | def get_environment( |
| 74 | service_name: str, config: ConfigData, mysql_data: MysqlConnectionData |
| 75 | ) -> Dict[str, Any]: |
| 76 | """Get environment variables. |
| 77 | |
| 78 | Args: |
| 79 | service_name (str): Cluster IP service name. |
| 80 | config (ConfigData): Charm configuration. |
| 81 | |
| 82 | Returns: |
| 83 | Dict[str, Any]: Dictionary with the environment variables for Keystone service. |
| 84 | """ |
| 85 | kwargs: Dict[str, Any] = config |
| 86 | config = ConfigModel(**kwargs) |
| 87 | config_ldap = ConfigLdapModel(**kwargs) |
| 88 | environment = { |
| 89 | "DB_HOST": mysql_data.host, |
| 90 | "DB_PORT": mysql_data.port, |
| 91 | "ROOT_DB_USER": mysql_data.username, |
| 92 | "ROOT_DB_PASSWORD": mysql_data.password, |
| 93 | "REGION_ID": config.region_id, |
| 94 | "KEYSTONE_HOST": service_name, |
| 95 | "KEYSTONE_DB_PASSWORD": config.keystone_db_password, |
| 96 | "ADMIN_USERNAME": config.admin_username, |
| 97 | "ADMIN_PASSWORD": config.admin_password, |
| 98 | "ADMIN_PROJECT": config.admin_project, |
| 99 | "SERVICE_USERNAME": config.service_username, |
| 100 | "SERVICE_PASSWORD": config.service_password, |
| 101 | "SERVICE_PROJECT": config.service_project, |
| 102 | } |
| 103 | if config_ldap.ldap_enabled: |
| 104 | environment.update( |
| 105 | { |
| 106 | "LDAP_AUTHENTICATION_DOMAIN_NAME": config_ldap.ldap_authentication_domain_name, |
| 107 | "LDAP_URL": config_ldap.ldap_url, |
| 108 | "LDAP_PAGE_SIZE": str(config_ldap.ldap_page_size), |
| 109 | "LDAP_USER_OBJECTCLASS": config_ldap.ldap_user_objectclass, |
| 110 | "LDAP_USER_ID_ATTRIBUTE": config_ldap.ldap_user_id_attribute, |
| 111 | "LDAP_USER_NAME_ATTRIBUTE": config_ldap.ldap_user_name_attribute, |
| 112 | "LDAP_USER_PASS_ATTRIBUTE": config_ldap.ldap_user_pass_attribute, |
| 113 | "LDAP_USER_ENABLED_MASK": str(config_ldap.ldap_user_enabled_mask), |
| 114 | "LDAP_USER_ENABLED_DEFAULT": config_ldap.ldap_user_enabled_default, |
| 115 | "LDAP_USER_ENABLED_INVERT": str(config_ldap.ldap_user_enabled_invert), |
| 116 | "LDAP_GROUP_OBJECTCLASS": config_ldap.ldap_group_objectclass, |
| 117 | } |
| 118 | ) |
| 119 | if config_ldap.ldap_use_starttls: |
| 120 | environment.update( |
| 121 | { |
| 122 | "LDAP_USE_STARTTLS": str(config_ldap.ldap_use_starttls), |
| 123 | "LDAP_TLS_CACERT_BASE64": config_ldap.ldap_tls_cacert_base64, |
| 124 | "LDAP_TLS_REQ_CERT": config_ldap.ldap_tls_req_cert, |
| 125 | } |
| 126 | ) |
| 127 | optional_ldap_configs = { |
| 128 | "LDAP_BIND_USER": config_ldap.ldap_bind_user, |
| 129 | "LDAP_BIND_PASSWORD": config_ldap.ldap_bind_password, |
| 130 | "LDAP_USER_TREE_DN": config_ldap.ldap_user_tree_dn, |
| 131 | "LDAP_USER_FILTER": config_ldap.ldap_user_filter, |
| 132 | "LDAP_USER_ENABLED_ATTRIBUTE": config_ldap.ldap_user_enabled_attribute, |
| 133 | "LDAP_CHASE_REFERRALS": config_ldap.ldap_chase_referrals, |
| 134 | "LDAP_GROUP_TREE_DN": config_ldap.ldap_group_tree_dn, |
| 135 | "LDAP_TLS_CACERT_BASE64": config_ldap.ldap_tls_cacert_base64, |
| 136 | } |
| 137 | for env, value in optional_ldap_configs.items(): |
| 138 | if value: |
| 139 | environment[env] = value |
| 140 | return environment |
| 141 | |
| 142 | |
| 143 | class ConfigModel(ConfigValidator): |
| 144 | """Keystone Configuration.""" |
| 145 | |
| 146 | region_id: str |
| 147 | keystone_db_password: str |
| 148 | admin_username: str |
| 149 | admin_password: str |
| 150 | admin_project: str |
| 151 | service_username: str |
| 152 | service_password: str |
| 153 | service_project: str |
| 154 | user_domain_name: str |
| 155 | project_domain_name: str |
| 156 | token_expiration: int |
| 157 | mysql_uri: Optional[str] |
| 158 | |
| 159 | |
| 160 | class ConfigLdapModel(ConfigValidator): |
| 161 | """LDAP Configuration.""" |
| 162 | |
| 163 | ldap_enabled: bool |
| 164 | ldap_authentication_domain_name: Optional[str] |
| 165 | ldap_url: Optional[str] |
| 166 | ldap_bind_user: Optional[str] |
| 167 | ldap_bind_password: Optional[str] |
| 168 | ldap_chase_referrals: Optional[str] |
| 169 | ldap_page_size: Optional[int] |
| 170 | ldap_user_tree_dn: Optional[str] |
| 171 | ldap_user_objectclass: Optional[str] |
| 172 | ldap_user_id_attribute: Optional[str] |
| 173 | ldap_user_name_attribute: Optional[str] |
| 174 | ldap_user_pass_attribute: Optional[str] |
| 175 | ldap_user_filter: Optional[str] |
| 176 | ldap_user_enabled_attribute: Optional[str] |
| 177 | ldap_user_enabled_mask: Optional[int] |
| 178 | ldap_user_enabled_default: Optional[str] |
| 179 | ldap_user_enabled_invert: Optional[bool] |
| 180 | ldap_group_objectclass: Optional[str] |
| 181 | ldap_group_tree_dn: Optional[str] |
| 182 | ldap_use_starttls: Optional[bool] |
| 183 | ldap_tls_cacert_base64: Optional[str] |
| 184 | ldap_tls_req_cert: Optional[str] |