initial commit

This commit is contained in:
unknown 2013-09-26 11:31:36 -07:00
parent 89eded3386
commit 95dda3c4d8
4 changed files with 229 additions and 0 deletions

View File

@ -2,3 +2,32 @@ galeranotify
============
Python E-Mail script for use with Galera wsrep_notify_cmd
Why do I need / want this?
--------------------------
[Galera](http://codership.com/products/galera_replication) makes my life easier with near synchronous replication for MySQL. We have monitoring tools in place, but its nice to get updates in real time about how the cluster is operating. So I wrote galeranotify.
I've been using this on our [Percona XtraDB Cluster](http://www.percona.com/software/percona-xtradb-cluster) for quite a while now with no issues.
I hope someone finds it useful.
Set up
------
1. Edit galeranotify.py to change the configuration options. They should be pretty straightforward.
2. Place galeranotify.py in a common location and make sure you and your MySql user have execute permissions.
3. Manually execute galeranotify.py with several of the options set (check usage) and check to make sure the script executes with no errors and that you receive the notification e-mail.
4. Set 'wsrep_notify_cmd = <path of galeranotify.py>' in your my.cnf file.
5. Restart MySql.
SELinux
-------
A SELinux policy (galeranotify.pp) is also included that allows the mysql user to connect to a standard remote smtp port (port 25). If you are using an alternate SMTP port (common with SSL), this rule will not work for you.
This rule was generated on Centos 6.4 64-bit. It may or may not work for your particular setup.

BIN
galeranotify.pp Normal file

Binary file not shown.

186
galeranotify.py Normal file
View File

@ -0,0 +1,186 @@
#!/usr/bin/python
#
# Script to send email notifications when a change in Galera cluster membership
# occurs.
#
# Complies with http://www.codership.com/wiki/doku.php?id=notification_command
#
# Author: Gabe Guillen <gguillen@gesa.com>
# Version: 1.2
# Release: 6/27/2013
# Use at your own risk. No warranties expressed or implied.
#
import os
import sys
import getopt
import smtplib, email
import socket
# Change this to some value if you don't want your server hostname to show in
# the notification emails
THIS_SERVER = socket.gethostname()
# Server hostname or IP address
SMTP_SERVER = 'YOUR_SMTP_HERE'
SMTP_PORT = 25
# Set to True if you need SMTP over SSL
SMTP_SSL = False
# Set to True if you need to authenticate to your SMTP server
SMTP_AUTH = False
# Fill in authorization information here if True above
SMTP_USERNAME = ''
SMTP_PASSWORD = ''
# Takes a single sender
MAIL_FROM = 'YOUR_EMAIL_HERE'
# Takes a list of recipients
MAIL_TO = ['SOME_OTHER_EMAIL_HERE']
# Edit below at your own risk
################################################################################
def main(argv):
str_status = ''
str_uuid = ''
str_primary = ''
str_members = ''
str_index = ''
message = ''
usage = "Usage: " + os.path.basename(sys.argv[0]) + " --status <status str>"
usage += " --uuid <state UUID> --primary <yes/no> --members <comma-seperated"
usage += " list of the component member UUIDs> --index <n>"
try:
opts, args = getopt.getopt(argv, "h", ["status=","uuid=",'primary=','members=','index='])
except getopt.GetoptError:
print usage
sys.exit(2)
if(len(opts) > 0):
message_obj = GaleraStatus(THIS_SERVER)
for opt, arg in opts:
if opt == '-h':
print usage
sys.exit()
elif opt in ("--status"):
message_obj.set_status(arg)
elif opt in ("--uuid"):
message_obj.set_uuid(arg)
elif opt in ("--primary"):
message_obj.set_primary(arg)
elif opt in ("--members"):
message_obj.set_members(arg)
elif opt in ("--index"):
message_obj.set_index(arg)
try:
send_notification(MAIL_FROM, MAIL_TO, 'Galera Notification: ' + THIS_SERVER,
str(message_obj), SMTP_SERVER, SMTP_PORT, SMTP_SSL, SMTP_AUTH,
SMTP_USERNAME, SMTP_PASSWORD)
except Exception, e:
print "Unable to send notification: %s" % e
sys.exit(1)
else:
print usage
sys.exit(2)
sys.exit(0)
def send_notification(from_email, to_email, subject, message, smtp_server,
smtp_port, use_ssl, use_auth, smtp_user, smtp_pass):
msg = email.MIMEMultipart.MIMEMultipart()
body = email.MIMEText.MIMEText(message)
msg.attach(body)
msg.add_header('From', from_email)
msg.add_header('To', ', '.join(to_email))
msg.add_header('Subject', subject)
if(use_ssl):
mailer = smtplib.SMTP_SSL(smtp_server, smtp_port)
else:
mailer = smtplib.SMTP(smtp_server, smtp_port)
if(use_auth):
mailer.login(smtp_user, smtp_pass)
mailer.sendmail(from_email, to_email, msg.as_string())
mailer.close()
class GaleraStatus:
def __init__(self, server):
self._server = server
self._status = ""
self._uuid = ""
self._primary = ""
self._members = ""
self._index = ""
self._count = 0
def set_status(self, status):
self._status = status
self._count += 1
def set_uuid(self, uuid):
self._uuid = uuid
self._count += 1
def set_primary(self, primary):
self._primary = primary.capitalize()
self._count += 1
def set_members(self, members):
self._members = members.split(',')
self._count += 1
def set_index(self, index):
self._index = index
self._count += 1
def __str__(self):
message = "Galera running on " + self._server + " has reported the following"
message += " cluster membership change"
if(self._count > 1):
message += "s"
message += ":\n\n"
if(self._status):
message += "Status of this node: " + self._status + "\n\n"
if(self._uuid):
message += "Cluster state UUID: " + self._uuid + "\n\n"
if(self._primary):
message += "Current cluster component is primary: " + self._primary + "\n\n"
if(self._members):
message += "Current members of the component:\n"
if(self._index):
for i in range(len(self._members)):
if(i == int(self._index)):
message += "-> "
else:
message += "-- "
message += self._members[i] + "\n"
else:
message += "\n".join((" " + str(x)) for x in self._members)
message += "\n"
if(self._index):
message += "Index of this node in the member list: " + self._index + "\n"
return message
if __name__ == "__main__":
main(sys.argv[1:])

14
galeranotify.te Normal file
View File

@ -0,0 +1,14 @@
module galeranotify 1.0;
require {
type smtp_port_t;
type mysqld_t;
class tcp_socket name_connect;
}
#============= mysqld_t ==============
#!!!! This avc can be allowed using one of the these booleans:
# mysql_connect_any, allow_ypbind
allow mysqld_t smtp_port_t:tcp_socket name_connect;