Skip to content

Instantly share code, notes, and snippets.

@abg
Forked from zastari/gist:9509625
Last active August 29, 2015 13:57
Show Gist options
  • Save abg/9626615 to your computer and use it in GitHub Desktop.
Save abg/9626615 to your computer and use it in GitHub Desktop.
#!/usr/bin/python
import ConfigParser
import logging
import optparse
import sys
import pyrax
error = logging.error
warn = logging.warn
info = logging.info
debug = logging.debug
class ConfigError(Exception):
"""Raised if an error is encountered parsing the configuration file"""
def load_config(path):
parser = ConfigParser.ConfigParser()
try:
with open(path, 'rb') as fileobj:
try:
parser.readfp(fileobj)
except ConfigParser.Error as exc:
raise ConfigError("manager.cfg error on parse: %s" % exc)
except IOError as exc:
raise ConfigError("Failed to open manager.cfg: %s" % exc)
# basic error checking
if not parser.has_section("auth"):
raise ConfigError("No [auth] section provided in %s" % path)
if not parser.has_section("lb"):
raise ConfigError("No [lb] section provided in %s" % path)
config = dict(auth={"user": "", "apikey": ""},
lb={"master-id": "", "slave-id": ""})
for name in parser.sections():
# skip unknown sections
if not name in config:
warn("Warning: skipping section [%s]", name)
continue
config[name].update(parser.items(name))
return config
def print_config(lb):
info("%s (%s) %s SRC %s", lb.name, lb.id, lb.virtual_ips[0].address,
lb.sourceAddresses['ipv4Servicenet'])
for node in lb.nodes:
info(" -- %s: %s (Server is currently %s)",
node.address, node.condition, node.status)
def verify_master(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:
error("Master Address %s not found in LB %s. "
"Is this the correct IP / Load Balancer?",
master_address, lb.name)
for err in errors:
if err == 1:
error("Master Address %s is not listed as enabled",
master_address)
if err == 2:
error("Slave(s) are listed as enabled: %s",
', '.join(writable_slaves))
return 1
else:
info("All checks completed successfully")
return 0
def _set_node_status(lb, address, status):
debug("setting node %s to %s on Load Balancer %s",
address, status, lb.name)
for node in lb.nodes:
if node.address != address:
continue
if node.condition != status:
node.condition = status
node.update()
pyrax.utils.wait_until(lb, "status", "ACTIVE",
interval=1, attempts=30, verbose=True)
info("Success: Node condition change complete")
return 0
else:
warn("Warning: Target node (%s) is already set to condition %s",
address, status)
return 0
error("%s not found in load balancer", address)
return 1
def disable_node(lb, address):
return _set_node_status(lb, address, 'DISABLED')
def enable_node(lb, address):
return _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():
logging.basicConfig(level=logging.DEBUG,
format='[%(levelname)s] %(asctime)s %(message)s')
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'
]
optparser = optparse.OptionParser()
for name in mha_options:
optparser.add_option("--" + name)
optparser.add_option("--address")
optparser.add_option("--config", "-c",
default="/etc/masterha/ip_manager.cnf",
help="Config file to use (default: %default)")
options, _ = optparser.parse_args()
command = options.command
orig_master_ip = options.orig_master_ip
new_master_ip = options.new_master_ip
try:
config = load_config(options.config)
except ConfigError as exc:
error("%s", exc)
return 1
auth(config['auth'])
lb_master = pyrax.cloud_loadbalancers.get(config['lb']['master-id'])
lb_slave = pyrax.cloud_loadbalancers.get(config['lb']['slave-id'])
print_config(lb_master)
print_config(lb_slave)
if command == 'status':
return verify_master(lb_master, orig_master_ip)
elif command == 'stop' or command == 'stopssh':
lb_master_status = disable_node(lb_master, orig_master_ip)
lb_slave_status = disable_node(lb_slave, orig_master_ip)
return max(lb_master_status, lb_slave_status)
elif command == 'start':
lb_master_status = enable_node(lb_master, new_master_ip)
lb_slave_status = 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