def get_config(ip, port):
    try:
        nodes = g.database.run(
            'select',
            'controller_security',
            ['old_password', 'password'],
            "`ip` = %s",
            [ip]
        )
        password = nodes[0][1] if nodes[0][1] is not None else ''
        old_password = (nodes[0][0] if nodes[0][0] is not None else password)
    except:
        password = ''
        old_password = ''

    luci = ams.luci.LuCI(ip, 80, password)
    if not luci.auth():
        luci = ams.luci.LuCI(ip, 80, old_password)
    if not luci.auth():
        luci = ams.luci.LuCI(ip, 80, '')
    if not luci.auth():
        return '{"result": "auth false"}'

    result = luci.put('uci', 'get_all', ['cgminer.default'])
    return ams_dumps(result)
def get_config(ip, port):
    import ams.luci
    clause = "`ip` = '{}'".format(ip)
    nodes = g.database.run('select', 'controller_config', ['password'], clause)
    if not nodes:
        return '{"result": "wrong node"}'
    password = nodes[0][0] if nodes[0][0] is not None else ''
    luci = ams.luci.LuCI(ip, 80, password)
    luci.auth()
    result = luci.put('uci', 'get_all', ['cgminer.default'])
    return json.dumps(result)
def get_config(ip, port):
    import ams.luci
    clause = "`ip` = '{}'".format(ip)
    nodes = g.database.run('select', 'controller_config', ['password'], clause)
    if not nodes:
        return '{"result": "wrong node"}'
    password = nodes[0][0] if nodes[0][0] is not None else ''
    luci = ams.luci.LuCI(ip, 80, password)
    luci.auth()
    result = luci.put('uci', 'get_all', ['cgminer.default'])
    return json.dumps(result)
def get_info(ip, port):
    import ams.luci
    clause = "`ip` = '{}'".format(ip)
    nodes = g.database.run('select', 'controller_config', ['password'], clause)
    if not nodes:
        return '{"result": "wrong node"}'
    password = nodes[0][0] if nodes[0][0] is not None else ''
    luci = ams.luci.LuCI(ip, 80, password)
    luci.auth()
    result = luci.put('uci', 'exec', ['ubus call network.device status'])
    result = json.loads(result['result'])
    mac = result['eth0']['macaddr']
    return json.dumps({'mac': mac})
def get_info(ip, port):
    import ams.luci
    clause = "`ip` = '{}'".format(ip)
    nodes = g.database.run('select', 'controller_config', ['password'], clause)
    if not nodes:
        return '{"result": "wrong node"}'
    password = nodes[0][0] if nodes[0][0] is not None else ''
    luci = ams.luci.LuCI(ip, 80, password)
    luci.auth()
    result = luci.put('uci', 'exec', ['ubus call network.device status'])
    result = json.loads(result['result'])
    mac = result['eth0']['macaddr']
    return json.dumps({'mac': mac})
def get_config(ip, port):
    try:
        nodes = g.database.run('select', 'controller_security',
                               ['old_password', 'password'], "`ip` = %s", [ip])
        password = nodes[0][1] if nodes[0][1] is not None else ''
        old_password = (nodes[0][0] if nodes[0][0] is not None else password)
    except:
        password = ''
        old_password = ''

    luci = ams.luci.LuCI(ip, 80, password)
    if not luci.auth():
        luci = ams.luci.LuCI(ip, 80, old_password)
    if not luci.auth():
        luci = ams.luci.LuCI(ip, 80, '')
    if not luci.auth():
        return '{"result": "auth false"}'

    result = luci.put('uci', 'get_all', ['cgminer.default'])
    return ams_dumps(result)
