mirror of
https://github.com/ceph/ceph
synced 2026-08-02 07:03:18 +00:00
mgr/dashboard: fix unncessary traceback when bucket not exist
UI has an async validator which calls the GET bucket API to make sure
the bucket name doesn't exist, but the proxy
was not properly handling the http_status_codes which results in raising
a massive traceback in logs whenever you type things in the bucket name
field. So handling that gracefully by capturing the proper status codes
for both RequestException and DashboardException
BEFORE
```
File "/usr/share/ceph/mgr/dashboard/services/exception.py", line 47, in dashboard_exception_handler
return handler(*args, **kwargs)
File "/lib/python3.9/site-packages/cherrypy/_cpdispatch.py", line 54, in _call_
return self.callable(*self.args, **self.kwargs)
File "/usr/share/ceph/mgr/dashboard/controllers/_base_controller.py", line 263, in inner
ret = func(*args, **kwargs)
File "/usr/share/ceph/mgr/dashboard/controllers/_rest_controller.py", line 193, in wrapper
return func(*vpath, **params)
File "/usr/share/ceph/mgr/dashboard/controllers/rgw.py", line 357, in get
result = self.proxy(daemon_name, 'GET', 'bucket', {'bucket': bucket})
File "/usr/share/ceph/mgr/dashboard/controllers/rgw.py", line 213, in proxy
raise DashboardException(e, http_status_code=http_status_code, component='rgw')
dashboard.exceptions.DashboardException: RGW REST API failed request with status code 404
(b'{"Code":"NoSuchBucket","Message":"","RequestId":"tx00000f14e08c1af0d5615-006'
b'71f54a7-3bc6-default","HostId":"3bc6-default-default"}')
2024-10-28T09:08:55.990+0000 7f89e045b640 0 [dashboard INFO request] [::ffff:10.74.18.122:51853] [GET] [500] [0.007s] [admin] [200.0B] /api/rgw/bucket/bucket-das
```
AFTER
```
Jul 08 09:28:28 ceph-node-00 ceph-mgr[2243]: [dashboard ERROR dashboard.rest_client] RGW REST API failed GET req status: 404
Jul 08 09:28:28 ceph-node-00 ceph-mgr[2243]: [dashboard INFO dashboard.services.exception] Dashboard Exception: RGW REST API failed request with status code 404
(b'{"Code":"NoSuchBucket","Message":"","RequestId":"tx00000c029a81e5d154844-006'
b'a4e183c-14251-default","HostId":"14251-default-default"}')
Jul 08 09:28:28 ceph-node-00 ceph-mgr[2243]: [dashboard INFO dashboard.tools] [::ffff:192.168.100.1:60408] [GET] [404] [0.078s] [admin] [200.0B] /api/rgw/bucket/testsa
```
Fixes: https://tracker.ceph.com/issues/78038
Signed-off-by: Nizamudeen A <nia@redhat.com>
This commit is contained in:
parent
dd7b7812d3
commit
0ad33c0965
@ -550,7 +550,7 @@ class RgwUserTest(RgwTestCase):
|
||||
self._delete('/api/rgw/user/teuth-test-user')
|
||||
self.assertStatus(204)
|
||||
self.get_rgw_user('teuth-test-user')
|
||||
self.assertStatus(500)
|
||||
self.assertStatus(404)
|
||||
resp = self.jsonBody()
|
||||
self.assertIn('detail', resp)
|
||||
self.assertIn('failed request with status code 404', resp['detail'])
|
||||
@ -593,7 +593,7 @@ class RgwUserTest(RgwTestCase):
|
||||
self._delete('/api/rgw/user/test01$teuth-test-user')
|
||||
self.assertStatus(204)
|
||||
self.get_rgw_user('test01$teuth-test-user')
|
||||
self.assertStatus(500)
|
||||
self.assertStatus(404)
|
||||
resp = self.jsonBody()
|
||||
self.assertIn('detail', resp)
|
||||
self.assertIn('failed request with status code 404', resp['detail'])
|
||||
|
||||
@ -394,7 +394,11 @@ class RgwRESTController(RESTController):
|
||||
result = json_str_to_object(result)
|
||||
return result
|
||||
except (DashboardException, RequestException) as e:
|
||||
http_status_code = e.status if isinstance(e, DashboardException) else 500
|
||||
response = getattr(e, 'response', None)
|
||||
if isinstance(e, RequestException) and response is not None:
|
||||
http_status_code = getattr(response, 'status_code', 500)
|
||||
else:
|
||||
http_status_code = getattr(e, 'status_code', getattr(e, 'status', None)) or 500
|
||||
raise DashboardException(e, http_status_code=http_status_code, component='rgw')
|
||||
|
||||
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
from unittest.mock import Mock, call, patch
|
||||
|
||||
from .. import mgr
|
||||
from ..controllers.rgw import Rgw, RgwDaemon, RgwTopic, RgwUser
|
||||
from ..controllers.rgw import Rgw, RgwBucket, RgwDaemon, RgwTopic, RgwUser
|
||||
from ..rest_client import RequestException
|
||||
from ..services.rgw_client import RgwClient, RgwMultisite
|
||||
from ..tests import ControllerTestCase, RgwStub
|
||||
@ -600,3 +600,51 @@ class TestRgwTopicController(ControllerTestCase):
|
||||
result = controller.delete(key='RGW22222222222222222:HttpTest')
|
||||
mock_delete_topic.assert_called_with(key='RGW22222222222222222:HttpTest')
|
||||
self.assertEqual(result, None)
|
||||
|
||||
|
||||
class RgwBucketControllerTestCase(ControllerTestCase):
|
||||
@classmethod
|
||||
def setup_server(cls):
|
||||
cls.setup_controllers([RgwBucket], '/test')
|
||||
|
||||
@patch('dashboard.services.rgw_client.RgwClient.admin_instance')
|
||||
def test_get_bucket_not_found(self, mock_admin_instance):
|
||||
mock_instance = Mock()
|
||||
mock_admin_instance.return_value = mock_instance
|
||||
|
||||
mock_response = Mock()
|
||||
mock_response.status_code = 404
|
||||
mock_exception = RequestException('RGW REST API failed request')
|
||||
mock_exception.response = mock_response
|
||||
mock_instance.proxy.side_effect = mock_exception
|
||||
|
||||
self._get('/test/api/rgw/bucket/i-do-not-exist')
|
||||
self.assertStatus(404)
|
||||
|
||||
@patch('dashboard.services.rgw_client.RgwClient.admin_instance')
|
||||
def test_get_bucket_not_found_with_fallback_attribute(self, mock_admin_instance):
|
||||
|
||||
mock_instance = Mock()
|
||||
mock_admin_instance.return_value = mock_instance
|
||||
|
||||
# mock that lacks a .response but has a direct .status_code attribute.
|
||||
mock_exception = RequestException('RGW REST API failed request')
|
||||
mock_exception.status_code = 404
|
||||
|
||||
mock_instance.proxy.side_effect = mock_exception
|
||||
|
||||
self._get('/test/api/rgw/bucket/i-do-not-exist')
|
||||
self.assertStatus(404)
|
||||
|
||||
@patch('dashboard.services.rgw_client.RgwClient.admin_instance')
|
||||
def test_get_bucket_server_error(self, mock_admin_instance):
|
||||
mock_instance = Mock()
|
||||
mock_admin_instance.return_value = mock_instance
|
||||
|
||||
mock_exception = RequestException('Internal Server Error')
|
||||
mock_exception.status_code = 500
|
||||
|
||||
mock_instance.proxy.side_effect = mock_exception
|
||||
|
||||
self._get('/test/api/rgw/bucket/i-do-not-exist')
|
||||
self.assertStatus(500)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user