Exemple #1
0
def manage_failover(params):
    failover_params = params.get('failover_params')

    if isinstance(failover_params, bool):
        failover_params = {
            'mode': 'eventual' if failover_params is True else 'disabled'
        }

    rename_dict_key_if_exists(failover_params, 'stateboard_params',
                              'tarantool_params')
    if failover_params.get('state_provider') == 'stateboard':
        failover_params['state_provider'] = 'tarantool'

    control_console = helpers.get_control_console(params['console_sock'])

    helpers.set_twophase_options_from_params(control_console, params)

    version = get_tarantool_version(control_console)
    if version is not None and version >= NEW_FAILOVER_API_CARTRIDGE_VERSION:
        return manage_failover_new(control_console, failover_params)
    else:
        if failover_params['mode'] == 'stateful':
            errmsg = 'Stateful failover is supported since cartridge {}'.format(
                NEW_FAILOVER_API_CARTRIDGE_VERSION)
            return helpers.ModuleRes(failed=True, msg=errmsg)
        return manage_failover_old(control_console, failover_params)
def config_app(params):
    control_console = helpers.get_control_console(params['console_sock'])
    config = params['app_config']

    new_sections = {}
    for section_name, section in config.items():
        if section_is_deleted(section):
            new_sections[section_name] = None
        else:
            new_sections[section_name] = section.get('body')

    helpers.set_twophase_options_from_params(control_console, params)

    changed, err = helpers.patch_clusterwide_config(control_console,
                                                    new_sections)
    if err is not None:
        return helpers.ModuleRes(failed=True, msg=err)

    return helpers.ModuleRes(changed=changed)
Exemple #3
0
def bootstrap_vshard(params):
    control_console = helpers.get_control_console(params['console_sock'])

    helpers.set_twophase_options_from_params(control_console, params)

    can_bootstrap, _ = control_console.eval_res_err('''
        return require('cartridge.vshard-utils').can_bootstrap()
    ''')

    if not can_bootstrap:
        return helpers.ModuleRes(changed=False)

    ok, err = control_console.eval_res_err('''
        return require('cartridge.admin').bootstrap_vshard()
    ''')

    if not ok:
        errmsg = 'Vshard bootstrap failed: {}'.format(err)
        return helpers.ModuleRes(failed=True, msg=errmsg)

    return helpers.ModuleRes()
