Exemple #1
0
def main():
    argument_spec = mysql_common_argument_spec()
    argument_spec.update(
        login_db=dict(type='str'),
        filter=dict(type='list'),
        exclude_fields=dict(type='list'),
        return_empty_dbs=dict(type='bool', default=False),
    )

    module = AnsibleModule(
        argument_spec=argument_spec,
        supports_check_mode=True,
    )

    db = module.params['login_db']
    connect_timeout = module.params['connect_timeout']
    login_user = module.params['login_user']
    login_password = module.params['login_password']
    ssl_cert = module.params['client_cert']
    ssl_key = module.params['client_key']
    ssl_ca = module.params['ca_cert']
    config_file = module.params['config_file']
    filter_ = module.params['filter']
    exclude_fields = module.params['exclude_fields']
    return_empty_dbs = module.params['return_empty_dbs']

    if filter_:
        filter_ = [f.strip() for f in filter_]

    if exclude_fields:
        exclude_fields = set([f.strip() for f in exclude_fields])

    if mysql_driver is None:
        module.fail_json(msg=mysql_driver_fail_msg)

    try:
        cursor, db_conn = mysql_connect(module,
                                        login_user,
                                        login_password,
                                        config_file,
                                        ssl_cert,
                                        ssl_key,
                                        ssl_ca,
                                        db,
                                        connect_timeout=connect_timeout,
                                        cursor_class='DictCursor')
    except Exception as e:
        module.fail_json(
            msg=
            "unable to connect to database, check login_user and login_password are correct or %s has the credentials. "
            "Exception message: %s" % (config_file, to_native(e)))

    ###############################
    # Create object and do main job

    mysql = MySQL_Info(module, cursor)

    module.exit_json(changed=False,
                     **mysql.get_info(filter_, exclude_fields,
                                      return_empty_dbs))
def main():
    argument_spec = mysql_common_argument_spec()
    argument_spec.update(
        variable=dict(type='str'),
        value=dict(type='str'),
        mode=dict(type='str',
                  choices=['global', 'persist', 'persist_only'],
                  default='global'),
    )

    module = AnsibleModule(argument_spec=argument_spec)
    user = module.params["login_user"]
    password = module.params["login_password"]
    connect_timeout = module.params['connect_timeout']
    ssl_cert = module.params["client_cert"]
    ssl_key = module.params["client_key"]
    ssl_ca = module.params["ca_cert"]
    check_hostname = module.params["check_hostname"]
    config_file = module.params['config_file']
    db = 'mysql'

    mysqlvar = module.params["variable"]
    value = module.params["value"]
    mode = module.params["mode"]

    if mysqlvar is None:
        module.fail_json(msg="Cannot run without variable to operate with")
    if match('^[0-9a-z_.]+$', mysqlvar) is None:
        module.fail_json(msg="invalid variable name \"%s\"" % mysqlvar)
    if mysql_driver is None:
        module.fail_json(msg=mysql_driver_fail_msg)
    else:
        warnings.filterwarnings('error', category=mysql_driver.Warning)

    try:
        cursor, db_conn = mysql_connect(module,
                                        user,
                                        password,
                                        config_file,
                                        ssl_cert,
                                        ssl_key,
                                        ssl_ca,
                                        db,
                                        connect_timeout=connect_timeout,
                                        check_hostname=check_hostname)
    except Exception as e:
        if os.path.exists(config_file):
            module.fail_json(
                msg=("unable to connect to database, check login_user and "
                     "login_password are correct or %s has the credentials. "
                     "Exception message: %s" % (config_file, to_native(e))))
        else:
            module.fail_json(msg="unable to find %s. Exception message: %s" %
                             (config_file, to_native(e)))

    mysqlvar_val = None
    var_in_mysqld_auto_cnf = None

    mysqlvar_val = getvariable(cursor, mysqlvar)
    if mysqlvar_val is None:
        module.fail_json(msg="Variable not available \"%s\"" % mysqlvar,
                         changed=False)

    if value is None:
        module.exit_json(msg=mysqlvar_val)

    if mode in ('persist', 'persist_only'):
        var_in_mysqld_auto_cnf = check_mysqld_auto(module, cursor, mysqlvar)

        if mode == 'persist_only':
            if var_in_mysqld_auto_cnf is None:
                mysqlvar_val = False
            else:
                mysqlvar_val = var_in_mysqld_auto_cnf

    # Type values before using them
    value_wanted = typedvalue(value)
    value_actual = typedvalue(mysqlvar_val)
    value_in_auto_cnf = None
    if var_in_mysqld_auto_cnf is not None:
        value_in_auto_cnf = typedvalue(var_in_mysqld_auto_cnf)

    if value_wanted == value_actual and mode in ('global', 'persist'):
        if mode == 'persist' and value_wanted == value_in_auto_cnf:
            module.exit_json(
                msg="Variable is already set to requested value globally"
                "and stored into mysqld-auto.cnf file.",
                changed=False)

        elif mode == 'global':
            module.exit_json(msg="Variable is already set to requested value.",
                             changed=False)

    if mode == 'persist_only' and value_wanted == value_in_auto_cnf:
        module.exit_json(msg="Variable is already stored into mysqld-auto.cnf "
                         "with requested value.",
                         changed=False)

    try:
        result = setvariable(cursor, mysqlvar, value_wanted, mode)
    except SQLParseError as e:
        result = to_native(e)

    if result is True:
        module.exit_json(msg="Variable change succeeded prev_value=%s" %
                         value_actual,
                         changed=True,
                         queries=executed_queries)
    else:
        module.fail_json(msg=result, changed=False)
Exemple #3
0
def main():
    module = AnsibleModule(
        argument_spec=dict(
            login_user=dict(type='str'),
            login_password=dict(type='str', no_log=True),
            login_host=dict(type='str', default='localhost'),
            login_port=dict(type='int', default=3306),
            login_unix_socket=dict(type='str'),
            user=dict(type='str', required=True, aliases=['name']),
            password=dict(type='str', no_log=True),
            encrypted=dict(type='bool', default=False),
            host=dict(type='str', default='localhost'),
            host_all=dict(type="bool", default=False),
            state=dict(type='str', default='present', choices=['absent', 'present']),
            priv=dict(type='raw'),
            append_privs=dict(type='bool', default=False),
            check_implicit_admin=dict(type='bool', default=False),
            update_password=dict(type='str', default='always', choices=['always', 'on_create'], no_log=False),
            connect_timeout=dict(type='int', default=30),
            config_file=dict(type='path', default='~/.my.cnf'),
            sql_log_bin=dict(type='bool', default=True),
            client_cert=dict(type='path', aliases=['ssl_cert']),
            client_key=dict(type='path', aliases=['ssl_key']),
            ca_cert=dict(type='path', aliases=['ssl_ca']),
            plugin=dict(default=None, type='str'),
            plugin_hash_string=dict(default=None, type='str'),
            plugin_auth_string=dict(default=None, type='str'),
            resource_limits=dict(type='dict'),
        ),
        supports_check_mode=True,
    )
    login_user = module.params["login_user"]
    login_password = module.params["login_password"]
    user = module.params["user"]
    password = module.params["password"]
    encrypted = module.boolean(module.params["encrypted"])
    host = module.params["host"].lower()
    host_all = module.params["host_all"]
    state = module.params["state"]
    priv = module.params["priv"]
    check_implicit_admin = module.params['check_implicit_admin']
    connect_timeout = module.params['connect_timeout']
    config_file = module.params['config_file']
    append_privs = module.boolean(module.params["append_privs"])
    update_password = module.params['update_password']
    ssl_cert = module.params["client_cert"]
    ssl_key = module.params["client_key"]
    ssl_ca = module.params["ca_cert"]
    db = ''
    sql_log_bin = module.params["sql_log_bin"]
    plugin = module.params["plugin"]
    plugin_hash_string = module.params["plugin_hash_string"]
    plugin_auth_string = module.params["plugin_auth_string"]
    resource_limits = module.params["resource_limits"]
    if priv and not (isinstance(priv, str) or isinstance(priv, dict)):
        module.fail_json(msg="priv parameter must be str or dict but %s was passed" % type(priv))

    if priv and isinstance(priv, dict):
        priv = convert_priv_dict_to_str(priv)

    if mysql_driver is None:
        module.fail_json(msg=mysql_driver_fail_msg)

    cursor = None
    try:
        if check_implicit_admin:
            try:
                cursor, db_conn = mysql_connect(module, 'root', '', config_file, ssl_cert, ssl_key, ssl_ca, db,
                                                connect_timeout=connect_timeout)
            except Exception:
                pass

        if not cursor:
            cursor, db_conn = mysql_connect(module, login_user, login_password, config_file, ssl_cert, ssl_key, ssl_ca, db,
                                            connect_timeout=connect_timeout)
    except Exception as e:
        module.fail_json(msg="unable to connect to database, check login_user and login_password are correct or %s has the credentials. "
                             "Exception message: %s" % (config_file, to_native(e)))

    if not sql_log_bin:
        cursor.execute("SET SQL_LOG_BIN=0;")

    if priv is not None:
        try:
            mode = get_mode(cursor)
        except Exception as e:
            module.fail_json(msg=to_native(e))
        try:
            priv = privileges_unpack(priv, mode)
        except Exception as e:
            module.fail_json(msg="invalid privileges string: %s" % to_native(e))

    if state == "present":
        if user_exists(cursor, user, host, host_all):
            try:
                if update_password == 'always':
                    changed, msg = user_mod(cursor, user, host, host_all, password, encrypted,
                                            plugin, plugin_hash_string, plugin_auth_string,
                                            priv, append_privs, module)
                else:
                    changed, msg = user_mod(cursor, user, host, host_all, None, encrypted,
                                            plugin, plugin_hash_string, plugin_auth_string,
                                            priv, append_privs, module)

            except (SQLParseError, InvalidPrivsError, mysql_driver.Error) as e:
                module.fail_json(msg=to_native(e))
        else:
            if host_all:
                module.fail_json(msg="host_all parameter cannot be used when adding a user")
            try:
                changed = user_add(cursor, user, host, host_all, password, encrypted,
                                   plugin, plugin_hash_string, plugin_auth_string,
                                   priv, module.check_mode)
                if changed:
                    msg = "User added"

            except (SQLParseError, InvalidPrivsError, mysql_driver.Error) as e:
                module.fail_json(msg=to_native(e))

        if resource_limits:
            changed = limit_resources(module, cursor, user, host, resource_limits, module.check_mode) or changed

    elif state == "absent":
        if user_exists(cursor, user, host, host_all):
            changed = user_delete(cursor, user, host, host_all, module.check_mode)
            msg = "User deleted"
        else:
            changed = False
            msg = "User doesn't exist"
    module.exit_json(changed=changed, user=user, msg=msg)
