Merge "Add prometheus main dashboard"
diff --git a/.kitchen.travis.yml b/.kitchen.travis.yml
index f847543..08b3a11 100644
--- a/.kitchen.travis.yml
+++ b/.kitchen.travis.yml
@@ -3,4 +3,4 @@
- name: <%= ENV['SUITE'] %>
provisioner:
pillars-from-files:
- neutron.sls: tests/pillar/<%= ENV['SUITE'] %>.sls
+ galera.sls: tests/pillar/<%= ENV['SUITE'] %>.sls
diff --git a/.kitchen.yml b/.kitchen.yml
index dbb9474..90b13c5 100644
--- a/.kitchen.yml
+++ b/.kitchen.yml
@@ -14,6 +14,13 @@
formula: galera
grains:
noservices: True
+ dependencies:
+ - name: mysql
+ repo: git
+ source: https://github.com/salt-formulas/salt-formula-mysql.git
+ - name: linux
+ repo: git
+ source: https://github.com/salt-formulas/salt-formula-linux.git
state_top:
base:
"*":
@@ -27,14 +34,6 @@
- galeracluster_debian_repo
pillars-from-files:
galeracluster_debian_repo.sls: tests/pillar/repo_galeracluster.sls
- dependencies:
- - name: mysql
- repo: git
- source: https://github.com/salt-formulas/salt-formula-mysql.git
- dependencies:
- - name: linux
- repo: git
- source: https://github.com/salt-formulas/salt-formula-linux.git
verifier:
name: inspec
diff --git a/README.rst b/README.rst
index 609ec3d..05ea8da 100644
--- a/README.rst
+++ b/README.rst
@@ -56,19 +56,76 @@
user: root
password: pass
+Enable TLS support:
+
+.. code-block:: yaml
+
+ galera:
+ slave or master:
+ ssl:
+ enabled: True
+
+ # path
+ cert_file: /etc/mysql/ssl/cert.pem
+ key_file: /etc/mysql/ssl/key.pem
+ ca_file: /etc/mysql/ssl/ca.pem
+
+ # content (not required if files already exists)
+ key: << body of key >>
+ cert: << body of cert >>
+ cacert_chain: << body of ca certs chain >>
+
+
+Additional mysql users:
+
+.. code-block:: yaml
+
+ mysql:
+ server:
+ users:
+ - name: clustercheck
+ password: clustercheck
+ database: '*.*'
+ grants: PROCESS
+ - name: inspector
+ host: 127.0.0.1
+ password: password
+ databases:
+ mydb:
+ - database: mydb
+ - table: mytable
+ - grant_option: True
+ - grants:
+ - all privileges
+
+Additional check params:
+========================
+
+.. code-block:: yaml
+
+ galera:
+ clustercheck:
+ - enabled: True
+ - user: clustercheck
+ - password: clustercheck
+ - available_when_donor: 0
+ - available_when_readonly: 1
+ - port 9200
+
Configurable soft parameters
============================
+
- **galera_innodb_buffer_pool_size** - the default value is 3138M
- **galera_max_connections** - the default value is 20000
Usage:
-
.. code-block:: yaml
_param:
galera_innodb_buffer_pool_size: 1024M
- galera_max_connections: 200
+ galera_max_connections: 200
+
Usage
=====
diff --git a/galera/clustercheck.sls b/galera/clustercheck.sls
new file mode 100644
index 0000000..a311a84
--- /dev/null
+++ b/galera/clustercheck.sls
@@ -0,0 +1,45 @@
+{%- from "galera/map.jinja" import clustercheck with context %}
+
+{%- if clustercheck.get('enabled', False) %}
+/usr/local/bin/mysql_clustercheck:
+ file.managed:
+ - source: salt://galera/files/clustercheck.sh
+ - user: root
+ - group: root
+ - mode: 755
+ - dir_mode: 755
+ - makedirs: True
+
+/etc/xinetd.d/mysql_clustercheck:
+ file.managed:
+ - source: salt://galera/files/xinet.d.conf
+ - template: jinja
+ - makedirs: True
+ - defaults:
+ name: mysqlchk
+ user: nobody
+ server: '/usr/local/bin/mysql_clustercheck'
+ server_args: '{{ clustercheck.get('user', 'clustercheck') }} {{ clustercheck.get('password', 'clustercheck') }} available_when_donor={{ clustercheck.get('available_when_donor', 0) }} /dev/null available_when_readonly={{ clustercheck.get('available_when_readonly', 0) }} {{ clustercheck.config }}'
+ port: {{ clustercheck.get('port', 9200) }}
+ flags: REUSE
+ per_source: UNLIMITED
+ - require:
+ - file: /usr/local/bin/mysql_clustercheck
+{%- if not grains.get('noservices', False) %}
+ - watch_in:
+ - galera_xinetd_service
+{%- endif %}
+
+galera_xinetd_package:
+ pkg.installed:
+ - name: xinetd
+
+{%- if not grains.get('noservices', False) %}
+galera_xinetd_service:
+ service.running:
+ - name: xinetd
+ - require:
+ - pkg: xinetd
+{%- endif %}
+{%- endif %}
+
diff --git a/galera/files/clustercheck.sh b/galera/files/clustercheck.sh
new file mode 100644
index 0000000..efed950
--- /dev/null
+++ b/galera/files/clustercheck.sh
@@ -0,0 +1,138 @@
+#!/bin/bash
+#
+# Script to make a proxy (ie HAProxy) capable of monitoring MySQL Cluster nodes properly
+#
+# Author: Olaf van Zandwijk <olaf.vanzandwijk@nedap.com>
+# Author: Raghavendra Prabhu <raghavendra.prabhu@percona.com>
+# Author: Petr Michalec <pmichalec@mirantis.com>
+#
+# Documentation and download: https://github.com/epcim/percona-clustercheck
+#
+# Based on the original script from Unai Rodriguez
+#
+
+function httpReply(){
+ HTTP_STATUS="${1}"
+ RESPONSE_CONTENT="${2}"
+
+ # https://serverfault.com/questions/504756/curl-failure-when-receiving-data-from-peer-using-percona-xtradb-cluster-check
+ sleep 0.1
+ if [[ "${HTTP_STATUS}" == "503" ]]
+ then
+ echo -en "HTTP/1.1 503 Service Unavailable\r\n"
+ elif [[ "${HTTP_STATUS}" == "404" ]]
+ then
+ echo -en "HTTP/1.1 404 Not Found\r\n"
+ elif [[ "${HTTP_STATUS}" == "401" ]]
+ then
+ echo -en "HTTP/1.1 401 Unauthorized\r\n"
+ elif [[ "${HTTP_STATUS}" == "200" ]]
+ then
+ echo -en "HTTP/1.1 200 OK\r\n"
+ else
+ echo -en "HTTP/1.1 ${HTTP_STATUS}\r\n"
+ fi
+
+ echo -en "Content-Type: text/plain\r\n"
+ echo -en "Connection: close\r\n"
+ echo -en "Content-Length: ${#RESPONSE_CONTENT}\r\n"
+ echo -en "\r\n"
+ echo -en "${RESPONSE_CONTENT}"
+ echo -en "\r\n"
+ sleep 0.1
+}
+
+if [[ $1 == '-h' || $1 == '--help' ]];then
+ echo "Usage: $0 <user> <pass> <available_when_donor=0|1> <log_file> <available_when_readonly=0|1> <defaults_extra_file> <timeout>"
+ exit
+fi
+
+# if the disabled file is present, return 503. This allows
+# admins to manually remove a node from a cluster easily.
+if [ -e "/var/tmp/clustercheck.disabled" ]; then
+ # Shell return-code is 1
+ httpReply "503" "MySQL Cluster Node is manually disabled.\r\n"
+ exit 1
+fi
+
+MYSQL_USERNAME="${1-clustercheckuser}"
+MYSQL_PASSWORD="${2-clustercheckpassword!}"
+AVAILABLE_WHEN_DONOR=${3:-0}
+ERR_FILE="${4:-/dev/null}"
+AVAILABLE_WHEN_READONLY=${5:-1}
+DEFAULTS_EXTRA_FILE=${6:-/etc/my.cnf}
+# Timeout exists for instances where mysqld may be hung
+# Default value considers the Galera timeouts
+TIMEOUT=${7:-18}
+
+EXTRA_ARGS=""
+if [[ -n "$MYSQL_USERNAME" ]]; then
+ EXTRA_ARGS="$EXTRA_ARGS --user=${MYSQL_USERNAME}"
+fi
+if [[ -n "$MYSQL_PASSWORD" ]]; then
+ EXTRA_ARGS="$EXTRA_ARGS --password=${MYSQL_PASSWORD}"
+fi
+if [[ -r $DEFAULTS_EXTRA_FILE ]];then
+ MYSQL_CMDLINE="mysql --defaults-extra-file=$DEFAULTS_EXTRA_FILE -nNE --connect-timeout=$TIMEOUT \
+ ${EXTRA_ARGS}"
+else
+ MYSQL_CMDLINE="mysql -nNE --connect-timeout=$TIMEOUT ${EXTRA_ARGS}"
+fi
+#
+# Perform the query to check the wsrep_local_state
+#
+WSREP_STATUS=$($MYSQL_CMDLINE -e "SHOW STATUS LIKE 'wsrep_local_state';" \
+ 2>${ERR_FILE} | tail -1 2>>${ERR_FILE}; exit ${PIPESTATUS[0]})
+mysql_ret=$?
+
+if [[ $mysql_ret -eq 1 || $mysql_ret -eq 127 ]]; then
+ # hash or command can be used here, but command is POSIX
+ command -v "$MYSQL_CMD"; mysql_ret=$?
+ if [[ $mysql_ret -eq 1 ]]; then
+ # mysql program not found
+ # => return HTTP 404
+ # Shell return-code is 3
+ httpReply "404" "Mysql command not found or service is not running.\r\n"
+ exit 2
+ fi
+
+ # Failed mysql login
+ # => return HTTP 401
+ # Shell return-code is 2
+ httpReply "401" "Access denied to database.\r\n"
+ exit 2
+fi
+
+
+
+if [[ "${WSREP_STATUS}" == "4" ]] || [[ "${WSREP_STATUS}" == "2" && ${AVAILABLE_WHEN_DONOR} == 1 ]]
+then
+ # Check only when set to 0 to avoid latency in response.
+ if [[ $AVAILABLE_WHEN_READONLY -eq 0 ]];then
+ READ_ONLY=$($MYSQL_CMDLINE -e "SHOW GLOBAL VARIABLES LIKE 'read_only';" \
+ 2>${ERR_FILE} | tail -1 2>>${ERR_FILE})
+
+ if [[ "${READ_ONLY}" == "ON" ]];then
+ # MySQL Cluster node local state is 'Synced', but it is in
+ # read-only mode. The variable AVAILABLE_WHEN_READONLY is set to 0.
+ # => return HTTP 503
+ # Shell return-code is 1
+ httpReply "503" "MySQL Cluster Node is read-only.\r\n"
+ exit 1
+ fi
+ fi
+ # MySQL Cluster node local state is 'Synced' => return HTTP 200
+ # Shell return-code is 0
+ httpReply "200" "MySQL Cluster Node is synced.\r\n"
+ exit 0
+else
+ # MySQL Cluster node local state is not 'Synced' => return HTTP 503
+ # Shell return-code is 1
+ if [[ -z "${WSREP_STATUS}" ]]
+ then
+ httpReply "503" "Received empty reply from MySQL Cluster Node.\r\nMight be a permission issue, check the credentials used by ${0}\r\n"
+ else
+ httpReply "503" "MySQL Cluster Node is not synced.\r\n"
+ fi
+ exit 1
+fi
diff --git a/galera/files/init_bootstrap.sh b/galera/files/init_bootstrap.sh
index 4683d1a..917c4f0 100644
--- a/galera/files/init_bootstrap.sh
+++ b/galera/files/init_bootstrap.sh
@@ -7,7 +7,7 @@
while [ $counter -gt 0 ]
do
- mysql -u root -e"quit"
+ mysql -u root -e"quit" || mysql -u {{ service.admin.user }} -p{{ service.admin.password }} -e"quit"
if [[ $? -eq 0 ]]; then
echo "Sucessfully connected to the MySQL service ($retries retries)."
exit 0
diff --git a/galera/files/my.cnf b/galera/files/my.cnf
index ea04def..049d6d6 100644
--- a/galera/files/my.cnf
+++ b/galera/files/my.cnf
@@ -9,6 +9,14 @@
{%- from "galera/map.jinja" import slave with context %}
{%- set service = slave %}
{%- endif %}
+
+[mysql]
+{% if service.get('ssl', {}).get('enabled', False) %}
+ssl-ca={{ service.ssl.ca_file }}
+ssl-cert={{ service.ssl.cert_file }}
+ssl-key={{ service.ssl.key_file }}
+{% endif %}
+
[mysqld_safe]
syslog
@@ -60,6 +68,13 @@
wsrep_provider_options="gcache.size = 256M"
wsrep_provider_options="gmcast.listen_addr = tcp://{{ service.bind.address }}:4567"
+{% if service.get('ssl', {}).get('enabled', False) %}
+wsrep_provider_options="socket.ssl=yes;socket.ssl_key={{ service.ssl.key_file }};socket.ssl_cert={{ service.ssl.cert_file }};socket.ssl_ca={{ service.ssl.ca_file }}"
+ssl-ca={{ service.ssl.ca_file }}
+ssl-cert={{ service.ssl.cert_file }}
+ssl-key={{ service.ssl.key_file }}
+{% endif %}
+
[xtrabackup]
parallel=4
diff --git a/galera/files/xinet.d.conf b/galera/files/xinet.d.conf
new file mode 100644
index 0000000..fd6f321
--- /dev/null
+++ b/galera/files/xinet.d.conf
@@ -0,0 +1,24 @@
+# default: {{ default_state|default('on') }}
+# description: {{ name }}
+
+service {{ name }}:
+{
+ disable = {{ disable|default('no') }}
+ {%- if flags is defined %}
+ flags = {{ flags }}
+ {%- endif %}
+ socket_type = {{ socket_type|default('stream') }}
+ port = {{ port }}
+ wait = {{ wait|default('no') }}
+ user = {{ user }}
+ server = {{ server }}
+ {%- if server_args is defined %}
+ server_args = {{ server_args }}
+ {%- endif %}
+ log_on_failure += {{ log_on_failure|default('USERID') }}
+ only_from = {{ only_from|default('0.0.0.0/0') }}
+ type = {{ type|default('UNLISTED') }}
+ {%- if per_source is defined %}
+ per_source = {{ per_source }}
+ {%- endif %}
+}
diff --git a/galera/init.sls b/galera/init.sls
index 94e1414..9944b4c 100644
--- a/galera/init.sls
+++ b/galera/init.sls
@@ -1,12 +1,16 @@
{%- if pillar.galera is defined %}
include:
+- galera.ssl
{%- if pillar.galera.master is defined %}
- galera.master
{%- endif %}
{%- if pillar.galera.slave is defined %}
- galera.slave
{%- endif %}
+{%- if pillar.galera.clustercheck is defined %}
+- galera.clustercheck
+{%- endif %}
{%- if pillar.galera.monitor is defined %}
- galera.monitor
{%- endif %}
diff --git a/galera/map.jinja b/galera/map.jinja
index e7fea3c..2db08d1 100644
--- a/galera/map.jinja
+++ b/galera/map.jinja
@@ -63,3 +63,20 @@
'config': '/etc/mysql/my.cnf',
},
}, grain='oscodename', merge=pillar.galera.get('slave', {})), base='default') %}
+
+{% set clustercheck = salt['grains.filter_by']({
+ 'Debian': {
+ 'config': '/etc/mysql/my.cnf',
+ 'enabled': False,
+ 'user': clustercheck,
+ 'password': clustercheck,
+ 'port': '9200'
+ },
+ 'RedHat': {
+ 'config': '/etc/my.cnf',
+ 'enabled': False,
+ 'user': clustercheck,
+ 'password': clustercheck,
+ 'port': '9200'
+ },
+}, merge=pillar.galera.get('clustercheck', {})) %}
diff --git a/galera/master.sls b/galera/master.sls
index 47af87d..9fc1f9f 100644
--- a/galera/master.sls
+++ b/galera/master.sls
@@ -115,6 +115,7 @@
- defaults:
service: {{ master|yaml }}
- template: jinja
+ - timeout: 1800
galera_bootstrap_script:
file.managed:
@@ -147,6 +148,7 @@
- require:
- file: galera_run_dir
- file: galera_init_script
+ - timeout: 1800
galera_bootstrap_set_root_password:
cmd.run:
@@ -166,23 +168,12 @@
- require:
- cmd: galera_bootstrap_set_root_password
-galera_bootstrap_stop_service_pre:
- cmd.run:
- - name: mysqladmin -h localhost -u root -p{{ master.admin.password }} shutdown
- {%- if not grains.get('noservices', False) %}
- - ignore_retcode: true
- - require:
- - cmd: mysql_bootstrap_update_maint_password
- {%- else %}
- - onlyif: /bin/false
- {%- endif %}
-
galera_bootstrap_stop_service:
service.dead:
- name: {{ master.service }}
{%- if not grains.get('noservices', False) %}
- require:
- - cmd: galera_bootstrap_stop_service_pre
+ - cmd: mysql_bootstrap_update_maint_password
{%- else %}
- onlyif: /bin/false
{%- endif %}
diff --git a/galera/server.sls b/galera/server.sls
index 78975a0..4b84654 100644
--- a/galera/server.sls
+++ b/galera/server.sls
@@ -1,5 +1,5 @@
{%- if pillar.get('mysql', {}).server is defined %}
-
+{%- from "mysql/map.jinja" import mysql_connection_args as connection with context %}
{%- set server = pillar.mysql.server %}
{%- for database_name, database in server.get('database', {}).iteritems() %}
@@ -7,14 +7,30 @@
mysql_database_{{ database_name }}:
mysql_database.present:
- name: {{ database_name }}
+ - character_set: {{ database.get('encoding', 'utf8') }}
+ #- connection_user: {{ connection.user }}
+ #- connection_pass: {{ connection.password }}
+ #- connection_charset: {{ connection.charset }}
+ {%- if grains.get('noservices') %}
+ - onlyif: /bin/false
+ {%- endif %}
-{%- for user in database.users %}
-
+{%- for user in database.get('users', {}) %}
mysql_user_{{ user.name }}_{{ database_name }}_{{ user.host }}:
mysql_user.present:
- host: '{{ user.host }}'
- name: '{{ user.name }}'
+ {%- if user.password is defined %}
- password: {{ user.password }}
+ {%- else %}
+ - allow_passwordless: true
+ {%- endif %}
+ #- connection_user: {{ connection.user }}
+ #- connection_pass: {{ connection.password }}
+ #- connection_charset: {{ connection.charset }}
+ {%- if grains.get('noservices') %}
+ - onlyif: /bin/false
+ {%- endif %}
mysql_grants_{{ user.name }}_{{ database_name }}_{{ user.host }}:
mysql_grants.present:
@@ -22,14 +38,18 @@
- database: '{{ database_name }}.*'
- user: '{{ user.name }}'
- host: '{{ user.host }}'
+ #- connection_user: {{ connection.user }}
+ #- connection_pass: {{ connection.password }}
+ #- connection_charset: {{ connection.charset }}
- require:
- mysql_user: mysql_user_{{ user.name }}_{{ database_name }}_{{ user.host }}
- mysql_database: mysql_database_{{ database_name }}
-
+ {%- if grains.get('noservices') %}
+ - onlyif: /bin/false
+ {%- endif %}
{%- endfor %}
{%- if database.initial_data is defined %}
-
/root/mysql/scripts/restore_{{ database_name }}.sh:
file.managed:
- source: salt://mysql/conf/restore.sh
@@ -49,25 +69,73 @@
- cwd: /root
- require:
- file: /root/mysql/scripts/restore_{{ database_name }}.sh
-
{%- endif %}
{%- endfor %}
{%- for user in server.get('users', []) %}
-
-mysql_user_{{ user.name }}_{{ user.host }}:
+{%- for host in user.get('hosts', user.get('host', 'localhost'))|sequence %}
+mysql_user_{{ user.name }}_{{ host }}:
mysql_user.present:
- - host: '{{ user.host }}'
+ - host: '{{ host }}'
- name: '{{ user.name }}'
- {%- if user.password is defined %}
- - password: {{ user.password }}
+ {%- if user['password_hash'] is defined %}
+ - password_hash: '{{ user.password_hash }}'
+ {%- elif user['password'] is defined and user['password'] != None %}
+ - password: '{{ user.password }}'
{%- else %}
- allow_passwordless: True
{%- endif %}
+ #- connection_user: {{ connection.user }}
+ #- connection_pass: {{ connection.password }}
+ #- connection_charset: {{ connection.charset }}
{%- if grains.get('noservices') %}
- onlyif: /bin/false
{%- endif %}
+
+{%- if 'grants' in user %}
+mysql_user_{{ user.name }}_{{ host }}_grants:
+ mysql_grants.present:
+ - name: {{ user.name }}
+ - grant: {{ user['grants']|sequence|join(",") }}
+ - database: '{{ user.get('database','*.*') }}'
+ - grant_option: {{ user['grant_option'] | default(False) }}
+ - user: {{ user.name }}
+ - host: '{{ host }}'
+ #- connection_user: {{ connection.user }}
+ #- connection_pass: {{ connection.password }}
+ #- connection_charset: {{ connection.charset }}
+ - require:
+ - mysql_user_{{ user.name }}_{{ host }}
+ {%- if grains.get('noservices') %}
+ - onlyif: /bin/false
+ {%- endif %}
+{%- endif %}
+
+{%- if 'databases' in user %}
+{%- for db in user['databases'] %}
+mysql_user_{{ user.name }}_{{ host }}_grants_db_{{ db.database }}_{{ loop.index0 }}:
+ mysql_grants.present:
+ - name: {{ user.name ~ '_' ~ db['database'] ~ '_' ~ db['table'] | default('all') }}
+ - grant: {{ db['grants']|sequence|join(",") }}
+ - database: '{{ db['database'] }}.{{ db['table'] | default('*') }}'
+ - grant_option: {{ db['grant_option'] | default(False) }}
+ - user: {{ user.name }}
+ - host: '{{ host }}'
+ #- connection_user: {{ connection.user }}
+ #- connection_pass: {{ connection.password }}
+ #- connection_charset: {{ connection.charset }}
+ - require:
+ - mysql_user_{{ user.name }}_{{ host }}
+ # the following line is not mandatory as database might not be managed by salt formula
+ #- mysql_database_{{ db.database }}
+ {%- if grains.get('noservices') %}
+ - onlyif: /bin/false
+ {%- endif %}
+{%- endfor %}
+{%- endif %}
{%- endfor %}
-{%- endif %}
\ No newline at end of file
+{%- endfor %}
+
+{%- endif %}
diff --git a/galera/slave.sls b/galera/slave.sls
index 3f5502a..290d371 100644
--- a/galera/slave.sls
+++ b/galera/slave.sls
@@ -147,6 +147,7 @@
- require:
- file: galera_run_dir
- file: galera_init_script
+ - timeout: 1800
galera_bootstrap_set_root_password:
cmd.run:
@@ -166,23 +167,12 @@
- require:
- cmd: galera_bootstrap_set_root_password
-galera_bootstrap_stop_service_pre:
- cmd.run:
- - name: mysqladmin -h localhost -u root -p{{ slave.admin.password }} shutdown
- {%- if not grains.get('noservices', False) %}
- - ignore_retcode: true
- - require:
- - cmd: mysql_bootstrap_update_maint_password
- {%- else %}
- - onlyif: /bin/false
- {%- endif %}
-
galera_bootstrap_stop_service:
service.dead:
- name: {{ slave.service }}
{%- if not grains.get('noservices', False) %}
- require:
- - cmd: galera_bootstrap_stop_service_pre
+ - cmd: mysql_bootstrap_update_maint_password
{%- else %}
- onlyif: /bin/false
{%- endif %}
@@ -205,6 +195,7 @@
- require:
- file: galera_bootstrap_init_config
- file: galera_bootstrap_script
+ - timeout: 1800
galera_bootstrap_finish_flag:
file.touch:
@@ -235,3 +226,4 @@
{%- endif %}
{%- endif %}
+
diff --git a/galera/ssl.sls b/galera/ssl.sls
new file mode 100644
index 0000000..f13fe5a
--- /dev/null
+++ b/galera/ssl.sls
@@ -0,0 +1,83 @@
+{%- from "galera/map.jinja" import master, slave with context %}
+
+{%- set service = master if pillar.galera.master is defined else slave %}
+{%- set role = 'master' if pillar.galera.master is defined else 'slave' %}
+
+{%- if service.get('ssl', {}).get('enabled', False) %}
+{%- if service.ssl.cacert_chain is defined %}
+mysql_cacertificate:
+ file.managed:
+ - name: {{ service.ssl.ca_file }}
+ - contents_pillar: galera:{{ role }}:ssl:cacert_chain
+ - mode: 0444
+ - makedirs: true
+ - require_in:
+ - service: galera_service
+{%- else %}
+mysql_cacertificate_exists:
+ file.exists:
+ - name: {{ service.ssl.ca_file }}
+mysql_cacertificate:
+ file.managed:
+ - name: {{ service.ssl.ca_file }}
+ - mode: 644
+ - create: False
+ - require:
+ - file: mysql_cacertificate_exists
+ - require_in:
+ - service: galera_service
+{%- endif %}
+
+{%- if service.ssl.cert is defined %}
+mysql_certificate:
+ file.managed:
+ - name: {{ service.ssl.cert_file }}
+ - contents_pillar: galera:{{ role }}:ssl:cert
+ - mode: 0444
+ - makedirs: true
+ - require_in:
+ - service: galera_service
+{%- else %}
+mysql_certificate_exists:
+ file.exists:
+ - name: {{ service.ssl.cert_file }}
+mysql_certificate:
+ file.managed:
+ - name: {{ service.ssl.cert_file }}
+ - mode: 644
+ - create: False
+ - require:
+ - file: mysql_certificate_exists
+ - require_in:
+ - service: galera_service
+{%- endif %}
+
+{%- if service.ssl.key is defined %}
+mysql_server_key:
+ file.managed:
+ - name: {{ service.ssl.key_file }}
+ - contents_pillar: galera:{{ role }}:ssl:key
+ - user: root
+ - group: mysql
+ - mode: 0440
+ - makedirs: true
+ - require_in:
+ - service: galera_service
+{%- else %}
+mysql_server_key_exists:
+ file.exists:
+ - name: {{ service.ssl.key_file }}
+mysql_server_key:
+ file.managed:
+ - name: {{ service.ssl.key_file }}
+ - user: root
+ - group: mysql
+ - mode: 0440
+ - create: False
+ - require:
+ - file: mysql_server_key_exists
+ - require_in:
+ - service: galera_service
+{%- endif %}
+
+{%- endif %}
diff --git a/metadata/service/ssl.yml b/metadata/service/ssl.yml
new file mode 100644
index 0000000..5b31b31
--- /dev/null
+++ b/metadata/service/ssl.yml
@@ -0,0 +1,21 @@
+# class to enable tls for galera.master and galera.slave
+
+parameters:
+ _param:
+ mysql_ssl_key_file: /etc/mysql/ssl/key.pem
+ mysql_ssl_cert_file: /etc/mysql/ssl/cert.pem
+ mysql_ssl_ca_file: /etc/mysql/ssl/ca.pem
+
+ galera:
+ master:
+ ssl:
+ enabled: True
+ key_file: ${_param:mysql_ssl_key_file}
+ cert_file: ${_param:mysql_ssl_cert_file}
+ ca_file: ${_param:mysql_ssl_ca_file}
+ slave:
+ ssl:
+ enabled: True
+ key_file: ${_param:mysql_ssl_key_file}
+ cert_file: ${_param:mysql_ssl_cert_file}
+ ca_file: ${_param:mysql_ssl_ca_file}
diff --git a/tests/integration/master_cluster/checks_clustercheck_spec.rb b/tests/integration/master_cluster/checks_clustercheck_spec.rb
new file mode 100644
index 0000000..d10fc19
--- /dev/null
+++ b/tests/integration/master_cluster/checks_clustercheck_spec.rb
@@ -0,0 +1,10 @@
+describe file('/etc/xinetd.d/mysql_clustercheck') do
+ it('should exist')
+ its('content') { should match /server.*\/usr\/local\/bin\/mysql_clustercheck/ }
+ its('content') { should match /server_args.*clustercheck password available_when_donor=1 \/dev\/null available_when_readonly=1/ }
+end
+
+describe file('/usr/local/bin/mysql_clustercheck') do
+ it('should exist')
+ it('should be_executable')
+end
diff --git a/tests/integration/slave_cluster/checks_clustercheck_spec.rb b/tests/integration/slave_cluster/checks_clustercheck_spec.rb
new file mode 100644
index 0000000..d10fc19
--- /dev/null
+++ b/tests/integration/slave_cluster/checks_clustercheck_spec.rb
@@ -0,0 +1,10 @@
+describe file('/etc/xinetd.d/mysql_clustercheck') do
+ it('should exist')
+ its('content') { should match /server.*\/usr\/local\/bin\/mysql_clustercheck/ }
+ its('content') { should match /server_args.*clustercheck password available_when_donor=1 \/dev\/null available_when_readonly=1/ }
+end
+
+describe file('/usr/local/bin/mysql_clustercheck') do
+ it('should exist')
+ it('should be_executable')
+end
diff --git a/tests/pillar/master_cluster.sls b/tests/pillar/master_cluster.sls
index 5b596d9..a8f0633 100644
--- a/tests/pillar/master_cluster.sls
+++ b/tests/pillar/master_cluster.sls
@@ -7,7 +7,7 @@
port: 3306
maintenance_password: password
admin:
- user: user
+ user: root
password: password
members:
- host: 127.0.0.1
@@ -16,10 +16,20 @@
port: 4567
- host: 127.0.0.1
port: 4567
+ clustercheck:
+ enabled: True
+ user: clustercheck
+ password: password
+ available_when_donor: 1
+ available_when_readonly: 1
+ port: 9200
max_connections: 20000
innodb_buffer_pool_size: 3138M
mysql:
server:
+ database:
+ mydb:
+ encoding: 'utf8'
users:
- name: haproxy
host: localhost
@@ -27,3 +37,17 @@
host: '%'
- name: haproxy
host: 127.0.0.1
+ - name: clustercheck
+ #host: localhost
+ password: password
+ database: '*.*'
+ grants: PROCESS
+ - name: inspector
+ host: 127.0.0.1
+ password: password
+ databases:
+ - database: mydb
+ table: mytable
+ grant_option: True
+ grants:
+ - all privileges
diff --git a/tests/pillar/slave_cluster.sls b/tests/pillar/slave_cluster.sls
index 40ec4de..38c8420 100644
--- a/tests/pillar/slave_cluster.sls
+++ b/tests/pillar/slave_cluster.sls
@@ -7,7 +7,7 @@
port: 3306
maintenance_password: password
admin:
- user: user
+ user: root
password: password
members:
- host: 127.0.0.1
@@ -16,6 +16,13 @@
port: 4567
- host: 127.0.0.1
port: 4567
+ clustercheck:
+ enabled: True
+ user: clustercheck
+ password: password
+ available_when_donor: 1
+ available_when_readonly: 1
+ port: 9200
max_connections: 20000
innodb_buffer_pool_size: 3138M
mysql:
@@ -26,4 +33,9 @@
- name: haproxy
host: '%'
- name: haproxy
- host: 127.0.0.1
\ No newline at end of file
+ host: 127.0.0.1
+ - name: clustercheck
+ #host: localhost
+ password: password
+ database: '*.*'
+ grants: PROCESS