def luciThread(node_queue, result_queue, commands, db, log, lock):
    database = DataBase(db)
    database.connect()
    while True:
        try:
            node = node_queue.get(False)
        except:
            break

        database.start_transaction()
        result = database.run('select', 'controller_security', ['password'],
                              "`ip` = %s FOR UPDATE", [node['ip']])
        if not result or not result[0]:
            password = ''
        else:
            password = result[0][0] if result[0][0] is not None else ''

        error = False
        auth = True
        for i in range(3):
            j = 0
            try:
                luci = ams.luci.LuCI(node['ip'], 80, password)
                if not luci.auth():
                    luci = ams.luci.LuCI(node['ip'], 80, '')
                if not luci.auth():
                    auth = False
                    error = True
                    break
                auth = True
                database.commit()
                result = []
                for c in commands[j:]:
                    if c['params'] is not None:
                        for i, param in enumerate(c['params']):
                            c['params'][i] = param.replace(
                                '`ip4`', node['ip'].split('.')[3])
                    if c['method'] == 'user.setpasswd':
                        new_password = base64.b64encode(os.urandom(9)).decode()
                        c['params'] = ['root', new_password]
                        database.start_transaction()
                        result = database.run('select', 'controller_security',
                                              ['password'],
                                              "`ip` = %s FOR UPDATE",
                                              [node['ip']])

                    r = luci.put(c['lib'], c['method'], c['params'], i + 10)

                    if c['method'] == 'user.setpasswd':
                        if r['error'] is None:
                            database.run(
                                'raw', '''\
INSERT INTO controller_security
       (ip, password)
VALUES (%s, %s)
    ON DUPLICATE KEY UPDATE
       password = %s''', [node['ip'], new_password, new_password])
                        database.commit()

                    with lock:
                        log.debug('[{}][{}][{}][{}][{}]'.format(
                            node['ip'],
                            c['method'],
                            '|'.join(c['params']),
                            r['result'],
                            r['error'],
                        ))

                    result.append(r)

                    j += 1
                error = False
                break
            except Exception as e:
                with lock:
                    log.error('[{}]'.format(e))
                error = True
                continue

        if not auth:
            result.append({'result': 'Authentication Failed'})
        elif error:
            result.append({'result': 'Connection Failed'})
        result_queue.put({
            'node': node,
            'result': result,
            'error': error,
        })
        node_queue.task_done()
    database.disconnect()
def luciThread(node_queue, result_queue, commands, db, log, lock):
    database = DataBase(db)
    database.connect()
    while True:
        try:
            node = node_queue.get(False)
        except:
            break

        database.start_transaction()
        result = database.run(
            'select',
            'controller_security',
            ['password'],
            "`ip` = %s FOR UPDATE",
            [node['ip']]
        )
        if not result or not result[0]:
            password = ''
        else:
            password = result[0][0] if result[0][0] is not None else ''

        error = False
        auth = True
        for i in range(3):
            j = 0
            try:
                luci = ams.luci.LuCI(node['ip'], 80, password)
                if not luci.auth():
                    luci = ams.luci.LuCI(node['ip'], 80, '')
                if not luci.auth():
                    auth = False
                    error = True
                    break
                auth = True
                database.commit()
                result = []
                for c in commands[j:]:
                    if c['params'] is not None:
                        for i, param in enumerate(c['params']):
                            c['params'][i] = param.replace(
                                '`ip4`', node['ip'].split('.')[3]
                            )
                    if c['method'] == 'user.setpasswd':
                        new_password = base64.b64encode(os.urandom(9)).decode()
                        c['params'] = ['root', new_password]
                        database.start_transaction()
                        result = database.run(
                            'select',
                            'controller_security',
                            ['password'],
                            "`ip` = %s FOR UPDATE",
                            [node['ip']]
                        )

                    r = luci.put(c['lib'], c['method'], c['params'], i + 10)

                    if c['method'] == 'user.setpasswd':
                        if r['error'] is None:
                            database.run(
                                'raw',
                                '''\
INSERT INTO controller_security
       (ip, password)
VALUES (%s, %s)
    ON DUPLICATE KEY UPDATE
       password = %s''',
                                [node['ip'], new_password, new_password])
                        database.commit()

                    with lock:
                        log.debug('[{}][{}][{}][{}][{}]'.format(
                            node['ip'],
                            c['method'],
                            '|'.join(c['params']),
                            r['result'],
                            r['error'],
                        ))

                    result.append(r)

                    j += 1
                error = False
                break
            except Exception as e:
                with lock:
                    log.error('[{}]'.format(e))
                error = True
                continue

        if not auth:
            result.append({'result': 'Authentication Failed'})
        elif error:
            result.append({'result': 'Connection Failed'})
        result_queue.put({
            'node': node,
            'result': result,
            'error': error,
        })
        node_queue.task_done()
    database.disconnect()