def main():
    argument_spec = mysql_common_argument_spec()
    argument_spec.update(
        user=dict(type='str', required=True, aliases=['name']),
        password=dict(type='str', no_log=True),
        encrypted=dict(type='bool', default=False),
        host=dict(type='str', default='localhost'),
        host_all=dict(type="bool", default=False),
        state=dict(type='str', default='present', choices=['absent', 'present']),
        priv=dict(type='raw'),
        tls_requires=dict(type='dict'),
        append_privs=dict(type='bool', default=False),
        check_implicit_admin=dict(type='bool', default=False),
        update_password=dict(type='str', default='always', choices=['always', 'on_create'], no_log=False),
        sql_log_bin=dict(type='bool', default=True),
        plugin=dict(default=None, type='str'),
        plugin_hash_string=dict(default=None, type='str'),
        plugin_auth_string=dict(default=None, type='str'),
        resource_limits=dict(type='dict'),
    )
    module = AnsibleModule(
        argument_spec=argument_spec,
        supports_check_mode=True,
    )
    login_user = module.params["login_user"]
    login_password = module.params["login_password"]
    user = module.params["user"]
    password = module.params["password"]
    encrypted = module.boolean(module.params["encrypted"])
    host = module.params["host"].lower()
    host_all = module.params["host_all"]
    state = module.params["state"]
    priv = module.params["priv"]
    tls_requires = sanitize_requires(module.params["tls_requires"])
    check_implicit_admin = module.params["check_implicit_admin"]
    connect_timeout = module.params["connect_timeout"]
    config_file = module.params["config_file"]
    append_privs = module.boolean(module.params["append_privs"])
    update_password = module.params['update_password']
    ssl_cert = module.params["client_cert"]
    ssl_key = module.params["client_key"]
    ssl_ca = module.params["ca_cert"]
    check_hostname = module.params["check_hostname"]
    db = ''
    sql_log_bin = module.params["sql_log_bin"]
    plugin = module.params["plugin"]
    plugin_hash_string = module.params["plugin_hash_string"]
    plugin_auth_string = module.params["plugin_auth_string"]
    resource_limits = module.params["resource_limits"]
    if priv and not isinstance(priv, (str, dict)):
        module.fail_json(msg="priv parameter must be str or dict but %s was passed" % type(priv))

    if priv and isinstance(priv, dict):
        priv = convert_priv_dict_to_str(priv)

    if priv and "REQUIRESSL" in priv:
        priv, tls_requires = handle_requiressl_in_priv_string(module, priv, tls_requires)

    if mysql_driver is None:
        module.fail_json(msg=mysql_driver_fail_msg)

    cursor = None
    try:
        if check_implicit_admin:
            try:
                cursor, db_conn = mysql_connect(module, "root", "", config_file, ssl_cert, ssl_key, ssl_ca, db,
                                                connect_timeout=connect_timeout, check_hostname=check_hostname)
            except Exception:
                pass

        if not cursor:
            cursor, db_conn = mysql_connect(module, login_user, login_password, config_file, ssl_cert, ssl_key, ssl_ca, db,
                                            connect_timeout=connect_timeout, check_hostname=check_hostname)
    except Exception as e:
        module.fail_json(msg="unable to connect to database, check login_user and login_password are correct or %s has the credentials. "
                             "Exception message: %s" % (config_file, to_native(e)))

    if not sql_log_bin:
        cursor.execute("SET SQL_LOG_BIN=0;")

    global impl
    cursor.execute("SELECT VERSION()")
    if 'mariadb' in cursor.fetchone()[0].lower():
        from ansible_collections.community.mysql.plugins.module_utils.implementations.mariadb import user as mysqluser
        impl = mysqluser
    else:
        from ansible_collections.community.mysql.plugins.module_utils.implementations.mysql import user as mariauser
        impl = mariauser

    if priv is not None:
        try:
            mode = get_mode(cursor)
        except Exception as e:
            module.fail_json(msg=to_native(e))
        try:
            priv = privileges_unpack(priv, mode)
        except Exception as e:
            module.fail_json(msg="invalid privileges string: %s" % to_native(e))

    if state == "present":
        if user_exists(cursor, user, host, host_all):
            try:
                if update_password == "always":
                    changed, msg = user_mod(cursor, user, host, host_all, password, encrypted,
                                            plugin, plugin_hash_string, plugin_auth_string,
                                            priv, append_privs, tls_requires, module)
                else:
                    changed, msg = user_mod(cursor, user, host, host_all, None, encrypted,
                                            plugin, plugin_hash_string, plugin_auth_string,
                                            priv, append_privs, tls_requires, module)

            except (SQLParseError, InvalidPrivsError, mysql_driver.Error) as e:
                module.fail_json(msg=to_native(e))
        else:
            if host_all:
                module.fail_json(msg="host_all parameter cannot be used when adding a user")
            try:
                changed = user_add(cursor, user, host, host_all, password, encrypted,
                                   plugin, plugin_hash_string, plugin_auth_string,
                                   priv, tls_requires, module.check_mode)
                if changed:
                    msg = "User added"

            except (SQLParseError, InvalidPrivsError, mysql_driver.Error) as e:
                module.fail_json(msg=to_native(e))

        if resource_limits:
            changed = limit_resources(module, cursor, user, host, resource_limits, module.check_mode) or changed

    elif state == "absent":
        if user_exists(cursor, user, host, host_all):
            changed = user_delete(cursor, user, host, host_all, module.check_mode)
            msg = "User deleted"
        else:
            changed = False
            msg = "User doesn't exist"
    module.exit_json(changed=changed, user=user, msg=msg)