def edit_topology(params):
    console_sock = params['console_sock']
    module_hostvars = params['module_hostvars']
    play_hosts = params['play_hosts']
    healthy_timeout = params['healthy_timeout']
    allow_missed_instances = params['allow_missed_instances']

    replicasets = get_configured_replicasets(module_hostvars, play_hosts)
    instances = get_instances_to_configure(module_hostvars, play_hosts)

    if not replicasets and not instances:
        return helpers.ModuleRes(changed=False)

    control_console = helpers.get_control_console(console_sock)

    helpers.set_twophase_options_from_params(control_console, params)
    set_enabled_roles(replicasets, control_console)

    cluster_instances = helpers.get_cluster_instances(control_console)
    cluster_replicasets = helpers.get_cluster_replicasets(control_console)

    # Configure replicasets and instances:
    # * Create new replicasets.
    # * Edit existent replicasets and join new instances to them.
    #   In this case failover_priority isn't changed since
    #   new instances hasn't UUIDs before join.
    # * Expel instances.
    # * Configure instances that are already joined.
    #   New instances aren't configured here since they don't have
    #   UUIDs before join.
    topology_params, err = get_topology_params(replicasets,
                                               cluster_replicasets, instances,
                                               cluster_instances,
                                               allow_missed_instances)
    if err is not None:
        return helpers.ModuleRes(
            failed=True,
            msg="Failed to collect edit topology params: %s" % err)

    topology_changed = False

    if topology_params:
        res, err = control_console.eval_res_err(edit_topology_func_body,
                                                topology_params)
        if err is not None:
            return helpers.ModuleRes(failed=True,
                                     msg="Failed to edit topology: %s" % err)

        topology_changed = True

        # Without this `Peer closed` error is returned on second `edit_topology`
        # call in some cases (e.g. when new instance is joined at first call
        # and then it's configured on second)
        # See https://github.com/tarantool/cartridge/issues/1320
        # The simplest w/a is to add a little delay between this calls,
        # and we just perform `is_healthy` call here.
        # If everything is Ok - this call doesn't take a long time, but
        # guarantees that next `edit_topology` call wouldn't fail.
        # If cluster isn't healthy then it's good to show error.
        if not wait_for_cluster_is_healthy(control_console, healthy_timeout):
            return helpers.ModuleRes(
                failed=True,
                msg="Cluster isn't healthy after editing topology")

        # Now we need to get updated instances and replicasets
        # configuration to check if we need one more call.
        # `edit_topology` returns summary of updated instances
        # so let's use it to update cluster_instances and cluster_replicasets.
        update_cluster_instances_and_replicasets(res, instances,
                                                 cluster_instances,
                                                 cluster_replicasets)

    # Configure failover_priority and instances that were joined on previous call:
    # * Edit failover_priority of replicasets if it's needed.
    # * Configure instances that weren't configured on first `edit_topology` call.
    topology_params, err = get_replicasets_failover_priority_and_instances_params(
        replicasets, cluster_replicasets, instances, cluster_instances,
        allow_missed_instances)
    if err is not None:
        return helpers.ModuleRes(
            failed=True,
            msg=
            "Failed to collect edit topology params for changing failover_priority "
            "and configuring new instances: %s" % err)

    if topology_params:
        res, err = control_console.eval_res_err(edit_topology_func_body,
                                                topology_params)
        if err is not None:
            return helpers.ModuleRes(
                failed=True,
                msg=
                "Failed to edit failover priority and configure instances: %s"
                % err)

        topology_changed = True

        if not wait_for_cluster_is_healthy(control_console, healthy_timeout):
            return helpers.ModuleRes(
                failed=True,
                msg=
                "Cluster isn't healthy after editing failover priority and configuring instances"
            )

    return helpers.ModuleRes(changed=topology_changed)
Exemple #5
0
def failover_promote(params):
    console_sock = params['console_sock']
    control_console = helpers.get_control_console(console_sock)

    err = check_leaders_promotion_is_possible(control_console)
    if err is not None:
        return helpers.ModuleRes(failed=True, msg=err)

    failover_promote_params = params.get('failover_promote_params')
    if failover_promote_params is None:
        failover_promote_params = {}

    critical_warnings = []

    # get replicaset leaders
    if params['promote_play_hosts']:
        module_hostvars = params['module_hostvars']
        play_hosts = params['play_hosts']

        replicaset_leaders, dead_replicasets = get_replicaset_leaders_by_play_hosts(
            play_hosts, module_hostvars, control_console)
        if dead_replicasets:
            critical_warnings.append(
                'These replicasets have no alive instances across specified play hosts: %s'
                % ', '.join(sorted(dead_replicasets)))
    else:
        specified_replicaset_leaders = failover_promote_params.get(
            'replicaset_leaders')

        replicaset_leaders, err = get_replicaset_leaders_by_aliases(
            specified_replicaset_leaders, control_console)

        if err is not None:
            return helpers.ModuleRes(failed=True, msg=err)

    if not replicaset_leaders:
        if critical_warnings:
            return helpers.ModuleRes(
                failed=True,
                msg="Failed to promote leaders: %s" % err,
                warnings=critical_warnings,
            )
        return helpers.ModuleRes(changed=False)

    force_inconsistency = failover_promote_params.get('force_inconsistency')

    # set two-phase commit opts
    helpers.set_twophase_options_from_params(control_console, params)

    active_leaders = get_active_leaders(control_console)

    _, err = call_failover_promote(control_console, replicaset_leaders,
                                   force_inconsistency)
    if err is not None:
        return helpers.ModuleRes(
            failed=True,
            msg="Failed to promote leaders: %s" % err,
            warnings=critical_warnings,
        )

    new_active_leaders = get_active_leaders(control_console)

    if critical_warnings:
        return helpers.ModuleRes(failed=True,
                                 msg="Promoted with critical warnings",
                                 warnings=critical_warnings)

    return helpers.ModuleRes(changed=active_leaders != new_active_leaders)