def handle(self, *arg, **options): if options.get('status'): print(Control('dispatcher').status()) return if options.get('running'): print(Control('dispatcher').running()) return if options.get('reload'): return Control('dispatcher').control({'control': 'reload'}) # It's important to close these because we're _about_ to fork, and we # don't want the forked processes to inherit the open sockets # for the DB and memcached connections (that way lies race conditions) django_connection.close() django_cache.close() # spawn a daemon thread to periodically enqueues scheduled tasks # (like the node heartbeat) periodic.run_continuously() reaper.reap() consumer = None # don't ship external logs inside the dispatcher's parent process # this exists to work around a race condition + deadlock bug on fork # in cpython itself: # https://bugs.python.org/issue37429 AWXProxyHandler.disable() with Connection(settings.BROKER_URL) as conn: try: bcast = 'tower_broadcast_all' queues = [ Queue(q, Exchange(q), routing_key=q) for q in (settings.AWX_CELERY_QUEUES_STATIC + [get_local_queuename()]) ] queues.append( Queue( construct_bcast_queue_name(bcast), exchange=Exchange(bcast, type='fanout'), routing_key=bcast, reply=True ) ) consumer = AWXConsumer( 'dispatcher', conn, TaskWorker(), queues, AutoscalePool(min_workers=4) ) consumer.run() except KeyboardInterrupt: logger.debug('Terminating Task Dispatcher') if consumer: consumer.stop()
def test_https_logging_handler_connectivity_test(https_adapter, status, reason, exc, protocol): host = 'example.org' if protocol: host = '://'.join([protocol, host]) https_adapter.status = status https_adapter.reason = reason settings = LazySettings() settings.configure( **{ 'LOG_AGGREGATOR_HOST': host, 'LOG_AGGREGATOR_PORT': 8080, 'LOG_AGGREGATOR_TYPE': 'logstash', 'LOG_AGGREGATOR_USERNAME': '******', 'LOG_AGGREGATOR_PASSWORD': '******', 'LOG_AGGREGATOR_LOGGERS': ['awx', 'activity_stream', 'job_events', 'system_tracking'], 'LOG_AGGREGATOR_PROTOCOL': 'https', 'CLUSTER_HOST_ID': '', 'LOG_AGGREGATOR_TOWER_UUID': str(uuid4()), 'LOG_AGGREGATOR_LEVEL': 'DEBUG', }) class FakeHTTPSHandler(HTTPSHandler): def __init__(self, *args, **kwargs): super(FakeHTTPSHandler, self).__init__(*args, **kwargs) self.session.mount('{}://'.format(protocol or 'https'), https_adapter) def emit(self, record): return super(FakeHTTPSHandler, self).emit(record) with mock.patch.object(AWXProxyHandler, 'get_handler_class') as mock_get_class: mock_get_class.return_value = FakeHTTPSHandler if exc: with pytest.raises(exc) as e: AWXProxyHandler().perform_test(settings) assert str(e).endswith('%s: %s' % (status, reason)) else: assert AWXProxyHandler().perform_test(settings) is None
def test_protocol_not_specified(): settings = LazySettings() settings.configure( **{ 'LOG_AGGREGATOR_HOST': 'https://server.invalid', 'LOG_AGGREGATOR_PORT': 22222, 'LOG_AGGREGATOR_PROTOCOL': None # awx/settings/defaults.py }) handler = AWXProxyHandler().get_handler(custom_settings=settings) assert isinstance(handler, logging.NullHandler)
def test_invalid_kwarg_to_real_handler(): settings = LazySettings() settings.configure( **{ 'LOG_AGGREGATOR_HOST': 'https://server.invalid', 'LOG_AGGREGATOR_PORT': 22222, 'LOG_AGGREGATOR_PROTOCOL': 'udp', 'LOG_AGGREGATOR_VERIFY_CERT': False # setting not valid for UDP handler }) handler = AWXProxyHandler().get_handler(custom_settings=settings) assert not hasattr(handler, 'verify_cert')
def test_real_handler_from_django_settings(params): settings = LazySettings() settings.configure(**params) handler = AWXProxyHandler().get_handler(custom_settings=settings) # need the _reverse_ dictionary from PARAM_NAMES attr_lookup = {} for attr_name, setting_name in PARAM_NAMES.items(): attr_lookup[setting_name] = attr_name for setting_name, val in params.items(): attr_name = attr_lookup[setting_name] if attr_name == 'protocol': continue assert hasattr(handler, attr_name)
def handle(self, *arg, **options): if options.get('status'): print(Control('dispatcher').status()) return if options.get('running'): print(Control('dispatcher').running()) return if options.get('reload'): return Control('dispatcher').control({'control': 'reload'}) # It's important to close these because we're _about_ to fork, and we # don't want the forked processes to inherit the open sockets # for the DB and memcached connections (that way lies race conditions) django_connection.close() django_cache.close() # spawn a daemon thread to periodically enqueues scheduled tasks # (like the node heartbeat) periodic.run_continuously() reaper.reap() consumer = None # don't ship external logs inside the dispatcher's parent process # this exists to work around a race condition + deadlock bug on fork # in cpython itself: # https://bugs.python.org/issue37429 AWXProxyHandler.disable() try: queues = ['tower_broadcast_all', get_local_queuename()] consumer = AWXConsumerPG('dispatcher', TaskWorker(), queues, AutoscalePool(min_workers=4)) consumer.run() except KeyboardInterrupt: logger.debug('Terminating Task Dispatcher') if consumer: consumer.stop()
def post(self, request, *args, **kwargs): defaults = dict() for key in settings_registry.get_registered_settings( category_slug='logging'): try: defaults[key] = settings_registry.get_setting_field( key).get_default() except serializers.SkipField: defaults[key] = None obj = type('Settings', (object, ), defaults)() serializer = self.get_serializer(obj, data=request.data) serializer.is_valid(raise_exception=True) # Special validation specific to logging test. errors = {} for key in ['LOG_AGGREGATOR_TYPE', 'LOG_AGGREGATOR_HOST']: if not request.data.get(key, ''): errors[key] = 'This field is required.' if errors: raise ValidationError(errors) if request.data.get('LOG_AGGREGATOR_PASSWORD', '').startswith('$encrypted$'): serializer.validated_data['LOG_AGGREGATOR_PASSWORD'] = getattr( settings, 'LOG_AGGREGATOR_PASSWORD', '') try: class MockSettings: pass mock_settings = MockSettings() for k, v in serializer.validated_data.items(): setattr(mock_settings, k, v) AWXProxyHandler().perform_test(custom_settings=mock_settings) if mock_settings.LOG_AGGREGATOR_PROTOCOL.upper() == 'UDP': return Response(status=status.HTTP_201_CREATED) except LoggingConnectivityException as e: return Response({'error': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) return Response(status=status.HTTP_200_OK)