Exemple #5
0
def main():
    argument_spec = mysql_common_argument_spec()
    argument_spec.update(
        name=dict(type='list', required=True, aliases=['db']),
        encoding=dict(type='str', default=''),
        collation=dict(type='str', default=''),
        target=dict(type='path'),
        state=dict(type='str', default='present', choices=['absent', 'dump', 'import', 'present']),
        single_transaction=dict(type='bool', default=False),
        quick=dict(type='bool', default=True),
        ignore_tables=dict(type='list', default=[]),
        hex_blob=dict(default=False, type='bool'),
        force=dict(type='bool', default=False),
        master_data=dict(type='int', default=0, choices=[0, 1, 2]),
        skip_lock_tables=dict(type='bool', default=False),
        dump_extra_args=dict(type='str'),
        use_shell=dict(type='bool', default=False),
        unsafe_login_password=dict(type='bool', default=False, no_log=True),
        restrict_config_file=dict(type='bool', default=False),
        check_implicit_admin=dict(type='bool', default=False),
        config_overrides_defaults=dict(type='bool', default=False),
    )

    module = AnsibleModule(
        argument_spec=argument_spec,
        supports_check_mode=True,
    )

    if mysql_driver is None:
        module.fail_json(msg=mysql_driver_fail_msg)

    db = module.params["name"]
    if not db:
        module.exit_json(changed=False, db=db, db_list=[])
    db = [each_db.strip() for each_db in db]

    encoding = module.params["encoding"]
    collation = module.params["collation"]
    state = module.params["state"]
    target = module.params["target"]
    socket = module.params["login_unix_socket"]
    login_port = module.params["login_port"]
    if login_port < 0 or login_port > 65535:
        module.fail_json(msg="login_port must be a valid unix port number (0-65535)")
    ssl_cert = module.params["client_cert"]
    ssl_key = module.params["client_key"]
    ssl_ca = module.params["ca_cert"]
    check_hostname = module.params["check_hostname"]
    connect_timeout = module.params['connect_timeout']
    config_file = module.params['config_file']
    login_password = module.params["login_password"]
    unsafe_login_password = module.params["unsafe_login_password"]
    login_user = module.params["login_user"]
    login_host = module.params["login_host"]
    ignore_tables = module.params["ignore_tables"]
    for a_table in ignore_tables:
        if a_table == "":
            module.fail_json(msg="Name of ignored table cannot be empty")
    single_transaction = module.params["single_transaction"]
    quick = module.params["quick"]
    hex_blob = module.params["hex_blob"]
    force = module.params["force"]
    master_data = module.params["master_data"]
    skip_lock_tables = module.params["skip_lock_tables"]
    dump_extra_args = module.params["dump_extra_args"]
    use_shell = module.params["use_shell"]
    restrict_config_file = module.params["restrict_config_file"]
    check_implicit_admin = module.params['check_implicit_admin']
    config_overrides_defaults = module.params['config_overrides_defaults']

    if len(db) > 1 and state == 'import':
        module.fail_json(msg="Multiple databases are not supported with state=import")
    db_name = ' '.join(db)

    all_databases = False
    if state in ['dump', 'import']:
        if target is None:
            module.fail_json(msg="with state=%s target is required" % state)
        if db == ['all']:
            all_databases = True
    else:
        if db == ['all']:
            module.fail_json(msg="name is not allowed to equal 'all' unless state equals import, or dump.")
    try:
        cursor = None
        if check_implicit_admin:
            try:
                cursor, db_conn = mysql_connect(module, 'root', '', config_file, ssl_cert, ssl_key, ssl_ca,
                                                connect_timeout=connect_timeout, check_hostname=check_hostname,
                                                config_overrides_defaults=config_overrides_defaults)
            except Exception as e:
                check_implicit_admin = False
                pass

        if not cursor:
            cursor, db_conn = mysql_connect(module, login_user, login_password, config_file, ssl_cert, ssl_key, ssl_ca,
                                            connect_timeout=connect_timeout, config_overrides_defaults=config_overrides_defaults,
                                            check_hostname=check_hostname)
    except Exception as e:
        if os.path.exists(config_file):
            module.fail_json(msg="unable to connect to database, check login_user and login_password are correct or %s has the credentials. "
                                 "Exception message: %s" % (config_file, to_native(e)))
        else:
            module.fail_json(msg="unable to find %s. Exception message: %s" % (config_file, to_native(e)))

    changed = False
    if not os.path.exists(config_file):
        config_file = None

    existence_list = []
    non_existence_list = []

    if not all_databases:
        for each_database in db:
            if db_exists(cursor, [each_database]):
                existence_list.append(each_database)
            else:
                non_existence_list.append(each_database)

    if state == "absent":
        if module.check_mode:
            module.exit_json(changed=bool(existence_list), db=db_name, db_list=db)
        try:
            changed = db_delete(cursor, existence_list)
        except Exception as e:
            module.fail_json(msg="error deleting database: %s" % to_native(e))
        module.exit_json(changed=changed, db=db_name, db_list=db, executed_commands=executed_commands)
    elif state == "present":
        if module.check_mode:
            module.exit_json(changed=bool(non_existence_list), db=db_name, db_list=db)
        changed = False
        if non_existence_list:
            try:
                changed = db_create(cursor, non_existence_list, encoding, collation)
            except Exception as e:
                module.fail_json(msg="error creating database: %s" % to_native(e),
                                 exception=traceback.format_exc())
        module.exit_json(changed=changed, db=db_name, db_list=db, executed_commands=executed_commands)
    elif state == "dump":
        if non_existence_list and not all_databases:
            module.fail_json(msg="Cannot dump database(s) %r - not found" % (', '.join(non_existence_list)))
        if module.check_mode:
            module.exit_json(changed=True, db=db_name, db_list=db)
        rc, stdout, stderr = db_dump(module, login_host, login_user,
                                     login_password, db, target, all_databases,
                                     login_port, config_file, socket, ssl_cert, ssl_key,
                                     ssl_ca, single_transaction, quick, ignore_tables,
                                     hex_blob, encoding, force, master_data, skip_lock_tables,
                                     dump_extra_args, unsafe_login_password, restrict_config_file,
                                     check_implicit_admin)
        if rc != 0:
            module.fail_json(msg="%s" % stderr)
        module.exit_json(changed=True, db=db_name, db_list=db, msg=stdout,
                         executed_commands=executed_commands)
    elif state == "import":
        if module.check_mode:
            module.exit_json(changed=True, db=db_name, db_list=db)
        if non_existence_list and not all_databases:
            try:
                db_create(cursor, non_existence_list, encoding, collation)
            except Exception as e:
                module.fail_json(msg="error creating database: %s" % to_native(e),
                                 exception=traceback.format_exc())
        rc, stdout, stderr = db_import(module, login_host, login_user,
                                       login_password, db, target,
                                       all_databases,
                                       login_port, config_file,
                                       socket, ssl_cert, ssl_key, ssl_ca,
                                       encoding, force, use_shell, unsafe_login_password,
                                       restrict_config_file, check_implicit_admin)
        if rc != 0:
            module.fail_json(msg="%s" % stderr)
        module.exit_json(changed=True, db=db_name, db_list=db, msg=stdout,
                         executed_commands=executed_commands)
