Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions internal/mariadb/volumes.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ func getGaleraVolumes(g *mariadbv1.Galera) []corev1.Volume {
Key: "galera.cnf.in",
Path: "galera.cnf.in",
},
{
Key: "mysql_pw_cache.cnf.in",
Path: "mysql_pw_cache.cnf.in",
},
{
Key: mariadbv1.CustomServiceConfigFile,
Path: mariadbv1.CustomServiceConfigFile,
Expand Down
51 changes: 44 additions & 7 deletions templates/galera/bin/mysql_root_auth.sh
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ MARIADB_API="apis/mariadb.openstack.org/v1beta1"

GALERA_INSTANCE="{{.galeraInstanceName}}"

MY_CNF="$HOME/.my.cnf"
PW_CACHE_FILE="/var/local/my.cnf/mysql_pw_cache.cnf"
MYSQL_SOCKET=/var/lib/mysql/mysql.sock

CREDENTIALS_CHECK_TIMEOUT=4
Expand All @@ -30,9 +30,9 @@ else
fi

# Check if we have cached credentials
if [ "${MYSQL_ROOT_AUTH_BYPASS_CHECKS}" != "true" ] && [ -f "${MY_CNF}" ]; then
if [ "${MYSQL_ROOT_AUTH_BYPASS_CHECKS}" != "true" ] && [ -f "${PW_CACHE_FILE}" ]; then
# Read the password from .my.cnf
PASSWORD=$(grep '^password=' "${MY_CNF}" | cut -d= -f2-)
PASSWORD=$(grep '^password=' "${PW_CACHE_FILE}" | cut -d= -f2-)

# Validate credentials if MySQL is accessible
if [ -n "${PASSWORD}" ]; then
Expand Down Expand Up @@ -153,15 +153,52 @@ fi
MYSQL_PWD="${PASSWORD}"
DB_ROOT_PASSWORD="${PASSWORD}"

# Cache credentials to /root/.my.cnf in MySQL client format
cat > "${MY_CNF}" <<EOF
# Cache credentials to $PW_CACHE_FILE.
# we use .my.cnf format, however as this file is not in an official my.cnf
# location or filename, it's not actually consumed directly by mysql client
# tools.
#
# rationale:
#
# 1. all the client tools are called with -uroot -p${PASSWORD}, so we don't
# actually need this file to be consumed by mariadb client applications
# 2. we don't want a mysql-owned/writable server configuration file in
# /etc/my.cnf.d, all other files in /etc/my.cnf.d/ are root owned /
# read-only
# 3. we don't want to be overwriting such a file either (in case it had
# other actual server conf in it)
# 4. we dont want the root password in a long-lived, volume-mounted file like
# /var/lib/mysql/.my.cnf
# 5. we don't want to mess around with $MARIADB_HOME, $MYSQL_HOME, as
# this is unnecessary due to item 1 above
#

# Create the directory if it doesn't exist
PW_CACHE_DIR=$(dirname "${PW_CACHE_FILE}")
if [ ! -d "${PW_CACHE_DIR}" ]; then
if ! mkdir -p "${PW_CACHE_DIR}" 2>/dev/null; then
echo "WARNING: Failed to create directory ${PW_CACHE_DIR} due to permissions; will try again later" >&2
fi
fi

if ! cat > "${PW_CACHE_FILE}" <<EOF 2>/dev/null
[client]
user=root
password=${PASSWORD}
EOF
then
# we are called for the first time from detect_gcomm_and_start.sh which is
# called **before** kolla can set directory permissions; so when writing
# the file, proceed even if we can't write the file yet
echo "WARNING: Failed to write to ${PW_CACHE_FILE} due to permissions; will try again later" >&2
fi

# Set restrictive permissions on .my.cnf
chmod 600 "${MY_CNF}"
# Set restrictive permissions on .my.cnf (only if file was successfully written)
if [ -f "${PW_CACHE_FILE}" ]; then
if ! chmod 600 "${PW_CACHE_FILE}" 2>/dev/null; then
echo "WARNING: Failed to set permissions on ${PW_CACHE_FILE}; will try again later" >&2
fi
fi

export MYSQL_PWD
export DB_ROOT_PASSWORD
11 changes: 11 additions & 0 deletions templates/galera/config/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@
"owner": "root",
"perm": "0644"
},
{
"source": "/var/lib/config-data/generated/mysql_pw_cache.cnf",
"dest": "/var/local/my.cnf/mysql_pw_cache.cnf",
"owner": "mysql",
"perm": "0644"
},
{
"source": "/var/lib/config-data/generated/galera_tls.cnf",
"dest": "/etc/my.cnf.d/galera_tls.cnf",
Expand Down Expand Up @@ -60,6 +66,11 @@
"path": "/var/log/mariadb",
"owner": "mysql:mysql",
"recurse": "true"
},
{
"path": "/var/local",
"owner": "mysql:mysql",
"recurse": "true"
}
]
}
1 change: 1 addition & 0 deletions templates/galera/config/galera.cnf.in
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
[client]
port = 3306
socket = /var/lib/mysql/mysql.sock
!includedir /var/local/my.cnf/

