Exemplo n.º 1
0
def do_members_history():
    # The information is available only if the agent is started
    wait_for_agent_started(visual_wait=True)

    try:
        history_entries = get_opsbro_json('/agent/members/history')
    except get_request_errors() as exp:
        logger.error('Cannot join opsbro agent to show member history: %s' %
                     exp)
        sys.exit(1)

    print_h1('History')
    for history_entry in history_entries:
        epoch_date = history_entry['date']
        # We want only group type events
        entries = [
            entry for entry in history_entry['entries']
            if entry['type'] == 'node-state-change'
        ]
        if not entries:
            continue
        print_h2(
            '  Date: %s ' %
            time.strftime("%a, %d %b %Y %H:%M:%S", time.localtime(epoch_date)))
        for entry in entries:
            name = entry['name']
            if entry.get('display_name', ''):
                name = '[ ' + entry.get('display_name') + ' ]'
            old_state = entry['old_state']
            new_state = entry['state']

            old_color = NODE_STATE_COLORS.get(old_state, 'cyan')
            old_state_prefix = NODE_STATE_PREFIXS.get(
                old_state, CHARACTERS.double_exclamation)

            new_color = NODE_STATE_COLORS.get(new_state, 'cyan')
            new_state_prefix = NODE_STATE_PREFIXS.get(
                new_state, CHARACTERS.double_exclamation)

            cprint('%s  ' % name.ljust(20), color='magenta', end='')
            cprint(('%s %s' % (old_state_prefix, old_state)).ljust(9),
                   color=old_color,
                   end='')  # 7 for the maximum state string + 2 for prefix

            cprint(' %s ' % CHARACTERS.arrow_left, color='grey', end='')

            cprint(('%s %s' % (new_state_prefix, new_state)).ljust(9),
                   color=new_color
                   )  # 7 for the maximum state string + 2 for prefix
Exemplo n.º 2
0
def do_gossip_add_event(event_type):
    # The information is available only if the agent is started
    wait_for_agent_started(visual_wait=True)

    try:
        r = post_opsbro_json('/agent/event', {'event_type': event_type})
    except get_request_errors() as exp:
        logger.error(exp)
        sys.exit(2)
    cprint('\n %s ' % CHARACTERS.arrow_left, color='grey', end='')
    cprint('%s ' % CHARACTERS.check, color='green', end='')
    cprint('The event ', end='')
    cprint('%s' % event_type, color='magenta', end='')
    cprint(' is ', end='')
    cprint('added', color='green')
Exemplo n.º 3
0
def do_wait_event(event_type, timeout=30):
    # The information is available only if the agent is started
    wait_for_agent_started(visual_wait=True)

    import itertools
    spinners = itertools.cycle(CHARACTERS.spinners)

    for i in range(timeout):
        uri = '/agent/event/%s' % event_type
        logger.debug('ASK FOR EVENT %s' % event_type)
        try:
            evt = get_opsbro_json(
                uri, timeout=1)  # slow timeout to allow fast looping
        # Timemouts: just loop
        except get_not_critical_request_errors() as exp:
            logger.debug(
                'Asking for event: get timeout (%s), skiping this turn' % exp)
            evt = None
        except get_request_errors() as exp:
            logger.error(
                'Cannot ask for event %s because there is a critical error: %s'
                % (event_type, exp))
            sys.exit(2)

        if evt is not None:
            cprint('\n %s ' % CHARACTERS.arrow_left, color='grey', end='')
            cprint('%s ' % CHARACTERS.check, color='green', end='')
            cprint('The event ', end='')
            cprint('%s' % event_type, color='magenta', end='')
            cprint(' is ', end='')
            cprint('detected', color='green')
            sys.exit(0)
        # Not detected? increase loop
        cprint('\r %s ' % next(spinners), color='blue', end='')
        cprint('%s' % event_type, color='magenta', end='')
        cprint(' is ', end='')
        cprint('NOT DETECTED', color='magenta', end='')
        cprint(' (%d/%d)' % (i, timeout), end='')
        # As we did not \n, we must flush stdout to print it
        sys.stdout.flush()
        time.sleep(1)
    cprint("\nThe event %s was not detected after %s seconds" %
           (event_type, timeout))
    sys.exit(2)