def main():
    argument_spec = mysql_common_argument_spec()
    argument_spec.update(
        mode=dict(type='str',
                  default='getreplica',
                  choices=[
                      'getmaster', 'getreplica', 'getslave', 'changemaster',
                      'stopreplica', 'stopslave', 'startreplica', 'startslave',
                      'resetmaster', 'resetreplica', 'resetslave',
                      'resetreplicaall', 'resetslaveall'
                  ]),
        master_auto_position=dict(type='bool', default=False),
        master_host=dict(type='str'),
        master_user=dict(type='str'),
        master_password=dict(type='str', no_log=True),
        master_port=dict(type='int'),
        master_connect_retry=dict(type='int'),
        master_log_file=dict(type='str'),
        master_log_pos=dict(type='int'),
        relay_log_file=dict(type='str'),
        relay_log_pos=dict(type='int'),
        master_ssl=dict(type='bool', default=False),
        master_ssl_ca=dict(type='str'),
        master_ssl_capath=dict(type='str'),
        master_ssl_cert=dict(type='str'),
        master_ssl_key=dict(type='str'),
        master_ssl_cipher=dict(type='str'),
        master_use_gtid=dict(
            type='str',
            choices=['current_pos', 'replica_pos', 'slave_pos', 'disabled']),
        master_delay=dict(type='int'),
        connection_name=dict(type='str'),
        channel=dict(type='str'),
        fail_on_error=dict(type='bool', default=False),
    )
    module = AnsibleModule(
        argument_spec=argument_spec,
        mutually_exclusive=[['connection_name', 'channel']],
    )
    mode = module.params["mode"]
    master_host = module.params["master_host"]
    master_user = module.params["master_user"]
    master_password = module.params["master_password"]
    master_port = module.params["master_port"]
    master_connect_retry = module.params["master_connect_retry"]
    master_log_file = module.params["master_log_file"]
    master_log_pos = module.params["master_log_pos"]
    relay_log_file = module.params["relay_log_file"]
    relay_log_pos = module.params["relay_log_pos"]
    master_ssl = module.params["master_ssl"]
    master_ssl_ca = module.params["master_ssl_ca"]
    master_ssl_capath = module.params["master_ssl_capath"]
    master_ssl_cert = module.params["master_ssl_cert"]
    master_ssl_key = module.params["master_ssl_key"]
    master_ssl_cipher = module.params["master_ssl_cipher"]
    master_auto_position = module.params["master_auto_position"]
    ssl_cert = module.params["client_cert"]
    ssl_key = module.params["client_key"]
    ssl_ca = module.params["ca_cert"]
    check_hostname = module.params["check_hostname"]
    connect_timeout = module.params['connect_timeout']
    config_file = module.params['config_file']
    master_delay = module.params['master_delay']
    if module.params.get("master_use_gtid") == 'disabled':
        master_use_gtid = 'no'
    else:
        master_use_gtid = module.params["master_use_gtid"]
    connection_name = module.params["connection_name"]
    channel = module.params['channel']
    fail_on_error = module.params['fail_on_error']

    if mysql_driver is None:
        module.fail_json(msg=mysql_driver_fail_msg)
    else:
        warnings.filterwarnings('error', category=mysql_driver.Warning)

    login_password = module.params["login_password"]
    login_user = module.params["login_user"]

    try:
        cursor, db_conn = mysql_connect(module,
                                        login_user,
                                        login_password,
                                        config_file,
                                        ssl_cert,
                                        ssl_key,
                                        ssl_ca,
                                        None,
                                        cursor_class='DictCursor',
                                        connect_timeout=connect_timeout,
                                        check_hostname=check_hostname)
    except Exception as e:
        if os.path.exists(config_file):
            module.fail_json(
                msg="unable to connect to database, check login_user and "
                "login_password are correct or %s has the credentials. "
                "Exception message: %s" % (config_file, to_native(e)))
        else:
            module.fail_json(msg="unable to find %s. Exception message: %s" %
                             (config_file, to_native(e)))

    # Since MySQL 8.0.22 and MariaDB 10.5.1,
    # "REPLICA" must be used instead of "SLAVE"
    if uses_replica_terminology(cursor):
        replica_term = 'REPLICA'
        if master_use_gtid == 'slave_pos':
            module.deprecate(
                'master_use_gtid "slave_pos" value is deprecated, use "replica_pos" instead.',
                version='3.0.0',
                collection_name='community.mysql')
            master_use_gtid = 'replica_pos'
    else:
        replica_term = 'SLAVE'
        if master_use_gtid == 'replica_pos':
            master_use_gtid = 'slave_pos'

    if mode in "getmaster":
        status = get_master_status(cursor)
        if not isinstance(status, dict):
            status = dict(Is_Master=False,
                          msg="Server is not configured as mysql master")
        else:
            status['Is_Master'] = True
        module.exit_json(queries=executed_queries, **status)

    elif mode in ("getreplica", "getslave"):
        if mode == "getslave":
            module.deprecate(
                '"getslave" option is deprecated, use "getreplica" instead.',
                version='3.0.0',
                collection_name='community.mysql')

        status = get_replica_status(cursor, connection_name, channel,
                                    replica_term)
        if not isinstance(status, dict):
            status = dict(Is_Slave=False,
                          msg="Server is not configured as mysql slave")
        else:
            status['Is_Slave'] = True
        module.exit_json(queries=executed_queries, **status)

    elif mode in "changemaster":
        chm = []
        result = {}
        if master_host is not None:
            chm.append("MASTER_HOST='%s'" % master_host)
        if master_user is not None:
            chm.append("MASTER_USER='******'" % master_user)
        if master_password is not None:
            chm.append("MASTER_PASSWORD='******'" % master_password)
        if master_port is not None:
            chm.append("MASTER_PORT=%s" % master_port)
        if master_connect_retry is not None:
            chm.append("MASTER_CONNECT_RETRY=%s" % master_connect_retry)
        if master_log_file is not None:
            chm.append("MASTER_LOG_FILE='%s'" % master_log_file)
        if master_log_pos is not None:
            chm.append("MASTER_LOG_POS=%s" % master_log_pos)
        if master_delay is not None:
            chm.append("MASTER_DELAY=%s" % master_delay)
        if relay_log_file is not None:
            chm.append("RELAY_LOG_FILE='%s'" % relay_log_file)
        if relay_log_pos is not None:
            chm.append("RELAY_LOG_POS=%s" % relay_log_pos)
        if master_ssl:
            chm.append("MASTER_SSL=1")
        if master_ssl_ca is not None:
            chm.append("MASTER_SSL_CA='%s'" % master_ssl_ca)
        if master_ssl_capath is not None:
            chm.append("MASTER_SSL_CAPATH='%s'" % master_ssl_capath)
        if master_ssl_cert is not None:
            chm.append("MASTER_SSL_CERT='%s'" % master_ssl_cert)
        if master_ssl_key is not None:
            chm.append("MASTER_SSL_KEY='%s'" % master_ssl_key)
        if master_ssl_cipher is not None:
            chm.append("MASTER_SSL_CIPHER='%s'" % master_ssl_cipher)
        if master_auto_position:
            chm.append("MASTER_AUTO_POSITION=1")
        if master_use_gtid is not None:
            chm.append("MASTER_USE_GTID=%s" % master_use_gtid)
        try:
            changemaster(cursor, chm, connection_name, channel)
        except mysql_driver.Warning as e:
            result['warning'] = to_native(e)
        except Exception as e:
            module.fail_json(msg='%s. Query == CHANGE MASTER TO %s' %
                             (to_native(e), chm))
        result['changed'] = True
        module.exit_json(queries=executed_queries, **result)
    elif mode in ("startreplica", "startslave"):
        if mode == "startslave":
            module.deprecate(
                '"startslave" option is deprecated, use "startreplica" instead.',
                version='3.0.0',
                collection_name='community.mysql')

        started = start_replica(module, cursor, connection_name, channel,
                                fail_on_error, replica_term)
        if started is True:
            module.exit_json(msg="Slave started ",
                             changed=True,
                             queries=executed_queries)
        else:
            module.exit_json(
                msg="Slave already started (Or cannot be started)",
                changed=False,
                queries=executed_queries)
    elif mode in ("stopreplica", "stopslave"):
        if mode == "stopslave":
            module.deprecate(
                '"stopslave" option is deprecated, use "stopreplica" instead.',
                version='3.0.0',
                collection_name='community.mysql')

        stopped = stop_replica(module, cursor, connection_name, channel,
                               fail_on_error, replica_term)
        if stopped is True:
            module.exit_json(msg="Slave stopped",
                             changed=True,
                             queries=executed_queries)
        else:
            module.exit_json(msg="Slave already stopped",
                             changed=False,
                             queries=executed_queries)
    elif mode in "resetmaster":
        reset = reset_master(module, cursor, fail_on_error)
        if reset is True:
            module.exit_json(msg="Master reset",
                             changed=True,
                             queries=executed_queries)
        else:
            module.exit_json(msg="Master already reset",
                             changed=False,
                             queries=executed_queries)
    elif mode in ("resetreplica", "resetslave"):
        if mode == "resetslave":
            module.deprecate(
                '"resetslave" option is deprecated, use "resetreplica" instead.',
                version='3.0.0',
                collection_name='community.mysql')

        reset = reset_replica(module, cursor, connection_name, channel,
                              fail_on_error, replica_term)
        if reset is True:
            module.exit_json(msg="Slave reset",
                             changed=True,
                             queries=executed_queries)
        else:
            module.exit_json(msg="Slave already reset",
                             changed=False,
                             queries=executed_queries)
    elif mode in ("resetreplicaall", "resetslaveall"):
        if mode == "resetslaveall":
            module.deprecate(
                '"resetslaveall" option is deprecated, use "resetreplicaall" instead.',
                version='3.0.0',
                collection_name='community.mysql')

        reset = reset_replica_all(module, cursor, connection_name, channel,
                                  fail_on_error, replica_term)
        if reset is True:
            module.exit_json(msg="Slave reset",
                             changed=True,
                             queries=executed_queries)
        else:
            module.exit_json(msg="Slave already reset",
                             changed=False,
                             queries=executed_queries)

    warnings.simplefilter("ignore")
