コード例 #1
0
async def ping_loop(ctx, ping_interval, cycle_time, initial_ping_timeout,
                    ping_retries, backoff, loop, inventory_router_url):
    """

    :param ctx:
    :param ping_interval:
    :param cycle_time:
    :param initial_ping_timeout:
    :param ping_retries:
    :param backoff:
    :param loop:
    :param inventory_router_url:
    :return:
    """
    # load the queue
    inventory_client = InventoryClient(inventory_router_url)

    while True:
        if stop_ping_loop:
            log.info('Stopping ping loop')
            break
        log.debug('Looking for work')
        now = time.time()
        for mercury_id, data in list(active_state.items(
        )):  # copy to list because the list length could change
            # out from under us
            if now - data['last_ping'] > ping_interval and not data['pinging']:
                log.debug('Scheduling ping for {}'.format(mercury_id))
                active_state[mercury_id]['pinging'] = True
                asyncio.ensure_future(ping(data, ctx, initial_ping_timeout,
                                           ping_retries, backoff,
                                           inventory_client),
                                      loop=loop)
        await asyncio.sleep(cycle_time)
コード例 #2
0
ファイル: service.py プロジェクト: SovietPanda/mercury
def reacquire(inventory_url, backend_name):
    """

    :param inventory_url:
    :param backend_name:
    :return:
    """
    # Onetime use synchronous client
    log.info('Attempting to reacquire active agents')
    log.debug('Inventory Router: {}'.format(inventory_url))

    inventory_client = InventoryClient(inventory_url,
                                       # TODO: Add these to configuration
                                       response_timeout=60,
                                       rcv_retry=10)

    existing_documents = inventory_client.query({'active': {'$ne': None},
                                                 'origin.name': backend_name},
                                                projection={'mercury_id': 1,
                                                            'active': 1})

    if existing_documents.get('error'):  # Transport Error
        log.error('[BACKEND CRITICAL] '
                  'Error communicating with inventory service, could not '
                  'reacquire: <{}>'.format(existing_documents.get('message')))
        # Return without reacquiring any nodes. Once communication is
        # reestablished, agents will begin to re-register
        return

    for doc in existing_documents['message']['items']:
        if not BackendController.validate_agent_info(doc['active']):
            log.error('Found junk in document {} expunging'.format(
                doc['mercury_id']))
            inventory_client.update_one(doc['mercury_id'], {'active': None})

        log.info('Attempting to reacquire %s : %s' % (
            doc['mercury_id'], doc['active']['rpc_address']))
        add_active_record(doc)

    log.info('Reacquire operation complete')
    inventory_client.close()
コード例 #3
0
ファイル: backend.py プロジェクト: BenjamenMeyer/mercury
    def reacquire(self):

        # Onetime use synchronous client
        inventory_client = InventoryClient(self.inventory_router_url)

        existing_documents = inventory_client.query({'active': {
            '$ne': None
        }},
                                                    projection={
                                                        'mercury_id': 1,
                                                        'active': 1
                                                    })
        for doc in existing_documents['items']:
            if not self.controller.validate_agent_info(doc['active']):
                log.error('Found junk in document {} expunging'.format(
                    doc['mercury_id']))
                inventory_client.update_one(doc['mercury_id'],
                                            {'active': None})

            log.info('Attempting to reacquire %s : %s' %
                     (doc['mercury_id'], doc['active']['rpc_address']))
            add_active_record(doc)

        inventory_client.close()
コード例 #4
0
 def __init__(self, *args, **kwargs):
     super(DiscoverView, self).__init__(*args, **kwargs)
     inventory_url = configuration.inventory.inventory_router
     self.inventory_client = InventoryClient(inventory_url)
コード例 #5
0
class DiscoverView(MethodView):
    """
    Discover method view
    """
    def __init__(self, *args, **kwargs):
        super(DiscoverView, self).__init__(*args, **kwargs)
        inventory_url = configuration.inventory.inventory_router
        self.inventory_client = InventoryClient(inventory_url)

    @staticmethod
    def render_agent_script():
        with open('scripts/agent.ipxe') as fp:
            template = fp.read()

        return pystache.render(template, **configuration)

    @staticmethod
    def plain(message):
        return Response(message, content_type='text/plain')

    def get(self, mac_address):
        """ Attempt to relate a device using the provided mac address """
        result = self.inventory_client.query(
            {'interfaces.address': mac_address},
            projection={
                'boot': 1,
                'mercury_id': 1,
                'dmi': 1
            })

        if result.get('error'):
            abort(500, result)

        message = result['message']

        if not message['total']:
            log.info('New device: {}'.format(mac_address))
            return self.plain(self.render_agent_script())

        if message['total'] > 1:
            log.error('DUPLICATE MAC ADDRESS: {}'.format(mac_address))
            abort(500, 'Duplicate mac addresses in inventory')

        inventory_data = message['items'][0]

        boot_info = inventory_data.get('boot', {})

        if boot_info.get('script'):
            # Dangerous, can potentially leak entire configuration into image
            # if an attacker knows the key names
            return pystache.render(boot_info['script'],
                                   dict(**inventory_data, **configuration))

        boot_state = boot_info.get('state', 'agent')

        if boot_state == 'local':
            log.info('Booting {} from hard drive'.format(
                inventory_data['mercury_id']))
            return self.plain('#!ipxe\nexit\n')

        elif boot_info == 'rescue':
            log.info('Booting {} to rescue mode'.format(
                inventory_data['mercury_id']))
            return self.plain('Boot rescue iPXE script here')

        log.info('Booting {} to agent'.format(inventory_data['mercury_id']))
        print(request.base_url)
        return self.plain(self.render_agent_script())
コード例 #6
0
import bson
import logging

from bottle import route, run, request, HTTPResponse
from mercury.common.clients.inventory import InventoryClient
from mercury.common.clients.rpc.frontend import RPCFrontEndClient

from mercury_api.configuration import api_configuration

log = logging.getLogger(__name__)
logging.basicConfig(level=logging.DEBUG)

inventory_router_url = api_configuration['inventory']['inventory_router']
rpc_router_url = api_configuration['rpc']['rpc_router']

inventory_client = InventoryClient(inventory_router_url)
rpc_client = RPCFrontEndClient(rpc_router_url)


def http_error(message, code=500):
    return HTTPResponse({'error': True, 'message': message}, status=code)


def validate_json(f):
    def wrapper(*args, **kwargs):
        try:
            if not request.json:
                return http_error('JSON request is missing', code=400)
        except ValueError:
            log.debug('JSON request is malformed: {}'.format(
                request.body.read()))