-
-
Save abg/9510448 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
import pyrax | |
import ConfigParser | |
import sys | |
import getopt | |
class Config(ConfigParser.ConfigParser): | |
def __getitems__(self, section): | |
try: | |
return dict(self.items(section)) | |
except ConfigParser.NoSectionError: | |
raise KeyError(section) | |
def __generate__(self, conf_file): | |
try: | |
self.readfp(open(conf_file)) | |
except ConfigParser.Error, exc: | |
print >>sys.stderr, "manager.cfg error on parse ", exc | |
return 1 | |
except IOError, exc: | |
print >>sys.stderr, "failed to open manager.cfg ", exc | |
return 1 | |
self.auth = {"user" : "", "apikey" : ""} | |
if "auth" in self.sections(): | |
self.auth.update(self.__getitems__("auth")) | |
else: | |
print >>sys.stderr, "[auth] section not found in manager.cfg ", exc | |
return 1 | |
self.lb = {"master-id" : "", "slave-id" : ""} | |
if "lb" in self.sections(): | |
self.lb.update(self.__getitems__("lb")) | |
else: | |
print >>sys.stderr, "[lb] section not found in manager.cfg ", exc | |
class MHAUtils: | |
def print_config(self, lb): | |
print "%s (%s) %s SRC %s" % (lb.name, lb.id, lb.virtual_ips[0].address, | |
lb.sourceAddresses['ipv4Servicenet']) | |
for node in lb.nodes: | |
print " -- %s: %s (Server is currently %s)" % (node.address, | |
node.condition, node.status) | |
def verify_master(self, lb, master_address): | |
hit_count = 0 | |
errors = [] | |
writable_slaves = [] | |
for node in lb.nodes: | |
if node.address == master_address: | |
hit_count += 1 | |
if node.condition != 'ENABLED': | |
errors.append(1) | |
else: | |
if node.condition == 'ENABLED': | |
errors.append(2) | |
writable_slaves.append(node.address) | |
if hit_count != 1 or errors != []: | |
if hit_count == 0: | |
print >>sys.stderr, "Master Address %s not found in LB %s. Is this the correct IP / Load Balancer?" % (master_address, lb.name) | |
for error in errors: | |
if error == 1: | |
print >>sys.stderr, "Master Address %s is not listed as enabled" % (master_address) | |
if error == 2: | |
print >>sys.stderr, "Slave(s) are listed as enabled: %s" % (', '.join(writable_slaves)) | |
return 1 | |
else: | |
print "All checks completed successfully" | |
return 0 | |
def _set_node_status(self, lb, address, status): | |
print "setting node %s to %s on Load Balancer %s" % (address, status, lb.name) | |
for node in lb.nodes: | |
if node.address == address: | |
if node.condition != status: | |
node.condition = status | |
node.update() | |
pyrax.utils.wait_until(lb, "status", "ACTIVE", interval=1, | |
attempts=30, verbose=True) | |
print "Success: Node condition change complete" | |
return 0 | |
else: | |
print >>sys.stderr, "Warning: Target node (%s) is already set to condition %s" % (address, status) | |
return 0 | |
def disable_node(self, lb, address): | |
return self._set_node_status(lb, address, 'DISABLED') | |
def enable_node(self, lb, address): | |
return self._set_node_status(lb, address, 'ENABLED') | |
def auth(auth_profile): | |
pyrax.set_setting("identity_type", "rackspace") | |
pyrax.set_credentials(auth_profile['user'], auth_profile['apikey']) | |
def main(): | |
conf_file = '/etc/masterha/ip_manager.cnf' | |
config = Config() | |
config.__generate__(conf_file) | |
auth(config.auth) | |
mha_utils = MHAUtils() | |
lb_master = pyrax.cloud_loadbalancers.get(config.lb['master-id']) | |
lb_slave = pyrax.cloud_loadbalancers.get(config.lb['slave-id']) | |
mha_utils.print_config(lb_master) | |
mha_utils.print_config(lb_slave) | |
mha_options = ['command=', 'ssh_user=', 'orig_master_host=', | |
'orig_master_ip=', 'orig_master_port=', 'new_master_host=', | |
'new_master_ip=', 'new_master_port=', 'new_master_user=', | |
'new_master_password=' | |
] | |
direct_options = ['address='] | |
try: | |
options, arguments = getopt.getopt(sys.argv[1:], '', mha_options + direct_options) | |
except getopt.GetoptError as exc: | |
print str(exc) | |
return 1 | |
command = None | |
orig_master_ip = None | |
new_master_ip = None | |
for option, argument in options: | |
if option == '--command': | |
command = argument | |
elif option == '--orig_master_ip': | |
orig_master_ip = argument | |
elif option == '--new_master_ip': | |
new_master_ip = argument | |
if command == 'status': | |
return mha_utils.verify_master(lb_master, orig_master_ip) | |
elif command == 'stop' or command == 'stopssh': | |
lb_master_status = mha_utils.disable_node(lb_master, orig_master_ip) | |
lb_slave_status = mha_utils.disable_node(lb_slave, orig_master_ip) | |
return max(lb_master_status, lb_slave_status) | |
elif command == 'start': | |
lb_master_status = mha_utils.enable_node(lb_master, new_master_ip) | |
lb_slave_status = mha_utils.enable_node(lb_slave, new_master_ip) | |
return max(lb_master_status, lb_slave_status) | |
if __name__ == '__main__': | |
sys.exit(main()) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment