'%s status is %s',
                    server.uri, member.status
                ))
            elseif allowed_states ~= nil and next(allowed_states) ~= nil then
                local member_state = member.payload.state
                if fun.index(member_state, allowed_states) == nil then
                    table.insert(bad_members, string.format(
                    '%s state is %s',
                    server.uri, member_state
                ))
                end
            end
        end

        return bad_members
    ''', allowed_states)

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

    if bad_members:
        return helpers.ModuleRes(failed=True,
                                 msg="Some instances aren't alive: %s" %
                                 ', '.join(sorted(bad_members)))

    return helpers.ModuleRes(changed=False)


if __name__ == '__main__':
    helpers.execute_module(argument_spec, check_members_alive)
        return instance_vars['ansible_host']

    raise Exception('Instance %s has not "ansible_host" option!' %
                    instance_name)


def get_one_not_expelled_instance_for_machine(params):
    module_hostvars = params['module_hostvars']
    play_hosts = params['play_hosts']

    machine_hostnames = set()
    instance_names = []

    for instance_name in play_hosts:
        instance_vars = module_hostvars[instance_name]

        if helpers.is_expelled(instance_vars):
            continue

        machine_hostname = get_machine_hostname(instance_vars, instance_name)
        if machine_hostname not in machine_hostnames:
            machine_hostnames.add(machine_hostname)
            instance_names.append(instance_name)

    return helpers.ModuleRes(changed=False, fact=instance_names)


if __name__ == '__main__':
    helpers.execute_module(argument_spec,
                           get_one_not_expelled_instance_for_machine)
예제 #3
0
        remote_config_path=remote_config_path,
    )

    output_format, apply_config_func = get_output_format_and_apply_config_func(
        upload_mode,
        console_sock=params['console_sock'],
        upload_url=params['upload_url'],
        cluster_cookie=params['cluster_cookie'],
        tdg_token=params['tdg_token'],
    )

    temp_paths = [remote_config_path]
    new_config_path = prepare_config(remote_config_path, output_format,
                                     upload_mode)
    if new_config_path != remote_config_path:
        temp_paths.append(new_config_path)

    changed = apply_config_func(new_config_path)

    return helpers.ModuleRes(changed=changed,
                             fact={
                                 'temp_paths': temp_paths,
                                 'upload_url': params['upload_url'],
                                 'upload_mode': params['upload_mode'],
                                 'expected_format': output_format,
                             })


if __name__ == '__main__':
    helpers.execute_module(argument_spec, apply_app_config)
예제 #4
0
                end
            end

            return true
        ''')
        if not buckets_ok:
            return helpers.ModuleRes(failed=True, msg=err)

    return helpers.ModuleRes(changed=False)


def check_state(params):
    try:
        control_console = helpers.get_control_console(params['console_sock'])

        if params['stateboard']:
            return check_stateboard_state(control_console)
        else:
            return check_instance_state(
                control_console,
                params['expected_states'],
                params['check_buckets_are_discovered'],
            )

    except helpers.CartridgeException as e:
        return helpers.ModuleRes(exception=e)


if __name__ == '__main__':
    helpers.execute_module(argument_spec, check_state)

def get_package_info(params):
    package_path = params['package_path']
    app_name = params['app_name']

    package_type = get_package_type(package_path)

    if package_type == 'rpm':
        package_info = get_rpm_info(package_path)
    elif package_type == 'deb':
        package_info = get_deb_info(package_path)
    elif package_type == 'tgz':
        package_info = get_tgz_info(package_path)
    else:
        return helpers.ModuleRes(failed=True,
                                 msg='Unknown package type: %s' % package_type)

    if package_type != 'tgz' and package_info['name'] != app_name:
        msg = "Value 'cartridge_app_name' should be equal to package name. " + \
              "Found 'cartridge_app_name': '%s', package name: '%s'" % (app_name, package_info['name'])
        return helpers.ModuleRes(failed=True, msg=msg)

    package_info['type'] = package_type

    return helpers.ModuleRes(changed=False, fact=package_info)


if __name__ == '__main__':
    helpers.execute_module(argument_spec, get_package_info)
예제 #6
0
        allowed_errcodes = [
            helpers.CartridgeErrorCodes.SOCKET_NOT_FOUND,
            helpers.CartridgeErrorCodes.FAILED_TO_CONNECT_TO_SOCKET,
            helpers.CartridgeErrorCodes.INSTANCE_IS_NOT_STARTED_YET
        ]
        if e.code in allowed_errcodes:
            return helpers.ModuleRes(changed=True, fact=True)

        raise e

    if params['check_package_updated']:
        needs_restart, err = check_needs_restart_to_update_package(params)
        if err is not None:
            return helpers.ModuleRes(failed=True, msg=err)
        if needs_restart:
            return helpers.ModuleRes(changed=True, fact=True)

    if params['check_config_updated']:
        needs_restart, err = check_needs_restart_to_update_config(
            params, control_console)
        if err is not None:
            return helpers.ModuleRes(failed=True, msg=err)
        if needs_restart:
            return helpers.ModuleRes(changed=True, fact=True)

    return helpers.ModuleRes(changed=False, fact=False)


if __name__ == '__main__':
    helpers.execute_module(argument_spec, set_needs_restart)
예제 #7
0
    'upload_config_timeout': {'required': False, 'type': 'int'},
    'apply_config_timeout': {'required': False, 'type': 'int'},
}


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()


if __name__ == '__main__':
    helpers.execute_module(argument_spec, bootstrap_vshard)
    errmsg = check_app_config(found_common_params)
    if errmsg is not None:
        return helpers.ModuleRes(failed=True, msg=errmsg)

    # Failover
    errmsg = check_failover(found_common_params)
    if errmsg is not None:
        return helpers.ModuleRes(failed=True, msg=errmsg)

    # Scenario
    errmsg = check_scenario(found_common_params)
    if errmsg is not None:
        return helpers.ModuleRes(failed=True, msg=errmsg)

    # Failover promote params
    errmsg = check_failover_promote_params(found_common_params)
    if errmsg is not None:
        return helpers.ModuleRes(failed=True, msg=errmsg)

    if found_common_params.get('cartridge_failover') is not None:
        warnings.append(
            "Variable 'cartridge_failover' is deprecated since 1.3.0 and will be removed in 2.0.0. "
            "Use 'cartridge_failover_params' instead."
        )

    return helpers.ModuleRes(changed=False, warnings=warnings)


if __name__ == '__main__':
    helpers.execute_module(argument_spec, validate_config)
                                            timeout=CONNECTION_TIMEOUT)
            conn.settimeout(CONNECTION_TIMEOUT)
            conn.recv(1024)
        except socket.error:
            continue

        alive_not_expelled_instance_name = instance_name
        break

    if alive_not_expelled_instance_name is None:
        errmsg = "Not found any alive instance that is not expelled and is not a stateboard"
        return helpers.ModuleRes(failed=True, msg=errmsg)

    instance_vars = module_hostvars[alive_not_expelled_instance_name]
    run_dir = instance_vars.get('cartridge_run_dir')
    console_sock = helpers.get_instance_console_sock(
        run_dir,
        app_name,
        alive_not_expelled_instance_name,
    )

    return helpers.ModuleRes(changed=False,
                             fact={
                                 'name': alive_not_expelled_instance_name,
                                 'console_sock': console_sock,
                             })


if __name__ == '__main__':
    helpers.execute_module(argument_spec, get_alive_not_expelled_instance)
    control_instance_name, err = get_control_instance_name(
        module_hostvars, play_hosts, control_console)
    if err is not None:
        return helpers.ModuleRes(failed=True, msg=err)

    # in the ideal imagined world we could just use
    # instance_vars['instance_info'], but if control instance is not
    # in play_hosts, instance_info isn't computed for it
    instance_vars = module_hostvars[control_instance_name]

    run_dir = instance_vars.get('cartridge_run_dir')
    control_instance_console_sock = helpers.get_instance_console_sock(
        run_dir,
        app_name,
        control_instance_name,
    )

    http_port = instance_vars.get('config', {}).get('http_port')

    return helpers.ModuleRes(changed=False,
                             fact={
                                 'name': control_instance_name,
                                 'console_sock': control_instance_console_sock,
                                 'http_port': http_port,
                             })


if __name__ == '__main__':
    helpers.execute_module(argument_spec, get_control_instance)
예제 #11
0
def connect_to_membership(params):
    control_console = helpers.get_control_console(params['console_sock'])
    module_hostvars = params['module_hostvars']
    play_hosts = params['play_hosts']

    changed = False

    for instance_name, instance_vars in module_hostvars.items():
        if helpers.is_expelled(instance_vars) or helpers.is_stateboard(
                instance_vars):
            continue

        if 'config' not in instance_vars or 'advertise_uri' not in instance_vars[
                'config']:
            continue

        connected, err = probe_server(control_console,
                                      instance_vars['config']['advertise_uri'])
        if err is not None and instance_name in play_hosts:
            return helpers.ModuleRes(failed=True, msg=err)

        if connected:
            changed = True

    return helpers.ModuleRes(changed=changed)


if __name__ == '__main__':
    helpers.execute_module(argument_spec, connect_to_membership)
예제 #12
0
        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)


if __name__ == '__main__':
    helpers.execute_module(argument_spec, failover_promote)
예제 #13
0
        return False, None

    if not helpers.box_cfg_was_called(control_console):
        if strict_mode:
            return None, "Impossible to patch instance config: 'box.cfg' wasn't called"
        return False, None

    old_box_config = helpers.get_box_cfg(control_console)
    new_config = deepcopy(defaults or {})
    new_config.update(instance_config)

    return change_dynamic_params(control_console, old_box_config, new_config,
                                 strict_mode)


def patch_instance_in_runtime(params):
    console_sock = params['console_sock']
    instance_config = params['instance_config']
    cartridge_defaults = params['cartridge_defaults']
    strict_mode = params['strict_mode']

    changed, error = configure_box_cfg_params(console_sock, instance_config,
                                              cartridge_defaults, strict_mode)
    if error is not None:
        return helpers.ModuleRes(failed=True, msg=error)
    return helpers.ModuleRes(changed=changed)