def main():
    argument_spec = mysql_common_argument_spec()
    argument_spec.update(
        query=dict(type='raw', required=True),
        login_db=dict(type='str'),
        positional_args=dict(type='list'),
        named_args=dict(type='dict'),
        single_transaction=dict(type='bool', default=False),
    )

    module = AnsibleModule(
        argument_spec=argument_spec,
        mutually_exclusive=(('positional_args', 'named_args'), ),
    )

    db = module.params['login_db']
    connect_timeout = module.params['connect_timeout']
    login_user = module.params['login_user']
    login_password = module.params['login_password']
    ssl_cert = module.params['client_cert']
    ssl_key = module.params['client_key']
    ssl_ca = module.params['ca_cert']
    check_hostname = module.params['check_hostname']
    config_file = module.params['config_file']
    query = module.params["query"]

    if not isinstance(query, (str, list)):
        module.fail_json(
            msg="the query option value must be a string or list, passed %s" %
            type(query))

    if isinstance(query, str):
        query = [query]

    for elem in query:
        if not isinstance(elem, str):
            module.fail_json(
                msg="the elements in query list must be strings, passed '%s' %s"
                % (elem, type(elem)))

    if module.params["single_transaction"]:
        autocommit = False
    else:
        autocommit = True
    # Prepare args:
    if module.params.get("positional_args"):
        arguments = module.params["positional_args"]
    elif module.params.get("named_args"):
        arguments = module.params["named_args"]
    else:
        arguments = None

    if mysql_driver is None:
        module.fail_json(msg=mysql_driver_fail_msg)

    # Connect to DB:
    try:
        cursor, db_connection = mysql_connect(module,
                                              login_user,
                                              login_password,
                                              config_file,
                                              ssl_cert,
                                              ssl_key,
                                              ssl_ca,
                                              db,
                                              check_hostname=check_hostname,
                                              connect_timeout=connect_timeout,
                                              cursor_class='DictCursor',
                                              autocommit=autocommit)
    except Exception as e:
        module.fail_json(
            msg="unable to connect to database, check login_user and "
            "login_password are correct or %s has the credentials. "
            "Exception message: %s" % (config_file, to_native(e)))

    # Set defaults:
    changed = False

    max_keyword_len = len(max(DML_QUERY_KEYWORDS + DDL_QUERY_KEYWORDS,
                              key=len))

    # Execute query:
    query_result = []
    executed_queries = []
    rowcount = []

    for q in query:
        try:
            cursor.execute(q, arguments)

        except Exception as e:
            if not autocommit:
                db_connection.rollback()

            cursor.close()
            module.fail_json(msg="Cannot execute SQL '%s' args [%s]: %s" %
                             (q, arguments, to_native(e)))

        try:
            query_result.append([dict(row) for row in cursor.fetchall()])

        except Exception as e:
            if not autocommit:
                db_connection.rollback()

            module.fail_json(msg="Cannot fetch rows from cursor: %s" %
                             to_native(e))

        # Check DML or DDL keywords in query and set changed accordingly:
        q = q.lstrip()[0:max_keyword_len].upper()
        for keyword in DML_QUERY_KEYWORDS:
            if keyword in q and cursor.rowcount > 0:
                changed = True

        for keyword in DDL_QUERY_KEYWORDS:
            if keyword in q:
                changed = True

        try:
            executed_queries.append(cursor._last_executed)
        except AttributeError:
            # MySQLdb removed cursor._last_executed as a duplicate of cursor._executed
            executed_queries.append(cursor._executed)
        rowcount.append(cursor.rowcount)

    # When the module run with the single_transaction == True:
    if not autocommit:
        db_connection.commit()

    # Create dict with returned values:
    kw = {
        'changed': changed,
        'executed_queries': executed_queries,
        'query_result': query_result,
        'rowcount': rowcount,
    }

    # Exit:
    module.exit_json(**kw)
def main():
    argument_spec = mysql_common_argument_spec()
    argument_spec.update(
        name=dict(type='str', required=True),
        state=dict(type='str', default='present', choices=['absent', 'present']),
        admin=dict(type='str'),
        priv=dict(type='raw'),
        append_privs=dict(type='bool', default=False),
        subtract_privs=dict(type='bool', default=False),
        members=dict(type='list', elements='str'),
        append_members=dict(type='bool', default=False),
        detach_members=dict(type='bool', default=False),
        check_implicit_admin=dict(type='bool', default=False),
        set_default_role_all=dict(type='bool', default=True),
        members_must_exist=dict(type='bool', default=True)
    )
    module = AnsibleModule(
        argument_spec=argument_spec,
        supports_check_mode=True,
        mutually_exclusive=(
            ('append_members', 'detach_members'),
            ('admin', 'members'),
            ('admin', 'append_members'),
            ('admin', 'detach_members'),
            ('append_privs', 'subtract_privs'),
        ),
    )

    login_user = module.params['login_user']
    login_password = module.params['login_password']
    name = module.params['name']
    state = module.params['state']
    admin = module.params['admin']
    priv = module.params['priv']
    check_implicit_admin = module.params['check_implicit_admin']
    connect_timeout = module.params['connect_timeout']
    config_file = module.params['config_file']
    append_privs = module.params['append_privs']
    subtract_privs = module.boolean(module.params['subtract_privs'])
    members = module.params['members']
    append_members = module.params['append_members']
    detach_members = module.params['detach_members']
    ssl_cert = module.params['client_cert']
    ssl_key = module.params['client_key']
    ssl_ca = module.params['ca_cert']
    check_hostname = module.params['check_hostname']
    db = ''
    set_default_role_all = module.params['set_default_role_all']
    members_must_exist = module.params['members_must_exist']

    if priv and not isinstance(priv, (str, dict)):
        msg = ('The "priv" parameter must be str or dict '
               'but %s was passed' % type(priv))
        module.fail_json(msg=msg)

    if priv and isinstance(priv, dict):
        priv = convert_priv_dict_to_str(priv)

    if mysql_driver is None:
        module.fail_json(msg=mysql_driver_fail_msg)

    cursor = None
    try:
        if check_implicit_admin:
            try:
                cursor, db_conn = mysql_connect(module, 'root', '', config_file,
                                                ssl_cert, ssl_key, ssl_ca, db,
                                                connect_timeout=connect_timeout,
                                                check_hostname=check_hostname)
            except Exception:
                pass

        if not cursor:
            cursor, db_conn = mysql_connect(module, login_user, login_password,
                                            config_file, ssl_cert, ssl_key,
                                            ssl_ca, db, connect_timeout=connect_timeout,
                                            check_hostname=check_hostname)

    except Exception as e:
        module.fail_json(msg='unable to connect to database, '
                             'check login_user and login_password '
                             'are correct or %s has the credentials. '
                             'Exception message: %s' % (config_file, to_native(e)))

    # Set defaults
    changed = False

    get_impl(cursor)

    if priv is not None:
        try:
            mode = get_mode(cursor)
        except Exception as e:
            module.fail_json(msg=to_native(e))

        try:
            priv = privileges_unpack(priv, mode, ensure_usage=not subtract_privs)
        except Exception as e:
            module.fail_json(msg='Invalid privileges string: %s' % to_native(e))

    server = DbServer(module, cursor)

    # Check if the server supports roles
    if not server.supports_roles():
        msg = ('Roles are not supported by the server. '
               'Minimal versions are MySQL 8.0.0 or MariaDB 10.0.5.')
        module.fail_json(msg=msg)

    if admin:
        if not server.is_mariadb():
            module.fail_json(msg='The "admin" option can be used only with MariaDB.')

        admin = normalize_users(module, [admin])[0]
        server.check_users_in_db([admin])

    if members:
        members = normalize_users(module, members, server.is_mariadb())
        if members_must_exist:
            server.check_users_in_db(members)
        else:
            members = list(server.filter_existing_users(members))

    # Main job starts here
    role = Role(module, cursor, name, server)

    try:
        if state == 'present':
            if not role.exists:
                if subtract_privs:
                    priv = None  # avoid granting unwanted privileges
                if detach_members:
                    members = None  # avoid adding unwanted members
                changed = role.add(members, priv, module.check_mode, admin,
                                   set_default_role_all)

            else:
                changed = role.update(members, priv, module.check_mode, append_privs, subtract_privs,
                                      append_members, detach_members, admin,
                                      set_default_role_all)

        elif state == 'absent':
            changed = role.drop(module.check_mode)

    except Exception as e:
        module.fail_json(msg=to_native(e))

    module.exit_json(changed=changed)