Exemplo n.º 4
0
def do_exec(group='*', cmd='uname -a'):
    if cmd == '':
        logger.error('Missing command')
        return
    # The information is available only if the agent is started
    wait_for_agent_started(visual_wait=True)

    try:
        (code, r) = get_opsbro_local('/exec/%s?cmd=%s' % (group, cmd))
    except get_request_errors() as exp:
        logger.error(exp)
        return
    print(r)
    cid = r
    print("Command group launch as cid", cid)
    time.sleep(5)  # TODO: manage a real way to get the result..
    try:
        (code, r) = get_opsbro_local('/exec-get/%s' % cid)
    except get_request_errors() as exp:
        logger.error(exp)
        return
    j = jsoner.loads(r)

    res = j['res']
    for (uuid, e) in res.items():
        node = e['node']
        nname = node['name']
        color = {
            'alive': 'green',
            'dead': 'red',
            'suspect': 'yellow',
            'leave': 'cyan'
        }.get(node['state'], 'cyan')
        cprint(nname, color=color)
        cprint('Return code:', end='')
        color = {0: 'green', 1: 'yellow', 2: 'red'}.get(e['rc'], 'cyan')
        cprint(e['rc'], color=color)
        cprint('Output:', end='')
        cprint(e['output'].strip(), color=color)
        if e['err']:
            cprint('Error:', end='')
            cprint(e['err'].strip(), color='red')
        cprint('')
Exemplo n.º 5
0
def do_exec(group='*', cmd='uname -a'):
    if cmd == '':
        logger.error('Missing command')
        return
    # The information is available only if the agent is started
    wait_for_agent_started(visual_wait=True)
    
    cmd_64 = bytes_to_unicode(base64.b64encode(unicode_to_bytes(cmd)))
    try:
        r = get_opsbro_json('/exec/%s?cmd=%s' % (group, cmd_64))
    except get_request_errors() as exp:
        cprint('ERROR: cannot launch the command: %s' % exp, color='red')
        sys.exit(2)
    
    cid = r
    print("Command group launch as cid", cid)
    time.sleep(5)  # TODO: manage a real way to get the result..
    try:
        r = get_opsbro_json('/exec-get/%s' % cid)
    except get_request_errors() as exp:
        cprint('ERROR: cannot get execution results: %s' % exp, color='red')
        sys.exit(2)
    
    res = r['res']
    print('Launched at: %s' % res)
    
    for (uuid, e) in res.items():
        node = e['node']
        nname = node['name']
        color = {'alive': 'green', 'dead': 'red', 'suspect': 'yellow', 'leave': 'cyan'}.get(node['state'], 'cyan')
        cprint(nname, color=color)
        cprint('Return code for [%s]:' % e['cmd'], end='')
        color = {0: 'green', 1: 'yellow', 2: 'red'}.get(e['rc'], 'cyan')
        cprint(e['rc'], color=color)
        cprint('Output:', end='')
        cprint(e['output'].strip(), color=color)
        if e['err']:
            cprint('Error:', end='')
            cprint(e['err'].strip(), color='red')
        cprint('')
Exemplo n.º 6
0
def do_join(seed=''):
    if seed == '':
        logger.error('Missing target argument. For example 192.168.0.1:6768')
        return
    # The information is available only if the agent is started
    wait_for_agent_started(visual_wait=True)

    try:
        (code, r) = get_opsbro_local('/agent/join/%s' % seed)
    except get_request_errors() as exp:
        logger.error(exp)
        return
    try:
        b = jsoner.loads(r)
    except ValueError as exp:  # bad json
        logger.error('Bad return from the server %s' % exp)
        return
    cprint('Joining %s : ' % seed, end='')
    if b:
        cprint('OK', color='green')
    else:
        cprint('FAILED', color='red')
