def convert_to_master(slave, args_array, **kwargs):
    """Function:  convert_to_master

    Description:  Creates MasterRep instance from a SlaveRep instance.

    Arguments:
        (input) slaves -> Slave instance array.
        (input) args_array -> Array of command line options and values.
        (output) master -> MasterRep instance.

    """

    slv_array = cmds_gen.create_cfg_array(args_array["-s"],
                                          cfg_path=args_array["-d"])

    for entry in slv_array:
        if slave.name == entry["name"] and slave.port == int(entry["port"]):
            rep_user = entry["rep_user"]
            rep_japd = entry["rep_japd"]
            break

    master = mysql_class.MasterRep(slave.name,
                                   slave.server_id,
                                   slave.sql_user,
                                   slave.sql_pass,
                                   slave.machine,
                                   host=slave.host,
                                   port=slave.port,
                                   defaults_file=slave.defaults_file,
                                   extra_def_file=slave.extra_def_file,
                                   rep_user=rep_user,
                                   rep_japd=rep_japd)
    master.connect()

    return master
def crt_slv_mst(slaves, **kwargs):
    """Function:  crt_slv_mst

    Description:  Creates the new master from an existing slave within the
        slave array.  Does ensure the slave is not in read-only mode.

    Arguments:
        (input) slaves -> Slave instance array.
        (input) **kwargs:
            new_mst -> Name of slave to be the new master.
        (output) new_master -> Class instance of new master.
        (output) err_flag -> True|False - if an error has occurred.
        (output) err_msg -> Error message.

    """

    slaves = list(slaves)
    err_flag = False
    err_msg = None
    new_master = None
    slv = mysql_libs.find_name(slaves, kwargs.get("new_mst"))

    if slv:

        if gen_libs.is_true(slv.read_only):
            err_flag = True
            err_msg = "Error:  New master %s is set to read-only mode." \
                      % (kwargs.get("new_mst"))

        # Assume slave is ready to be new master.
        else:
            new_master = mysql_class.MasterRep(
                slv.name,
                slv.server_id,
                slv.sql_user,
                slv.sql_pass,
                os_type=slv.machine,
                host=slv.host,
                port=slv.port,
                defaults_file=slv.defaults_file,
                extra_def_file=slv.extra_def_file,
                rep_user=slv.rep_user,
                rep_japd=slv.rep_japd)
            new_master.connect(silent=True)

            if new_master.conn_msg:
                err_flag = True
                err_msg = "Detected problem in new master connection"
                print("Error:  Connection problem for new master.")
                print("\tNew Master:  %s" % (new_master.conn_msg))

    else:
        err_flag = True
        err_msg = "Error: Slave(new master) %s was not found in slave array." \
                  % (kwargs.get("new_mst"))

    return new_master, err_flag, err_msg
def chk_rep(clone, args_array, **kwargs):
    """Function:  chk_rep

    Description:  Create master and slave instances and check the status of the
        replication system between the two servers.

    Arguments:
        (input) clone -> Destination server instance.
        (input) args_array -> Array of command line options and values.

    """

    args_array = dict(args_array)

    if "-n" not in args_array:
        cfg = gen_libs.load_module(args_array["-c"], args_array["-d"])
        master = mysql_class.MasterRep(cfg.name,
                                       cfg.sid,
                                       cfg.user,
                                       cfg.japd,
                                       os_type=getattr(machine, cfg.serv_os)(),
                                       host=cfg.host,
                                       port=cfg.port,
                                       defaults_file=cfg.cfg_file,
                                       extra_def_file=cfg.__dict__.get(
                                           "extra_def_file", None),
                                       rep_user=cfg.rep_user,
                                       rep_japd=cfg.rep_japd)
        master.connect()
        mysql_libs.change_master_to(master, clone)
        slave = mysql_libs.create_instance(args_array["-t"], args_array["-d"],
                                           mysql_class.SlaveRep)
        slave.connect()
        slave.start_slave()

        # Waiting for slave to start.
        time.sleep(5)
        master.upd_mst_status()
        slave.upd_slv_status()
        chk_slv_err([slave])
        chk_slv_thr([slave])
        chk_mst_log(master, [slave])
        cmds_gen.disconnect(master, slave)
def run_program(args_array, func_dict, **kwargs):

    """Function:  run_program

    Description:  Creates class instance(s) and controls flow of the program.

    Arguments:
        (input) args_array -> Array of command line options and values.
        (input) func_dict -> Dictionary list of functions and options.

    """

    args_array = dict(args_array)
    func_dict = dict(func_dict)
    master = None

    if "-c" in args_array:
        mst_cfg = gen_libs.load_module(args_array["-c"], args_array["-d"])

        master = mysql_class.MasterRep(
            mst_cfg.name, mst_cfg.sid, mst_cfg.user, mst_cfg.passwd,
            machine=getattr(machine, mst_cfg.serv_os)(), host=mst_cfg.host,
            port=mst_cfg.port, defaults_file=mst_cfg.cfg_file)
        master.connect()

    slaves = []

    if "-s" in args_array:
        slv_cfg = cmds_gen.create_cfg_array(args_array["-s"],
                                            cfg_path=args_array["-d"])
        slaves = mysql_libs.create_slv_array(slv_cfg)

    call_run_chk(args_array, func_dict, master, slaves)

    if master:
        cmds_gen.disconnect(master, slaves)

    else:
        cmds_gen.disconnect(slaves)
