kolla-ansible/kolla_ansible/database_shards.py
Michal Arbet de973b81fa Add proxysql support for database
Kolla environment currently uses haproxy
to fullfill HA in mariadb. This patch
is switching haproxy to proxysql if enabled.

This patch is also replacing mariadb's user
'haproxy' with user 'monitor'. This replacement
has two reasons:
  - Use better name to "monitor" galera claster
    as there are two services using this user
    (HAProxy, ProxySQL)
  - Set password for monitor user as it's
    always better to use password then not use.
    Previous haproxy user didn't use password
    as it was historically not possible with
    haproxy and mariadb-clustercheck wasn't
    implemented.

Depends-On: https://review.opendev.org/c/openstack/kolla/+/769385
Depends-On: https://review.opendev.org/c/openstack/kolla/+/765781
Depends-On: https://review.opendev.org/c/openstack/kolla/+/850656

Change-Id: I0edae33d982c2e3f3b5f34b3d5ad07a431162844
2022-07-29 15:05:21 +02:00

131 lines
4.5 KiB
Python

# -*- coding: utf-8 -*-
#
# Copyright 2022 Michal Arbet (kevko)
#
# 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.
from jinja2.filters import pass_context
from jinja2.runtime import Undefined
from kolla_ansible.exception import FilterError
from kolla_ansible.helpers import _call_bool_filter
@pass_context
def database_shards_info(context, hostnames):
"""returns dict with database shards info
Returned dict looks as example below:
"database_shards_info": {
"shards": {
"0": {
"hosts": [
"controller0",
"controller1",
"controller2"
]
},
"1": {
"hosts": [
"controller3",
"controller4",
"controller5"
]
}
},
"users": [
{
"password": "secret",
"shard_id": "0",
"user": "root_shard_0"
},
{
"password": "secret",
"shard_id": "0",
"user": "backup_shard_0"
},
{
"password": "secret",
"shard_id": "1",
"user": "root_shard_1"
},
{
"password": "secret",
"shard_id": "1",
"user": "backup_shard_1"
}
]
}
:param context: Jinja2 Context
:param hostnames: List of database hosts
:returns: Dict with database shards info
"""
hostvars = context.get('hostvars')
if isinstance(hostvars, Undefined):
raise FilterError("'hostvars' variable is unavailable")
shards_info = {'shards': {}, 'users': []}
for hostname in hostnames:
host = hostvars.get(hostname)
if isinstance(host, Undefined):
raise FilterError(f"'{hostname}' not in 'hostvars'")
host_shard_id = host.get('mariadb_shard_id')
if host_shard_id is None:
raise FilterError(f"'mariadb_shard_id' is undefined "
"for host '{hostname}'")
else:
host_shard_id = str(host_shard_id)
if host_shard_id not in shards_info['shards']:
shards_info['shards'][host_shard_id] = {'hosts': [hostname]}
backup_enabled = host.get('enable_mariabackup')
if backup_enabled is None:
raise FilterError("'enable_mariabackup' variable is "
"unavailable")
backup_enabled = _call_bool_filter(context, backup_enabled)
db_password = host.get('database_password')
if db_password is None:
raise FilterError("'database_password' variable is "
"unavailable")
db_root_prefix = host.get('mariadb_shard_root_user_prefix')
if db_root_prefix is None:
raise FilterError("'mariadb_shard_root_user_prefix' variable "
"is unavailable")
db_user = f"{db_root_prefix}{host_shard_id}"
user_dict = {'password': db_password, 'user': db_user,
'shard_id': host_shard_id}
shards_info['users'].append(user_dict)
if backup_enabled:
db_backup_prefix = host.get('mariadb_shard_backup_user_prefix')
if db_backup_prefix is None:
raise FilterError("'mariadb_shard_backup_user_prefix' "
"variable is unavailable")
db_user = f"{db_backup_prefix}{host_shard_id}"
user_dict = {'password': db_password, 'user': db_user,
'shard_id': host_shard_id}
shards_info['users'].append(user_dict)
else:
shards_info['shards'][host_shard_id]['hosts'].append(hostname)
return shards_info