[isamchk]
key_buffer_size = 16M
Expand Down
36 changes: 18 additions & 18 deletions test/chainsaw/tests/root-auth-cache/chainsaw-test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,39 +15,39 @@ spec:
- assert:
file: ../../common/galera-assert.yaml

- name: verify .my.cnf created
description: Verify that .my.cnf is created after first mysql_root_auth.sh invocation
- name: verify mysql_pw_cache.cnf created
description: Verify that mysql_pw_cache.cnf is created after first mysql_root_auth.sh invocation
try:
- script:
content: |
oc exec -n ${NAMESPACE} -c galera openstack-galera-0 -- /bin/sh -c '
source /var/lib/operator-scripts/mysql_root_auth.sh
test -f $HOME/.my.cnf
test -f /var/local/my.cnf/mysql_pw_cache.cnf
'

- name: verify .my.cnf format
description: Verify .my.cnf has proper MySQL client format
- name: verify mysql_pw_cache.cnf format
description: Verify mysql_pw_cache.cnf has proper MySQL client format
try:
- script:
content: |
oc exec -n ${NAMESPACE} -c galera openstack-galera-0 -- /bin/sh -c '
grep -q "^\[client\]" $HOME/.my.cnf &&
grep -q "^user=root" $HOME/.my.cnf &&
grep -q "^password=" $HOME/.my.cnf
grep -q "^\[client\]" /var/local/my.cnf/mysql_pw_cache.cnf &&
grep -q "^user=root" /var/local/my.cnf/mysql_pw_cache.cnf &&
grep -q "^password=" /var/local/my.cnf/mysql_pw_cache.cnf
'

- name: verify .my.cnf permissions
description: Verify .my.cnf has secure permissions (600)
- name: verify mysql_pw_cache.cnf permissions
description: Verify mysql_pw_cache.cnf has secure permissions (600)
try:
- script:
content: |
oc exec -n ${NAMESPACE} -c galera openstack-galera-0 -- /bin/sh -c '
perms=$(stat -c "%a" $HOME/.my.cnf)
perms=$(stat -c "%a" /var/local/my.cnf/mysql_pw_cache.cnf)
test "$perms" = "600"
'

- name: verify mysql works without explicit credentials
description: Verify MySQL commands work using .my.cnf without MYSQL_PWD env var
- name: verify we can in theory use the file like a my.cnf file
description: Verify MySQL commands work using mysql_pw_cache.cnf without MYSQL_PWD env var
try:
- script:
content: |
Expand All @@ -56,8 +56,8 @@ spec:
mysql -e "SELECT 1" > /dev/null
'

- name: verify mysqladmin works without explicit credentials
description: Verify mysqladmin ping works using .my.cnf
- name: verify we can in theory use the file like a my.cnf file with mysqladmin
description: Verify mysqladmin ping works using mysql_pw_cache.cnf
try:
- script:
content: |
Expand Down Expand Up @@ -90,13 +90,13 @@ spec:
'

- name: verify cache refresh on invalid credentials
description: Verify that invalid credentials in .my.cnf trigger a refresh
description: Verify that invalid credentials in mysql_pw_cache.cnf trigger a refresh
try:
- script:
content: |
oc exec -n ${NAMESPACE} -c galera openstack-galera-0 -- /bin/sh -c '
# Write invalid credentials to .my.cnf
echo -e "[client]\nuser=root\npassword=wrongpassword" > $HOME/.my.cnf
# Write invalid credentials to mysql_pw_cache.cnf
echo -e "[client]\nuser=root\npassword=wrongpassword" > /var/local/my.cnf/mysql_pw_cache.cnf
# Source mysql_root_auth.sh - should detect invalid creds and refresh
source /var/lib/operator-scripts/mysql_root_auth.sh
# Verify MySQL works now (credentials were refreshed)
Expand Down
2 changes: 1 addition & 1 deletion test/chainsaw/tests/update-root-pw/chainsaw-test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ spec:
echo "Testing login on $pod..."
oc exec -n ${NAMESPACE} -c galera $pod -- /bin/sh -c '
# Clear the cached credentials to force using new password
rm -f $HOME/.my.cnf
rm -f /var/local/mysql_pw_cache.cnf
source /var/lib/operator-scripts/mysql_root_auth.sh
if [ "$MYSQL_PWD" != "newrootpassword123" ]; then
echo "ERROR: password != 'newrootpassword123' (actual: $MYSQL_PWD)"
Expand Down