Univention Bugzilla – Bug 55057
wrong status code 201 (CREATED) instead of 202 (ACCEPTED) for UDM REST API move operation
Last modified: 2024-03-08 10:35:42 CET
The UDM REST API returns status code 201 (CREATED) instead of 202 (ACCEPTED) for a move operation. Patch: diff --git management/univention-directory-manager-rest/src/univention/admin/rest/module.py management/univention-directory-manager-rest/src/univention/admin/rest/module.py index 302aff81b4..f11a716735 100755 --- management/univention-directory-manager-rest/src/univention/admin/rest/module.py +++ management/univention-directory-manager-rest/src/univention/admin/rest/module.py @@ -3004,7 +3004,7 @@ class Object(FormBase, Resource): shared_memory.queue[self.request.user_dn] = shared_memory.dict() shared_memory.queue[self.request.user_dn][status_id] = status - self.set_status(201) + self.set_status(202) self.set_header('Location', self.abspath('progress', status['id'])) self.add_caching(public=False, must_revalidate=True) self.content_negotiation(dict(status)) diff --git management/univention-directory-manager-rest/src/univention/admin/rest/client/__init__.py management/univention-directory-manager-rest/src/univention/admin/rest/client/__init__.py index e027249981..1e27950f42 100755 --- management/univention-directory-manager-rest/src/univention/admin/rest/client/__init__.py +++ management/univention-directory-manager-rest/src/univention/admin/rest/client/__init__.py @@ -668,8 +668,8 @@ class Object(Client): def _follow_redirection(self, response, reload=True): # type: (Response, bool) -> Response location = None - # python-requests doesn't follow redirects for 201 - if response.response.status_code == 201 and 'Location' in response.response.headers: + # python-requests doesn't follow redirects for 20X + if response.response.status_code in (201, 202) and 'Location' in response.response.headers: location = response.response.headers['Location'] response = self.client.make_request('GET', location, allow_redirects=False)
What fixed, please verify that the UDM REST API client (https://github.com/univention/python-udm-rest-api-client/) still works. If not, please create a new bug for it, and depend on it (wait with the release) - this is an API change.
(In reply to Daniel Tröder from comment #1) > What fixed, please verify that the UDM REST API client > (https://github.com/univention/python-udm-rest-api-client/) still works. > If not, please create a new bug for it, and depend on it (wait with the > release) - this is an API change. The client is compatible since python-udm-rest-api-client 1.0.11 (2022-10-19): https://github.com/univention/python-udm-rest-api-client/pull/107
I think we need this for the kelvin api. It looks like the udm-rest-client is trying to make a progress call due to the 201 status. But that progress call than fails. Log for the progress call /var/log/apache2/access.log: ``` 172.17.0.1 - - [28/Nov/2022:14:10:54 +0100] "PUT /univention/udm//users/user/uid=t1,cn=lehrer,cn=users,ou=DEMOSCHOOL,dc=school,dc=test HTTP/1.1" 201 1100 "-" "udm-rest-client/1.0.13" 172.17.0.1 - - [28/Nov/2022:14:10:54 +0100] "GET /univention/udm/progress/6e195e06-60b1-45a1-81a5-a5198aa2f257 HTTP/1.1" 404 1707 "-" "Python/3.8 aiohttp/3.8.3" 172.17.0.2 - - [28/Nov/2022:14:10:53 +0100] "PUT /ucsschool/kelvin/v1/users/t1 HTTP/1.1" 500 332 "-" "python-httpx/0.23.1" ``` Kelvin log: ``` Traceback (most recent call last): File "/usr/lib/python3.8/site-packages/uvicorn/protocols/http/h11_impl.py", line 407, in run_asgi result = await app( # type: ignore[func-returns-value] File "/usr/lib/python3.8/site-packages/uvicorn/middleware/proxy_headers.py", line 78, in __call__ return await self.app(scope, receive, send) File "/usr/lib/python3.8/site-packages/fastapi/applications.py", line 270, in __call__ await super().__call__(scope, receive, send) File "/usr/lib/python3.8/site-packages/starlette/applications.py", line 124, in __call__ await self.middleware_stack(scope, receive, send) File "/usr/lib/python3.8/site-packages/starlette/middleware/errors.py", line 184, in __call__ raise exc File "/usr/lib/python3.8/site-packages/starlette/middleware/errors.py", line 162, in __call__ await self.app(scope, receive, _send) File "/usr/lib/python3.8/site-packages/starlette/middleware/base.py", line 106, in __call__ response = await self.dispatch_func(request, call_next) File "/usr/lib/python3.8/site-packages/fastapi_utils/timing.py", line 47, in timing_middleware response = await call_next(request) File "/usr/lib/python3.8/site-packages/starlette/middleware/base.py", line 80, in call_next raise app_exc File "/usr/lib/python3.8/site-packages/starlette/middleware/base.py", line 69, in coro await self.app(scope, receive_or_disconnect, send_no_error) File "/usr/lib/python3.8/site-packages/asgi_correlation_id/middleware.py", line 81, in __call__ await self.app(scope, receive, handle_outgoing_request) File "/usr/lib/python3.8/site-packages/starlette/middleware/exceptions.py", line 79, in __call__ raise exc File "/usr/lib/python3.8/site-packages/starlette/middleware/exceptions.py", line 68, in __call__ await self.app(scope, receive, sender) File "/usr/lib/python3.8/site-packages/fastapi/middleware/asyncexitstack.py", line 21, in __call__ raise e File "/usr/lib/python3.8/site-packages/fastapi/middleware/asyncexitstack.py", line 18, in __call__ await self.app(scope, receive, send) File "/usr/lib/python3.8/site-packages/starlette/routing.py", line 706, in __call__ await route.handle(scope, receive, send) File "/usr/lib/python3.8/site-packages/starlette/routing.py", line 276, in handle await self.app(scope, receive, send) File "/usr/lib/python3.8/site-packages/starlette/routing.py", line 66, in app response = await func(request) File "/usr/lib/python3.8/site-packages/fastapi/routing.py", line 235, in app raw_response = await run_endpoint_function( File "/usr/lib/python3.8/site-packages/fastapi/routing.py", line 161, in run_endpoint_function return await dependant.call(**values) File "/kelvin/kelvin-api/ucsschool/kelvin/routers/user.py", line 1286, in complete_update user_current = await change_school(udm, logger, user_current, new_school, new_schools.copy()) File "/kelvin/kelvin-api/ucsschool/kelvin/routers/user.py", line 879, in change_school await user.change_school(new_school, udm) File "/kelvin/ucs-school-import/modules/ucsschool/importer/models/import_user.py", line 326, in change_school res = await super(ImportUser, self).change_school(school, lo) File "/kelvin/ucs-school-lib/modules/ucsschool/lib/models/base.py", line 809, in change_school return await self.move(lo, force=True) File "/kelvin/ucs-school-import/modules/ucsschool/importer/models/import_user.py", line 1178, in move return await super(ImportUser, self).move(lo, udm_obj, force) File "/kelvin/ucs-school-lib/modules/ucsschool/lib/models/base.py", line 761, in move success = await self.move_without_hooks(lo, udm_obj, force) File "/kelvin/ucs-school-import/modules/ucsschool/importer/models/import_user.py", line 1185, in move_without_hooks return await super(ImportUser, self).move_without_hooks(lo, udm_obj, force) File "/kelvin/ucs-school-lib/modules/ucsschool/lib/models/base.py", line 781, in move_without_hooks await self.do_move(udm_obj, lo) File "/kelvin/ucs-school-lib/modules/ucsschool/lib/models/base.py", line 794, in do_move await udm_obj.save() File "/usr/lib/python3.8/site-packages/udm_rest_client/base_http.py", line 704, in save api_obj = await self._move(self.position, language=language) File "/usr/lib/python3.8/site-packages/udm_rest_client/base_http.py", line 891, in _move udm_api_response = await self._follow_move_redirects( File "/usr/lib/python3.8/site-packages/udm_rest_client/base_http.py", line 948, in _follow_move_redirects raise ApiException( openapi_client_udm.exceptions.ApiException: (UDM REST API returned status 404, headers: <CIMultiDictProxy('Date': 'Mon, 28 Nov 2022 13:10:54 GMT', 'Server': 'Univention/1.0', 'X-Permitted-Cross-Domain-Policies': 'master-only', 'X-XSS-Protection': '1; mode=block', 'X-Content-Type-Options': 'nosniff', 'Content-Security-Policy': "frame-ancestors 'none';", 'Content-Language': 'en-US', 'Content-Type': 'text/html; charset=UTF-8', 'Access-Control-Expose-Headers': '*, Authorization, X-Request-Id', 'X-Request-Id': '007f3ff4-0e15-4fff-8a57-af67f387249e', 'Link': '<https://backup1.school.test/univention/udm/progress/6e195e06-60b1-45a1-81a5-a5198aa2f257>; rel="self"; title="HTTP-Error 404: "', 'Link': '<https://backup1.school.test/univention/udm/css/style.css>; rel="stylesheet"', 'Cache-Control': 'private, must-revalidate, no-cache, no-store', 'Vary': 'Accept,Accept-Language,Accept-Encoding,Authorization', 'Content-Length': '862', 'Via': '1.1 backup1.school.test')> for move of UdmObject('users/user', 'uid=t1,cn=lehrer,cn=users,ou=DEMOSCHOOL,dc=school,dc=test') to position 'cn=lehrer,cn=users,ou=school1,dc=school,dc=test'.) ```
MR: https://git.knut.univention.de/univention/ucs/-/merge_requests/579
(In reply to Florian Best from comment #5) > MR: https://git.knut.univention.de/univention/ucs/-/merge_requests/579 I tried the changes in the MR and now get a different error, sorry. Do you think this a new bug or part of this one? Python UDM REST Client: 1.0.13 I also tried "update_openapi_client", but no change. ``` Traceback (most recent call last): File "/usr/lib/python3.8/site-packages/uvicorn/protocols/http/h11_impl.py", line 407, in run_asgi result = await app( # type: ignore[func-returns-value] File "/usr/lib/python3.8/site-packages/uvicorn/middleware/proxy_headers.py", line 78, in __call__ return await self.app(scope, receive, send) File "/usr/lib/python3.8/site-packages/fastapi/applications.py", line 270, in __call__ await super().__call__(scope, receive, send) File "/usr/lib/python3.8/site-packages/starlette/applications.py", line 124, in __call__ await self.middleware_stack(scope, receive, send) File "/usr/lib/python3.8/site-packages/starlette/middleware/errors.py", line 184, in __call__ raise exc File "/usr/lib/python3.8/site-packages/starlette/middleware/errors.py", line 162, in __call__ await self.app(scope, receive, _send) File "/usr/lib/python3.8/site-packages/starlette/middleware/base.py", line 106, in __call__ response = await self.dispatch_func(request, call_next) File "/usr/lib/python3.8/site-packages/fastapi_utils/timing.py", line 47, in timing_middleware response = await call_next(request) File "/usr/lib/python3.8/site-packages/starlette/middleware/base.py", line 80, in call_next raise app_exc File "/usr/lib/python3.8/site-packages/starlette/middleware/base.py", line 69, in coro await self.app(scope, receive_or_disconnect, send_no_error) File "/usr/lib/python3.8/site-packages/asgi_correlation_id/middleware.py", line 81, in __call__ await self.app(scope, receive, handle_outgoing_request) File "/usr/lib/python3.8/site-packages/starlette/middleware/exceptions.py", line 79, in __call__ raise exc File "/usr/lib/python3.8/site-packages/starlette/middleware/exceptions.py", line 68, in __call__ await self.app(scope, receive, sender) File "/usr/lib/python3.8/site-packages/fastapi/middleware/asyncexitstack.py", line 21, in __call__ raise e File "/usr/lib/python3.8/site-packages/fastapi/middleware/asyncexitstack.py", line 18, in __call__ await self.app(scope, receive, send) File "/usr/lib/python3.8/site-packages/starlette/routing.py", line 706, in __call__ await route.handle(scope, receive, send) File "/usr/lib/python3.8/site-packages/starlette/routing.py", line 276, in handle await self.app(scope, receive, send) File "/usr/lib/python3.8/site-packages/starlette/routing.py", line 66, in app response = await func(request) File "/usr/lib/python3.8/site-packages/fastapi/routing.py", line 235, in app raw_response = await run_endpoint_function( File "/usr/lib/python3.8/site-packages/fastapi/routing.py", line 161, in run_endpoint_function return await dependant.call(**values) File "/kelvin/kelvin-api/ucsschool/kelvin/routers/user.py", line 1286, in complete_update user_current = await change_school(udm, logger, user_current, new_school, new_schools.copy()) File "/kelvin/kelvin-api/ucsschool/kelvin/routers/user.py", line 879, in change_school await user.change_school(new_school, udm) File "/kelvin/ucs-school-import/modules/ucsschool/importer/models/import_user.py", line 326, in change_school res = await super(ImportUser, self).change_school(school, lo) File "/kelvin/ucs-school-lib/modules/ucsschool/lib/models/base.py", line 809, in change_school return await self.move(lo, force=True) File "/kelvin/ucs-school-import/modules/ucsschool/importer/models/import_user.py", line 1178, in move return await super(ImportUser, self).move(lo, udm_obj, force) File "/kelvin/ucs-school-lib/modules/ucsschool/lib/models/base.py", line 761, in move success = await self.move_without_hooks(lo, udm_obj, force) File "/kelvin/ucs-school-import/modules/ucsschool/importer/models/import_user.py", line 1185, in move_without_hooks return await super(ImportUser, self).move_without_hooks(lo, udm_obj, force) File "/kelvin/ucs-school-lib/modules/ucsschool/lib/models/base.py", line 781, in move_without_hooks await self.do_move(udm_obj, lo) File "/kelvin/ucs-school-lib/modules/ucsschool/lib/models/base.py", line 794, in do_move await udm_obj.save() File "/usr/lib/python3.8/site-packages/udm_rest_client/base_http.py", line 704, in save api_obj = await self._move(self.position, language=language) File "/usr/lib/python3.8/site-packages/udm_rest_client/base_http.py", line 871, in _move new_api_obj, status, header = await self._udm_module.session.call_openapi( File "/usr/lib/python3.8/site-packages/udm_rest_client/base_http.py", line 457, in call_openapi _dn = None if status == 204 else api_model_obj.dn AttributeError: 'dict' object has no attribute 'dn' ```
(In reply to Jürn Brodersen from comment #6) > I tried the changes in the MR and now get a different error, sorry. Do you > think this a new bug or part of this one? I think it's a different bug related to problems in the shared memory. > ``` > Traceback (most recent call last): … > _dn = None if status == 204 else api_model_obj.dn > AttributeError: 'dict' object has no attribute 'dn' > ``` This has been fixed in: https://git.knut.univention.de/univention/components/python-udm-rest-api-client/-/merge_requests/11
(In reply to Florian Best from comment #7) > (In reply to Jürn Brodersen from comment #6) > > I tried the changes in the MR and now get a different error, sorry. Do you > > think this a new bug or part of this one? > I think it's a different bug related to problems in the shared memory. The problem was that the service was accessed with a different `Accept-Language` header when following the move-redirects. The move-progress is not shared across language-bound-processes.
QA: Code: OK Changelog: OK Tests: OK Correct status code: OK
univention-directory-manager-rest (11.0.5) 154e1cc083af | fix(udm-rest)!: change status code to 202 for move operations