Exemple #9
0
def main():
    argument_spec = mysql_common_argument_spec()
    argument_spec.update(
        mode=dict(type='str',
                  default='getreplica',
                  choices=[
                      'getprimary', 'getreplica', 'changeprimary',
                      'stopreplica', 'startreplica', 'resetprimary',
                      'resetreplica', 'resetreplicaall'
                  ]),
        primary_auto_position=dict(type='bool',
                                   default=False,
                                   aliases=['master_auto_position']),
        primary_host=dict(type='str', aliases=['master_host']),
        primary_user=dict(type='str', aliases=['master_user']),
        primary_password=dict(type='str',
                              no_log=True,
                              aliases=['master_password']),
        primary_port=dict(type='int', aliases=['master_port']),
        primary_connect_retry=dict(type='int',
                                   aliases=['master_connect_retry']),
        primary_log_file=dict(type='str', aliases=['master_log_file']),
        primary_log_pos=dict(type='int', aliases=['master_log_pos']),
        relay_log_file=dict(type='str'),
        relay_log_pos=dict(type='int'),
        primary_ssl=dict(type='bool', default=False, aliases=['master_ssl']),
        primary_ssl_ca=dict(type='str', aliases=['master_ssl_ca']),
        primary_ssl_capath=dict(type='str', aliases=['master_ssl_capath']),
        primary_ssl_cert=dict(type='str', aliases=['master_ssl_cert']),
        primary_ssl_key=dict(type='str',
                             no_log=False,
                             aliases=['master_ssl_key']),
        primary_ssl_cipher=dict(type='str', aliases=['master_ssl_cipher']),
        primary_use_gtid=dict(
            type='str',
            choices=['current_pos', 'replica_pos', 'disabled'],
            aliases=['master_use_gtid']),
        primary_delay=dict(type='int', aliases=['master_delay']),
        connection_name=dict(type='str'),
        channel=dict(type='str'),
        fail_on_error=dict(type='bool', default=False),
    )
    module = AnsibleModule(
        argument_spec=argument_spec,
        mutually_exclusive=[['connection_name', 'channel']],
    )
    mode = module.params["mode"]
    primary_host = module.params["primary_host"]
    primary_user = module.params["primary_user"]
    primary_password = module.params["primary_password"]
    primary_port = module.params["primary_port"]
    primary_connect_retry = module.params["primary_connect_retry"]
    primary_log_file = module.params["primary_log_file"]
    primary_log_pos = module.params["primary_log_pos"]
    relay_log_file = module.params["relay_log_file"]
    relay_log_pos = module.params["relay_log_pos"]
    primary_ssl = module.params["primary_ssl"]
    primary_ssl_ca = module.params["primary_ssl_ca"]
    primary_ssl_capath = module.params["primary_ssl_capath"]
    primary_ssl_cert = module.params["primary_ssl_cert"]
    primary_ssl_key = module.params["primary_ssl_key"]
    primary_ssl_cipher = module.params["primary_ssl_cipher"]
    primary_auto_position = module.params["primary_auto_position"]
    ssl_cert = module.params["client_cert"]
    ssl_key = module.params["client_key"]
    ssl_ca = module.params["ca_cert"]
    check_hostname = module.params["check_hostname"]
    connect_timeout = module.params['connect_timeout']
    config_file = module.params['config_file']
    primary_delay = module.params['primary_delay']
    if module.params.get("primary_use_gtid") == 'disabled':
        primary_use_gtid = 'no'
    else:
        primary_use_gtid = module.params["primary_use_gtid"]
    connection_name = module.params["connection_name"]
    channel = module.params['channel']
    fail_on_error = module.params['fail_on_error']

    if mysql_driver is None:
        module.fail_json(msg=mysql_driver_fail_msg)
    else:
        warnings.filterwarnings('error', category=mysql_driver.Warning)

    login_password = module.params["login_password"]
    login_user = module.params["login_user"]

    try:
        cursor, db_conn = mysql_connect(module,
                                        login_user,
                                        login_password,
                                        config_file,
                                        ssl_cert,
                                        ssl_key,
                                        ssl_ca,
                                        None,
                                        cursor_class='DictCursor',
                                        connect_timeout=connect_timeout,
                                        check_hostname=check_hostname)
    except Exception as e:
        if os.path.exists(config_file):
            module.fail_json(
                msg="unable to connect to database, check login_user and "
                "login_password are correct or %s has the credentials. "
                "Exception message: %s" % (config_file, to_native(e)))
        else:
            module.fail_json(msg="unable to find %s. Exception message: %s" %
                             (config_file, to_native(e)))

    cursor.execute("SELECT VERSION()")
    if 'mariadb' in cursor.fetchone()["VERSION()"].lower():
        from ansible_collections.community.mysql.plugins.module_utils.implementations.mariadb import replication as impl
    else:
        from ansible_collections.community.mysql.plugins.module_utils.implementations.mysql import replication as impl

    # Since MySQL 8.0.22 and MariaDB 10.5.1,
    # "REPLICA" must be used instead of "SLAVE"
    if impl.uses_replica_terminology(cursor):
        replica_term = 'REPLICA'
    else:
        replica_term = 'SLAVE'

    if mode == 'getprimary':
        status = get_primary_status(cursor)
        if not isinstance(status, dict):
            status = dict(Is_Primary=False,
                          msg="Server is not configured as mysql primary")
        else:
            status['Is_Primary'] = True

        module.exit_json(queries=executed_queries, **status)

    elif mode == "getreplica":
        status = get_replica_status(cursor, connection_name, channel,
                                    replica_term)
        if not isinstance(status, dict):
            status = dict(Is_Replica=False,
                          msg="Server is not configured as mysql replica")
        else:
            status['Is_Replica'] = True

        module.exit_json(queries=executed_queries, **status)

    elif mode == 'changeprimary':
        chm = []
        result = {}
        if primary_host is not None:
            chm.append("MASTER_HOST='%s'" % primary_host)
        if primary_user is not None:
            chm.append("MASTER_USER='******'" % primary_user)
        if primary_password is not None:
            chm.append("MASTER_PASSWORD='******'" % primary_password)
        if primary_port is not None:
            chm.append("MASTER_PORT=%s" % primary_port)
        if primary_connect_retry is not None:
            chm.append("MASTER_CONNECT_RETRY=%s" % primary_connect_retry)
        if primary_log_file is not None:
            chm.append("MASTER_LOG_FILE='%s'" % primary_log_file)
        if primary_log_pos is not None:
            chm.append("MASTER_LOG_POS=%s" % primary_log_pos)
        if primary_delay is not None:
            chm.append("MASTER_DELAY=%s" % primary_delay)
        if relay_log_file is not None:
            chm.append("RELAY_LOG_FILE='%s'" % relay_log_file)
        if relay_log_pos is not None:
            chm.append("RELAY_LOG_POS=%s" % relay_log_pos)
        if primary_ssl:
            chm.append("MASTER_SSL=1")
        if primary_ssl_ca is not None:
            chm.append("MASTER_SSL_CA='%s'" % primary_ssl_ca)
        if primary_ssl_capath is not None:
            chm.append("MASTER_SSL_CAPATH='%s'" % primary_ssl_capath)
        if primary_ssl_cert is not None:
            chm.append("MASTER_SSL_CERT='%s'" % primary_ssl_cert)
        if primary_ssl_key is not None:
            chm.append("MASTER_SSL_KEY='%s'" % primary_ssl_key)
        if primary_ssl_cipher is not None:
            chm.append("MASTER_SSL_CIPHER='%s'" % primary_ssl_cipher)
        if primary_auto_position:
            chm.append("MASTER_AUTO_POSITION=1")
        if primary_use_gtid is not None:
            chm.append("MASTER_USE_GTID=%s" % primary_use_gtid)
        try:
            changeprimary(cursor, chm, connection_name, channel)
        except mysql_driver.Warning as e:
            result['warning'] = to_native(e)
        except Exception as e:
            module.fail_json(msg='%s. Query == CHANGE MASTER TO %s' %
                             (to_native(e), chm))
        result['changed'] = True
        module.exit_json(queries=executed_queries, **result)
    elif mode == "startreplica":
        started = start_replica(module, cursor, connection_name, channel,
                                fail_on_error, replica_term)
        if started is True:
            module.exit_json(msg="Replica started ",
                             changed=True,
                             queries=executed_queries)
        else:
            module.exit_json(
                msg="Replica already started (Or cannot be started)",
                changed=False,
                queries=executed_queries)
    elif mode == "stopreplica":
        stopped = stop_replica(module, cursor, connection_name, channel,
                               fail_on_error, replica_term)
        if stopped is True:
            module.exit_json(msg="Replica stopped",
                             changed=True,
                             queries=executed_queries)
        else:
            module.exit_json(msg="Replica already stopped",
                             changed=False,
                             queries=executed_queries)
    elif mode == 'resetprimary':
        reset = reset_primary(module, cursor, fail_on_error)
        if reset is True:
            module.exit_json(msg="Primary reset",
                             changed=True,
                             queries=executed_queries)
        else:
            module.exit_json(msg="Primary already reset",
                             changed=False,
                             queries=executed_queries)
    elif mode == "resetreplica":
        reset = reset_replica(module, cursor, connection_name, channel,
                              fail_on_error, replica_term)
        if reset is True:
            module.exit_json(msg="Replica reset",
                             changed=True,
                             queries=executed_queries)
        else:
            module.exit_json(msg="Replica already reset",
                             changed=False,
                             queries=executed_queries)
    elif mode == "resetreplicaall":
        reset = reset_replica_all(module, cursor, connection_name, channel,
                                  fail_on_error, replica_term)
        if reset is True:
            module.exit_json(msg="Replica reset",
                             changed=True,
                             queries=executed_queries)
        else:
            module.exit_json(msg="Replica already reset",
                             changed=False,
                             queries=executed_queries)

    warnings.simplefilter("ignore")