Exemplo n.º 7
0
def do_leave(nuuid=''):
    # The information is available only if the agent is started
    wait_for_agent_started(visual_wait=True)

    # Lookup at the localhost name first
    if not nuuid:
        try:
            nuuid = get_opsbro_json('/agent/uuid')
        except get_request_errors() as exp:
            logger.error('Cannot join opsbro agent to get our uuid: %s' % exp)
            sys.exit(2)
    uri = '/agent/leave/%s' % nuuid
    try:
        (code, r) = get_opsbro_local(uri)
    except get_request_errors() as exp:
        logger.error(exp)
        return

    if code != 200:
        logger.error('Node %s is missing (return=%s)' % (nuuid, r))
        return
    cprint('Node %s is set to leave state' % nuuid, end='')
    cprint(': OK', color='green')
Exemplo n.º 8
0
def do_ping(node):
    # The information is available only if the agent is started
    wait_for_agent_started(visual_wait=True)

    try:
        node_obj = get_opsbro_json('/agent/query/guess/%s' % node)
    except get_request_errors() as exp:
        logger.error('Cannot query the node: %s' % exp)
        sys.exit(2)
    if node_obj is None:
        cprint('FAILED: cannot find the node %s' % node, color='red')
        sys.exit(2)
    node_uuid = node_obj['uuid']

    try:
        ping_result = get_opsbro_json('/agent/ping/%s' % node_uuid)
    except get_request_errors() as exp:
        logger.error('Cannot launch the node ping: %s' % exp)
        sys.exit(2)
    if 'error' in ping_result:
        cprint('FAILED: %s' % ping_result['error'], color='red')
        sys.exit(2)
    node_state = ping_result['state']
    display_name = node_obj['display_name']
    if not display_name:
        display_name = node_obj['name']

    state_color = NODE_STATE_COLORS.get(node_state)
    state_char = NODE_STATE_PREFIXS.get(node_state)
    cprint(' %s ' % state_char, color=state_color, end='')
    cprint('%-15s ' % display_name, color='magenta', end='')
    cprint('is: ', end='')
    cprint(node_state, color=state_color)

    # If not alive, it's an error
    if node_state != NODE_STATES.ALIVE:
        sys.exit(2)
Exemplo n.º 9
0
def do_wait_members(name='', display_name='', group='', count=1, timeout=30):
    # The information is available only if the agent is started
    wait_for_agent_started(visual_wait=True)

    import itertools
    spinners = itertools.cycle(CHARACTERS.spinners)

    for i in range(timeout):
        try:
            members = get_opsbro_json('/agent/members').values()
        except get_request_errors() as exp:
            logger.error(exp)
            sys.exit(2)
        if name:
            for m in members:
                if m['name'] == name:
                    cprint('\n %s ' % CHARACTERS.arrow_left,
                           color='grey',
                           end='')
                    cprint('%s ' % CHARACTERS.check, color='green', end='')
                    cprint('The member ', end='')
                    cprint('%s' % name, color='magenta', end='')
                    cprint(' is ', end='')
                    cprint('detected', color='green')
                    sys.exit(0)
        elif display_name:
            for m in members:
                if m['display_name'] == display_name:
                    cprint('\n %s ' % CHARACTERS.arrow_left,
                           color='grey',
                           end='')
                    cprint('%s ' % CHARACTERS.check, color='green', end='')
                    cprint('The member ', end='')
                    cprint('%s' % display_name, color='magenta', end='')
                    cprint(' is ', end='')
                    cprint('detected', color='green')
                    sys.exit(0)

        elif group:
            founded = []
            for m in members:
                if group in m['groups']:
                    founded.append(m)

            if len(founded) > count:
                cprint('\n %s ' % CHARACTERS.arrow_left, color='grey', end='')
                cprint('%s ' % CHARACTERS.check, color='green', end='')
                cprint('The group ', end='')
                cprint('%s' % group, color='magenta', end='')
                cprint(' is ', end='')
                cprint('detected', color='green')
                cprint(' with %d members' % len(founded), end='')
                sys.exit(0)

        # Not detected? increase loop
        cprint('\r %s ' % next(spinners), color='blue', end='')
        if name:
            cprint('%s' % name, color='magenta', end='')
        elif display_name:
            cprint('%s' % display_name, color='magenta', end='')
        else:
            cprint('%s' % group, color='magenta', end='')
        cprint(' is ', end='')
        cprint('NOT DETECTED', color='magenta', end='')
        cprint(' (%d/%d)' % (i, timeout), end='')
        # As we did not \n, we must flush stdout to print it
        sys.stdout.flush()
        time.sleep(1)
    cprint("\nThe name/display_name/group was not detected after %s seconds" %
           (timeout))
    sys.exit(2)