if __name__ == '__main__':
    helpers.execute_module(argument_spec, patch_instance_in_runtime)
    # tmpfiles conf
    instance_info['tmpfiles_conf'] = os.path.join(
        instance_vars['cartridge_tmpfiles_dir'], '%s.conf' % app_name)

    # code dirs
    if not instance_vars['cartridge_multiversion']:
        dist_dir = os.path.join(instance_vars['cartridge_app_install_dir'],
                                app_name)

        instance_info['dist_dir'] = dist_dir
        instance_info['instance_dist_dir'] = dist_dir
    else:
        instance_info['dist_dir'] = get_multiversion_dist_dir(
            instance_vars['cartridge_app_install_dir'],
            instance_vars.get('cartridge_package_path'))

        instance_info[
            'instance_dist_dir'] = helpers.get_multiversion_instance_code_dir(
                instance_vars['cartridge_app_instances_dir'],
                app_name,
                instance_name,
                instance_vars['stateboard'],
            )

    return helpers.ModuleRes(changed=False, fact=instance_info)


if __name__ == '__main__':
    helpers.execute_module(argument_spec, get_instance_info)
예제 #15
0
            return None, "Unknown scenario '%s'" % scenario_name
        scenario = scenarios[scenario_name]

    return scenario, None


def get_scenario_steps(params):
    steps_paths = get_steps_paths(params['role_path'], params['custom_steps_dir'], params['custom_steps'])
    scenario, err = get_scenario(
        params['scenario'],
        params['role_scenarios'], params['custom_scenarios'], params['scenario_name'],
    )
    if err:
        return helpers.ModuleRes(failed=True, msg=err)

    scenario_steps = []
    for step_name in scenario:
        if step_name not in steps_paths:
            return helpers.ModuleRes(failed=True, msg="Unknown step '%s'" % step_name)

        scenario_steps.append({
            'name': step_name,
            'path': steps_paths[step_name],
        })

    return helpers.ModuleRes(changed=False, fact=scenario_steps)


if __name__ == '__main__':
    helpers.execute_module(argument_spec, get_scenario_steps)
예제 #16
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)


if __name__ == '__main__':
    helpers.execute_module(argument_spec, manage_failover)
}


def section_is_deleted(section):
    return 'deleted' in section and section['deleted'] is True


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)


if __name__ == '__main__':
    helpers.execute_module(argument_spec, config_app)
예제 #18
0
#!/usr/bin/env python

from ansible.module_utils.helpers import Helpers as helpers

argument_spec = {
    'console_sock': {'required': True, 'type': 'str'},
    'body': {'required': True, 'type': 'str'},
    'args': {'required': False, 'default': [], 'type': 'list'},
}


def eval_code(params):
    body = params['body']
    args = params['args']

    control_console = helpers.get_control_console(params['console_sock'])
    eval_res = control_console.eval(body, *args)

    return helpers.ModuleRes(changed=False, fact=eval_res)


if __name__ == '__main__':
    helpers.execute_module(argument_spec, eval_code)
        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)


if __name__ == '__main__':
    helpers.execute_module(argument_spec, edit_topology)
        'expelled',
        'stateboard',
    ],
}


def get_cached_facts(params):
    hostvars = params['hostvars']

    facts = {}
    for instance_name, instance_vars in hostvars.items():
        role_vars = hostvars[instance_name].get('role_facts', {})

        for target, fact_names in FACTS_BY_TARGETS.items():
            facts[target] = facts.get(target, {})
            facts[target][instance_name] = facts[target].get(instance_name, {})

            for fact_name in fact_names:
                if fact_name in role_vars:
                    facts[target][instance_name][fact_name] = role_vars[
                        fact_name]
                elif fact_name in instance_vars:
                    facts[target][instance_name][fact_name] = instance_vars[
                        fact_name]

    return helpers.ModuleRes(changed=False, facts=facts)


if __name__ == '__main__':
    helpers.execute_module(argument_spec, get_cached_facts)
예제 #21
0
        if issues is None:
            return helpers.ModuleRes(failed=True, msg=msg)

        helpers.warn(msg)

    issues_by_level = {}
    for issue in issues:
        level = issue['level']
        if level not in issues_by_level:
            issues_by_level[level] = []

        issues_by_level[level].append(issue)

    if show_issues:
        messages = get_messages(issues_by_level)
        helpers.warn(*messages)

    if issues:
        if allow_warnings:
            critical_issues_num = len(issues) - len(issues_by_level.get('warning', []))
            if critical_issues_num > 0:
                return helpers.ModuleRes(failed=True, msg="Cluster has %s critical issues" % critical_issues_num)
        else:
            return helpers.ModuleRes(failed=True, msg="Cluster has %s issues" % len(issues))

    return helpers.ModuleRes(changed=False)


if __name__ == '__main__':
    helpers.execute_module(argument_spec, check_cluster_issues)