Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Diable API if auth is enabled #1225

Merged
merged 3 commits into from
Jul 1, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 1 addition & 9 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,7 @@ Celery command and before Flower sub-command): ::
API
---

Flower API enables to manage the cluster via REST API, call tasks and
receive task events in real-time via WebSockets.
Flower API enables to manage the cluster via REST API.

For example you can restart worker's pool by: ::

Expand All @@ -119,13 +118,6 @@ Or terminate executing task by: ::

$ curl -X POST -d 'terminate=True' http://localhost:5555/api/task/revoke/8a4da87b-e12b-4547-b89a-e92e4d1f8efd

Or receive task completion events in real-time: ::

var ws = new WebSocket("ws://localhost:5555/api/task/events/task-succeeded/");
ws.onmessage = function (event) {
console.log(event.data);
}

For more info checkout `API Reference`_ and `examples`_.

.. _API Reference: https://flower.readthedocs.io/en/latest/api.html
Expand Down
20 changes: 0 additions & 20 deletions examples/event-api.html

This file was deleted.

30 changes: 6 additions & 24 deletions flower/api/__init__.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,7 @@
import tornado.websocket
import tornado.web
from ..views import BaseHandler


class BaseWebSocketHandler(tornado.websocket.WebSocketHandler):
# listeners = [], should be created in derived class

def open(self):
listeners = self.listeners
listeners.append(self)

def on_message(self, message):
pass

def on_close(self):
listeners = self.listeners
if self in listeners:
listeners.remove(self)

@classmethod
def send_message(cls, message):
for l in cls.listeners:
l.write_message(message)

def check_origin(self, origin):
return True
class BaseApiHandler(BaseHandler):
def prepare(self):
if self.application.options.basic_auth or self.application.options.auth:
raise tornado.web.HTTPError(405, "api is not available when auth is enabled")
4 changes: 2 additions & 2 deletions flower/api/control.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@
from tornado import gen
from tornado import util

from ..views import BaseHandler
from . import BaseApiHandler


logger = logging.getLogger(__name__)


class ControlHandler(BaseHandler):
class ControlHandler(BaseApiHandler):
def is_worker(self, workername):
return workername and workername in self.application.workers

Expand Down
35 changes: 0 additions & 35 deletions flower/api/events.py

This file was deleted.

4 changes: 2 additions & 2 deletions flower/api/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from celery.backends.base import DisabledBackend

from ..utils import tasks
from ..views import BaseHandler
from . import BaseApiHandler
from ..utils.broker import Broker
from ..api.control import ControlHandler
from collections import OrderedDict
Expand All @@ -24,7 +24,7 @@
logger = logging.getLogger(__name__)


class BaseTaskHandler(BaseHandler):
class BaseTaskHandler(BaseApiHandler):
DATE_FORMAT = '%Y-%m-%d %H:%M:%S.%f'

def get_task_args(self):
Expand Down
5 changes: 0 additions & 5 deletions flower/events.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,11 +117,6 @@ def event(self, event):
if event_type == 'worker-offline':
self.metrics.worker_online.labels(worker_name).set(0)

# Send event to api subscribers (via websockets)
classname = api.events.getClassName(event_type)
cls = getattr(api.events, classname, None)
if cls:
cls.send_message(event)


class Events(threading.Thread):
Expand Down
10 changes: 0 additions & 10 deletions flower/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

from tornado.web import StaticFileHandler, url

from .api import events
from .api import control
from .api import tasks
from .api import workers
Expand Down Expand Up @@ -57,15 +56,6 @@
(r"/api/task/timeout/(.+)", control.TaskTimout),
(r"/api/task/rate-limit/(.+)", control.TaskRateLimit),
(r"/api/task/revoke/(.+)", control.TaskRevoke),
# Events WebSocket API
(r"/api/task/events/task-sent/(.*)", events.TaskSent),
(r"/api/task/events/task-received/(.*)", events.TaskReceived),
(r"/api/task/events/task-started/(.*)", events.TaskStarted),
(r"/api/task/events/task-succeeded/(.*)", events.TaskSucceeded),
(r"/api/task/events/task-failed/(.*)", events.TaskFailed),
(r"/api/task/events/task-revoked/(.*)", events.TaskRevoked),
(r"/api/task/events/task-retried/(.*)", events.TaskRetried),
(r"/api/task/events/task-custom/(.*)", events.TaskCustom),
# Metrics
(r"/metrics", monitor.Metrics),
(r"/healthcheck", monitor.Healthcheck),
Expand Down
12 changes: 11 additions & 1 deletion tests/unit/api/test_control.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
from mock import MagicMock

import mock
from flower.api.control import ControlHandler

from tests.unit import AsyncHTTPTestCase
from tornado.options import options


class UnknownWorkerControlTests(AsyncHTTPTestCase):
Expand Down Expand Up @@ -169,3 +170,12 @@ def test_terminate_signal(self):
celery.control.revoke.assert_called_once_with('test',
terminate=True,
signal='SIGUSR1')


class ControlAuthTests(WorkerControlTests):
def test_auth(self):
with mock.patch.object(options.mockable(), 'basic_auth', ['user1:password1']):
app = self._app.capp
app.control.broadcast = MagicMock()
r = self.post('/api/worker/shutdown/test', body={})
self.assertEqual(405, r.code)
Empty file removed tests/unit/api/test_events.py
Empty file.