Exemplo n.º 10
0
def do_members(detail=False):
    # The information is available only if the agent is started
    wait_for_agent_started(visual_wait=True)

    try:
        members = get_opsbro_json('/agent/members').values()
    except get_request_errors() as exp:
        logger.error('Cannot join opsbro agent to list members: %s' % exp)
        sys.exit(1)
    members = my_sort(members, cmp_f=__sorted_members)
    pprint = libstore.get_pprint()
    logger.debug('Raw members: %s' % (pprint.pformat(members)))
    # If there is a display_name, use it
    max_name_size = max([
        max(len(m['name']),
            len(m.get('display_name', '')) + 4) for m in members
    ])
    max_addr_size = max(
        [len(m['addr']) + len(str(m['port'])) + 1 for m in members])
    zones = set()
    for m in members:
        mzone = m.get('zone', '')
        if mzone == '':
            mzone = NO_ZONE_DEFAULT
        m['zone'] = mzone  # be sure to fix broken zones
        zones.add(mzone)
    zones = list(zones)
    zones.sort()
    for z in zones:
        z_display = z
        if not z:
            z_display = NO_ZONE_DEFAULT
        z_display = z_display.ljust(15)
        title_s = '%s: %s' % (sprintf('Zone', color='yellow', end=''),
                              sprintf(z_display, color='blue', end=''))
        print_h1(title_s, raw_title=True)
        for m in members:
            zone = m.get('zone', NO_ZONE_DEFAULT)
            if zone != z:
                continue
            name = m['name']
            if m.get('display_name', ''):
                name = '[ ' + m.get('display_name') + ' ]'
            groups = m.get('groups', [])
            groups.sort()
            port = m['port']
            addr = m['addr']
            state = m['state']
            is_proxy = m.get('is_proxy', False)
            if not detail:
                cprint('  - %s > ' % zone, color='blue', end='')
                cprint('%s  ' % name.ljust(max_name_size),
                       color='magenta',
                       end='')
            else:
                cprint(' %s  %s  ' % (m['uuid'], name.ljust(max_name_size)),
                       end='')
            c = NODE_STATE_COLORS.get(state, 'cyan')
            state_prefix = NODE_STATE_PREFIXS.get(
                state, CHARACTERS.double_exclamation)
            cprint(('%s %s' % (state_prefix, state)).ljust(9), color=c,
                   end='')  # 7 for the maximum state string + 2 for prefix
            s = ' %s:%s ' % (addr, port)
            s = s.ljust(max_addr_size + 2)  # +2 for the spaces
            cprint(s, end='')
            if is_proxy:
                cprint('proxy ', end='')
            else:
                cprint('      ', end='')
            if detail:
                cprint('%5d' % m['incarnation'], end='')
            cprint(' %s ' % ','.join(groups))