Exemple #10
0
def main():
    argument_spec = mysql_common_argument_spec()
    argument_spec.update(
        user=dict(type='str', required=True, aliases=['name']),
        password=dict(type='str', no_log=True),
        encrypted=dict(type='bool', default=False),
        host=dict(type='str', default='localhost'),
        host_all=dict(type="bool", default=False),
        state=dict(type='str',
                   default='present',
                   choices=['absent', 'present']),
        priv=dict(type='raw'),
        tls_requires=dict(type='dict'),
        append_privs=dict(type='bool', default=False),
        subtract_privs=dict(type='bool', default=False),
        check_implicit_admin=dict(type='bool', default=False),
        update_password=dict(
            type='str',
            default='always',
            choices=['always', 'on_create', 'on_new_username'],
            no_log=False),
        sql_log_bin=dict(type='bool', default=True),
        plugin=dict(default=None, type='str'),
        plugin_hash_string=dict(default=None, type='str'),
        plugin_auth_string=dict(default=None, type='str'),
        resource_limits=dict(type='dict'),
        force_context=dict(type='bool', default=False),
    )
    module = AnsibleModule(argument_spec=argument_spec,
                           supports_check_mode=True,
                           mutually_exclusive=(('append_privs',
                                                'subtract_privs'), ))
    login_user = module.params["login_user"]
    login_password = module.params["login_password"]
    user = module.params["user"]
    password = module.params["password"]
    encrypted = module.boolean(module.params["encrypted"])
    host = module.params["host"].lower()
    host_all = module.params["host_all"]
    state = module.params["state"]
    priv = module.params["priv"]
    tls_requires = sanitize_requires(module.params["tls_requires"])
    check_implicit_admin = module.params["check_implicit_admin"]
    connect_timeout = module.params["connect_timeout"]
    config_file = module.params["config_file"]
    append_privs = module.boolean(module.params["append_privs"])
    subtract_privs = module.boolean(module.params['subtract_privs'])
    update_password = module.params['update_password']
    ssl_cert = module.params["client_cert"]
    ssl_key = module.params["client_key"]
    ssl_ca = module.params["ca_cert"]
    check_hostname = module.params["check_hostname"]
    db = ''
    if module.params["force_context"]:
        db = 'mysql'
    sql_log_bin = module.params["sql_log_bin"]
    plugin = module.params["plugin"]
    plugin_hash_string = module.params["plugin_hash_string"]
    plugin_auth_string = module.params["plugin_auth_string"]
    resource_limits = module.params["resource_limits"]
    if priv and not isinstance(priv, (str, dict)):
        module.fail_json(
            msg="priv parameter must be str or dict but %s was passed" %
            type(priv))

    if priv and isinstance(priv, dict):
        priv = convert_priv_dict_to_str(priv)

    if mysql_driver is None:
        module.fail_json(msg=mysql_driver_fail_msg)

    cursor = None
    try:
        if check_implicit_admin:
            try:
                cursor, db_conn = mysql_connect(
                    module,
                    "root",
                    "",
                    config_file,
                    ssl_cert,
                    ssl_key,
                    ssl_ca,
                    db,
                    connect_timeout=connect_timeout,
                    check_hostname=check_hostname)
            except Exception:
                pass

        if not cursor:
            cursor, db_conn = mysql_connect(module,
                                            login_user,
                                            login_password,
                                            config_file,
                                            ssl_cert,
                                            ssl_key,
                                            ssl_ca,
                                            db,
                                            connect_timeout=connect_timeout,
                                            check_hostname=check_hostname)
    except Exception as e:
        module.fail_json(
            msg=
            "unable to connect to database, check login_user and login_password are correct or %s has the credentials. "
            "Exception message: %s" % (config_file, to_native(e)))

    if not sql_log_bin:
        cursor.execute("SET SQL_LOG_BIN=0;")

    get_impl(cursor)

    if priv is not None:
        try:
            mode = get_mode(cursor)
        except Exception as e:
            module.fail_json(msg=to_native(e))
        priv = privileges_unpack(priv, mode, ensure_usage=not subtract_privs)
    password_changed = False
    if state == "present":
        if user_exists(cursor, user, host, host_all):
            try:
                if update_password == "always":
                    result = user_mod(cursor, user, host, host_all, password,
                                      encrypted, plugin, plugin_hash_string,
                                      plugin_auth_string, priv, append_privs,
                                      subtract_privs, tls_requires, module)

                else:
                    result = user_mod(cursor, user, host, host_all, None,
                                      encrypted, None, None, None, priv,
                                      append_privs, subtract_privs,
                                      tls_requires, module)
                changed = result['changed']
                msg = result['msg']
                password_changed = result['password_changed']

            except (SQLParseError, InvalidPrivsError, mysql_driver.Error) as e:
                module.fail_json(msg=to_native(e))
        else:
            if host_all:
                module.fail_json(
                    msg="host_all parameter cannot be used when adding a user")
            try:
                if subtract_privs:
                    priv = None  # avoid granting unwanted privileges
                reuse_existing_password = update_password == 'on_new_username'
                result = user_add(cursor, user, host, host_all, password,
                                  encrypted, plugin, plugin_hash_string,
                                  plugin_auth_string, priv, tls_requires,
                                  module.check_mode, reuse_existing_password)
                changed = result['changed']
                password_changed = result['password_changed']
                if changed:
                    msg = "User added"

            except (SQLParseError, InvalidPrivsError, mysql_driver.Error) as e:
                module.fail_json(msg=to_native(e))

        if resource_limits:
            changed = limit_resources(module, cursor, user, host,
                                      resource_limits,
                                      module.check_mode) or changed

    elif state == "absent":
        if user_exists(cursor, user, host, host_all):
            changed = user_delete(cursor, user, host, host_all,
                                  module.check_mode)
            msg = "User deleted"
        else:
            changed = False
            msg = "User doesn't exist"
    module.exit_json(changed=changed,
                     user=user,
                     msg=msg,
                     password_changed=password_changed)