def create_instances(args_array, **kwargs):
    """Function:  create_instances

    Description:  Create a Master_Rep instance for master and Slave_Rep
        instances for slaves.  Slave instances will be appended to an array.

    Arguments:
        (input) args_array -> Array of command line options and values.
        (input) kwargs:
            slv_key -> Dictionary of keys and data types.
        (output) master -> Master instance.
        (output) slave -> Slave instance list.

    """

    args_array = dict(args_array)
    cfg = gen_libs.load_module(args_array["-c"], args_array["-d"])
    master = mysql_class.MasterRep(cfg.name,
                                   cfg.sid,
                                   cfg.user,
                                   cfg.japd,
                                   os_type=getattr(machine, cfg.serv_os)(),
                                   host=cfg.host,
                                   port=cfg.port,
                                   defaults_file=cfg.cfg_file,
                                   extra_def_file=cfg.__dict__.get(
                                       "extra_def_file", None),
                                   rep_user=cfg.rep_user,
                                   rep_japd=cfg.rep_japd)
    master.connect(silent=True)
    slaves = []
    slv_array = gen_libs.create_cfg_array(args_array["-s"],
                                          cfg_path=args_array["-d"])
    slv_array = gen_libs.transpose_dict(slv_array, kwargs.get("slv_key", {}))
    slaves = mysql_libs.create_slv_array(slv_array)

    return master, slaves
def move_slave_up(master, slaves, **kwargs):
    """Function:  move_slave_up

    Description:  Find the slave that will be moved, creates the new and slave
        master instances, sync up the databases between new master,
        slave/master and slave and then move the slave from the
        slave/master to the new master.

    Arguments:
        (input) master -> Master class instance.
        (input) slaves -> Slave instance array.
        (input) **kwargs:
            new_mst -> Name of slave to be the new master.
            slv_mv -> Name of slave to be moved to new master.
            args -> Array of command line options and values.
        (output) err_flag -> True|False - if an error has occurred.
        (output) err_msg -> Error message.

    """

    args_array = dict(kwargs.get("args"))
    slaves = list(slaves)
    slave_move, err_flag, err_msg = mysql_libs.fetch_slv(
        slaves, kwargs.get("slv_mv"))

    if err_flag:
        return err_flag, err_msg

    cfg = gen_libs.load_module(kwargs.get("new_mst"), args_array["-d"])
    new_master = mysql_class.MasterRep(cfg.name,
                                       cfg.sid,
                                       cfg.user,
                                       cfg.japd,
                                       os_type=getattr(machine, cfg.serv_os)(),
                                       host=cfg.host,
                                       port=cfg.port,
                                       defaults_file=cfg.cfg_file,
                                       extra_def_file=cfg.__dict__.get(
                                           "extra_def_file", None),
                                       rep_user=cfg.rep_user,
                                       rep_japd=cfg.rep_japd)
    new_master.connect(silent=True)
    slv_master = mysql_class.SlaveRep(master.name,
                                      master.server_id,
                                      master.sql_user,
                                      master.sql_pass,
                                      os_type=master.machine,
                                      host=master.host,
                                      port=master.port,
                                      defaults_file=master.defaults_file,
                                      rep_user=master.rep_user,
                                      rep_japd=master.rep_japd)
    slv_master.connect(silent=True)

    if new_master.conn_msg or slv_master.conn_msg:
        err_flag = True
        err_msg = "Detected problem in one of the connections"

        print("Error:  Connection problem for new master/slave master.")
        print("\tNew Master:  %s" % (new_master.conn_msg))
        print("\tSlave Master:  %s" % (slv_master.conn_msg))

        if new_master.conn:
            mysql_libs.disconnect(new_master)

        if slv_master.conn:
            mysql_libs.disconnect(slv_master)

    else:
        err_flag, err_msg = mysql_libs.sync_rep_slv(new_master, slv_master)

        if not err_flag:
            err_flag, err_msg = mysql_libs.sync_rep_slv(
                master, mysql_libs.find_name(slaves, kwargs.get("slv_mv")))

            if not err_flag:
                mysql_libs.change_master_to(new_master, slave_move)
                mysql_libs.chg_slv_state([slave_move, slv_master], "start")
                is_slv_up(slave_move)
                is_slv_up(slv_master)

        mysql_libs.disconnect(new_master, slv_master)

    return err_flag, err_msg