Exemplo n.º 11
0
def do_detect_nodes(auto_join, timeout=5):
    # The information is available only if the agent is started
    wait_for_agent_started(visual_wait=True)

    print_h1('UDP broadcast LAN detection')
    print(
        "Trying to detect other nodes on the network thanks to a UDP broadcast. Will last %ds."
        % timeout)
    cprint(' * The detection scan will be ', end='')
    cprint('%ds' % timeout, color='magenta', end='')
    cprint(' long.')
    threader.create_and_launch(__print_detection_spinner, (timeout, ),
                               'spinner',
                               essential=False)

    # Send UDP broadcast packets from the daemon
    try:
        network_nodes = get_opsbro_json('/agent/detect?timeout=%d' % timeout,
                                        timeout=timeout + 10)
    except get_request_errors() as exp:
        logger.error('Cannot join opsbro agent to detect network nodes: %s' %
                     exp)
        sys.exit(1)
    cprint(" * Detection is DONE")
    print_h1('Detection result')
    if len(network_nodes) == 0:
        cprint(' ERROR: ', color='red', end='')
        cprint("cannot detect (broadcast UDP) other nodes")
        sys.exit(1)
    cprint("Other network nodes detected on this network:")
    cprint(
        '  Name                                 Zone        Address:port          Proxy    Groups'
    )
    for node in network_nodes:
        cprint('  %-35s  %-10s  %s:%d  %5s     %s' %
               (node['name'], node['zone'], node['addr'], node['port'],
                node['is_proxy'], ','.join(node['groups'])))
    if not auto_join:
        cprint('NOTICE: ', color='blue', end='')
        cprint(
            "Auto join (--auto-join) is not enabled, so don't try to join theses nodes"
        )
        return

    # try to join theses nodes so :)
    # NOTE: sort by uuid so we are always joining the same nodes
    # and so we don't have split network if possible (common node)
    all_proxys = sorted([node for node in network_nodes if node['is_proxy']],
                        key=lambda n: n['uuid'])
    not_proxys = sorted(
        [node for node in network_nodes if not node['is_proxy']],
        key=lambda n: n['uuid'])
    if all_proxys:
        node = all_proxys.pop()
        cprint("A proxy node is detected, using it: %s (%s:%d)" %
               (node['name'], node['addr'], node['port']))
        to_connect = '%s:%d' % (node['addr'], node['port'])
    else:
        node = not_proxys.pop()
        cprint("No proxy node detected. Using a standard one: %s (%s:%d)" %
               (node['name'], node['addr'], node['port']))
        to_connect = '%s:%d' % (node['addr'], node['port'])
    do_join(to_connect)
Exemplo n.º 12
0
def do_agent_wait_full_initialized(timeout=30, show_init_header=False):
    import itertools
    from opsbro.agentstates import AGENT_STATES

    if show_init_header:
        spinners = itertools.cycle(CHARACTERS.spinners)
        display_state = AGENT_STATES.AGENT_STATE_INITIALIZING
        agent_state = display_state
        for i in range(timeout):
            _show_init_d_label()
            _print_move_to_init_d_state()
            cprint('[', end='')
            cprint('%s ' % next(spinners), color='cyan',
                   end='')  # note: spinners.next() do not exists in python3
            cprint(display_state, color='blue', end='')
            cprint(']', end='')
            sys.stdout.flush()
            agent_state = wait_for_agent_started(visual_wait=False,
                                                 timeout=1,
                                                 wait_for_spawn=True)

            # If the agent is started, we can exit and show the user help
            if agent_state == AGENT_STATES.AGENT_STATE_OK:
                _show_init_d_label()
                _print_move_to_init_d_state()
                cprint('[', end='')
                cprint('%s OK' % CHARACTERS.check, color='green', end='')
                cprint(']           '
                       )  # lot of space to clean the initializing text
                cprint(
                    '  %s Note: you can have information about OpsBro with the command: opsbro agent info'
                    % CHARACTERS.corner_bottom_left,
                    color='grey')
                return
            # if stopped or initializing, still wait
            elif agent_state in [
                    AGENT_STATES.AGENT_STATE_STOPPED,
                    AGENT_STATES.AGENT_STATE_INITIALIZING
            ]:
                continue
            else:
                cprint('ERROR: the agent state: %s is not managed',
                       color='red')
                sys.exit(2)
        # Oups, timeout reached, still not initialized after this
        _show_init_d_label()
        _print_move_to_init_d_state()
        cprint('FAILED (initialisation was not finish after %d seconds): %s' %
               (timeout, agent_state),
               color='red')
        sys.exit(2)
    else:
        agent_state = wait_for_agent_started(visual_wait=True,
                                             timeout=timeout,
                                             wait_for_spawn=True)
        if agent_state == AGENT_STATES.AGENT_STATE_OK:
            cprint(AGENT_STATES.AGENT_STATE_OK, color='green')
            return
        if agent_state == AGENT_STATES.AGENT_STATE_STOPPED:
            cprint(AGENT_STATES.AGENT_STATE_STOPPED, color='red')
            sys.exit(2)
        if agent_state == AGENT_STATES.AGENT_STATE_INITIALIZING:
            cprint(AGENT_STATES.AGENT_STATE_INITIALIZING, color='yellow')
            sys.exit(2)
        cprint(agent_state, color='grey')