def main():
    module = AnsibleModule(
        argument_spec=dict(
            login_user=dict(type='str'),
            login_password=dict(type='str', no_log=True),
            login_host=dict(type='str', default='localhost'),
            login_port=dict(type='int', default=3306),
            login_unix_socket=dict(type='str'),
            mode=dict(type='str',
                      default='getslave',
                      choices=[
                          'getmaster', 'getslave', 'changemaster', 'stopslave',
                          'startslave', 'resetmaster', 'resetslave',
                          'resetslaveall'
                      ]),
            master_auto_position=dict(type='bool', default=False),
            master_host=dict(type='str'),
            master_user=dict(type='str'),
            master_password=dict(type='str', no_log=True),
            master_port=dict(type='int'),
            master_connect_retry=dict(type='int'),
            master_log_file=dict(type='str'),
            master_log_pos=dict(type='int'),
            relay_log_file=dict(type='str'),
            relay_log_pos=dict(type='int'),
            master_ssl=dict(type='bool', default=False),
            master_ssl_ca=dict(type='str'),
            master_ssl_capath=dict(type='str'),
            master_ssl_cert=dict(type='str'),
            master_ssl_key=dict(type='str'),
            master_ssl_cipher=dict(type='str'),
            connect_timeout=dict(type='int', default=30),
            config_file=dict(type='path', default='~/.my.cnf'),
            client_cert=dict(type='path', aliases=['ssl_cert']),
            client_key=dict(type='path', aliases=['ssl_key']),
            ca_cert=dict(type='path', aliases=['ssl_ca']),
            master_use_gtid=dict(
                type='str', choices=['current_pos', 'slave_pos', 'disabled']),
            master_delay=dict(type='int'),
            connection_name=dict(type='str'),
            channel=dict(type='str'),
            fail_on_error=dict(type='bool', default=False),
        ),
        mutually_exclusive=[['connection_name', 'channel']],
    )
    mode = module.params["mode"]
    master_host = module.params["master_host"]
    master_user = module.params["master_user"]
    master_password = module.params["master_password"]
    master_port = module.params["master_port"]
    master_connect_retry = module.params["master_connect_retry"]
    master_log_file = module.params["master_log_file"]
    master_log_pos = module.params["master_log_pos"]
    relay_log_file = module.params["relay_log_file"]
    relay_log_pos = module.params["relay_log_pos"]
    master_ssl = module.params["master_ssl"]
    master_ssl_ca = module.params["master_ssl_ca"]
    master_ssl_capath = module.params["master_ssl_capath"]
    master_ssl_cert = module.params["master_ssl_cert"]
    master_ssl_key = module.params["master_ssl_key"]
    master_ssl_cipher = module.params["master_ssl_cipher"]
    master_auto_position = module.params["master_auto_position"]
    ssl_cert = module.params["client_cert"]
    ssl_key = module.params["client_key"]
    ssl_ca = module.params["ca_cert"]
    connect_timeout = module.params['connect_timeout']
    config_file = module.params['config_file']
    master_delay = module.params['master_delay']
    if module.params.get("master_use_gtid") == 'disabled':
        master_use_gtid = 'no'
    else:
        master_use_gtid = module.params["master_use_gtid"]
    connection_name = module.params["connection_name"]
    channel = module.params['channel']
    fail_on_error = module.params['fail_on_error']

    if mysql_driver is None:
        module.fail_json(msg=mysql_driver_fail_msg)
    else:
        warnings.filterwarnings('error', category=mysql_driver.Warning)

    login_password = module.params["login_password"]
    login_user = module.params["login_user"]

    try:
        cursor, db_conn = mysql_connect(module,
                                        login_user,
                                        login_password,
                                        config_file,
                                        ssl_cert,
                                        ssl_key,
                                        ssl_ca,
                                        None,
                                        cursor_class='DictCursor',
                                        connect_timeout=connect_timeout)
    except Exception as e:
        if os.path.exists(config_file):
            module.fail_json(
                msg=
                "unable to connect to database, check login_user and login_password are correct or %s has the credentials. "
                "Exception message: %s" % (config_file, to_native(e)))
        else:
            module.fail_json(msg="unable to find %s. Exception message: %s" %
                             (config_file, to_native(e)))

    if mode in "getmaster":
        status = get_master_status(cursor)
        if not isinstance(status, dict):
            status = dict(Is_Master=False,
                          msg="Server is not configured as mysql master")
        else:
            status['Is_Master'] = True
        module.exit_json(queries=executed_queries, **status)

    elif mode in "getslave":
        status = get_slave_status(cursor, connection_name, channel)
        if not isinstance(status, dict):
            status = dict(Is_Slave=False,
                          msg="Server is not configured as mysql slave")
        else:
            status['Is_Slave'] = True
        module.exit_json(queries=executed_queries, **status)

    elif mode in "changemaster":
        chm = []
        result = {}
        if master_host is not None:
            chm.append("MASTER_HOST='%s'" % master_host)
        if master_user is not None:
            chm.append("MASTER_USER='******'" % master_user)
        if master_password is not None:
            chm.append("MASTER_PASSWORD='******'" % master_password)
        if master_port is not None:
            chm.append("MASTER_PORT=%s" % master_port)
        if master_connect_retry is not None:
            chm.append("MASTER_CONNECT_RETRY=%s" % master_connect_retry)
        if master_log_file is not None:
            chm.append("MASTER_LOG_FILE='%s'" % master_log_file)
        if master_log_pos is not None:
            chm.append("MASTER_LOG_POS=%s" % master_log_pos)
        if master_delay is not None:
            chm.append("MASTER_DELAY=%s" % master_delay)
        if relay_log_file is not None:
            chm.append("RELAY_LOG_FILE='%s'" % relay_log_file)
        if relay_log_pos is not None:
            chm.append("RELAY_LOG_POS=%s" % relay_log_pos)
        if master_ssl:
            chm.append("MASTER_SSL=1")
        if master_ssl_ca is not None:
            chm.append("MASTER_SSL_CA='%s'" % master_ssl_ca)
        if master_ssl_capath is not None:
            chm.append("MASTER_SSL_CAPATH='%s'" % master_ssl_capath)
        if master_ssl_cert is not None:
            chm.append("MASTER_SSL_CERT='%s'" % master_ssl_cert)
        if master_ssl_key is not None:
            chm.append("MASTER_SSL_KEY='%s'" % master_ssl_key)
        if master_ssl_cipher is not None:
            chm.append("MASTER_SSL_CIPHER='%s'" % master_ssl_cipher)
        if master_auto_position:
            chm.append("MASTER_AUTO_POSITION=1")
        if master_use_gtid is not None:
            chm.append("MASTER_USE_GTID=%s" % master_use_gtid)
        try:
            changemaster(cursor, chm, connection_name, channel)
        except mysql_driver.Warning as e:
            result['warning'] = to_native(e)
        except Exception as e:
            module.fail_json(msg='%s. Query == CHANGE MASTER TO %s' %
                             (to_native(e), chm))
        result['changed'] = True
        module.exit_json(queries=executed_queries, **result)
    elif mode in "startslave":
        started = start_slave(module, cursor, connection_name, channel,
                              fail_on_error)
        if started is True:
            module.exit_json(msg="Slave started ",
                             changed=True,
                             queries=executed_queries)
        else:
            module.exit_json(
                msg="Slave already started (Or cannot be started)",
                changed=False,
                queries=executed_queries)
    elif mode in "stopslave":
        stopped = stop_slave(module, cursor, connection_name, channel,
                             fail_on_error)
        if stopped is True:
            module.exit_json(msg="Slave stopped",
                             changed=True,
                             queries=executed_queries)
        else:
            module.exit_json(msg="Slave already stopped",
                             changed=False,
                             queries=executed_queries)
    elif mode in "resetmaster":
        reset = reset_master(module, cursor, fail_on_error)
        if reset is True:
            module.exit_json(msg="Master reset",
                             changed=True,
                             queries=executed_queries)
        else:
            module.exit_json(msg="Master already reset",
                             changed=False,
                             queries=executed_queries)
    elif mode in "resetslave":
        reset = reset_slave(module, cursor, connection_name, channel,
                            fail_on_error)
        if reset is True:
            module.exit_json(msg="Slave reset",
                             changed=True,
                             queries=executed_queries)
        else:
            module.exit_json(msg="Slave already reset",
                             changed=False,
                             queries=executed_queries)
    elif mode in "resetslaveall":
        reset = reset_slave_all(module, cursor, connection_name, channel,
                                fail_on_error)
        if reset is True:
            module.exit_json(msg="Slave reset",
                             changed=True,
                             queries=executed_queries)
        else:
            module.exit_json(msg="Slave already reset",
                             changed=False,
                             queries=executed_queries)

    warnings.simplefilter("ignore")