-
Notifications
You must be signed in to change notification settings - Fork 81
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
Adding delete #236
Adding delete #236
Changes from all commits
b78511a
b24a23b
56b6e1f
7b90090
0015e22
8c8c155
91650a6
961523e
7de7ec5
bfdd88a
7dbe785
ac2a81f
43b9b05
19c25f7
199b835
47e6316
5015d89
100ac9c
1f767e0
eee9b0a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,12 +7,13 @@ | |
from flask_api import status | ||
from marshmallow import ValidationError | ||
|
||
from app import db | ||
from app import db, events | ||
from app.models import Host, HostSchema, PatchHostSchema | ||
from app.auth import current_identity | ||
from app.exceptions import InventoryException | ||
from app.logging import get_logger | ||
from api import api_operation, metrics | ||
from tasks import emit_event | ||
|
||
|
||
TAG_OPERATIONS = ("apply", "remove") | ||
|
@@ -244,6 +245,26 @@ def find_hosts_by_hostname_or_id(account_number, hostname): | |
sqlalchemy.or_(*filter_list)])) | ||
|
||
|
||
@api_operation | ||
@metrics.api_request_time.time() | ||
def delete_by_id(host_id_list): | ||
query = _get_host_list_by_id_list( | ||
current_identity.account_number, host_id_list, order=False | ||
) | ||
|
||
hosts = query.all() | ||
|
||
if not hosts: | ||
return flask.abort(status.HTTP_404_NOT_FOUND) | ||
|
||
with metrics.delete_host_processing_time.time(): | ||
query.delete(synchronize_session="fetch") | ||
db.session.commit() | ||
metrics.delete_host_count.inc(len(hosts)) | ||
for deleted_host in hosts: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This actually doesn’t work The hosts variable is a BaseQuery, not a list. This query is used just a few lines earlier to delete the hosts. Then here, iterating over the hosts run a SELECT query, which doesn’t find anything, because the hosts are already deleted. @api_operation
@metrics.api_request_time.time()
def delete_by_id(host_id_list):
query = _get_host_list_by_id_list(
current_identity.account_number, host_id_list, order=False
)
hosts = query.all()
with metrics.delete_host_processing_time.time():
query.delete(synchronize_session="fetch")
db.session.commit()
metrics.delete_host_count.inc(len(hosts))
for deleted_host in hosts:
emit_event(events.delete(deleted_host.id)) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should be fixed. |
||
emit_event(events.delete(deleted_host.id)) | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is no return statement. The API specification specifies though, that this operations should return 404 Not Found if the host is not found. This is currently not true: 200 OK is returned automatically, but nothing is deleted. Because this can operate on more than one host, I suggest using 207 Multi-Status instead, just at add_host_list does. Like that it’d be possible to return more statūs, one for each records. It can happen that some hosts are found (and deleted) and some are not. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. At this point, I do not think adding the 207 multi-status is required/needed. We can add it later on if we find that it is needed. |
||
|
||
@api_operation | ||
@metrics.api_request_time.time() | ||
def get_host_by_id(host_id_list, page=1, per_page=100): | ||
|
@@ -259,11 +280,16 @@ def get_host_by_id(host_id_list, page=1, per_page=100): | |
) | ||
|
||
|
||
def _get_host_list_by_id_list(account_number, host_id_list): | ||
return Host.query.filter( | ||
def _get_host_list_by_id_list(account_number, host_id_list, order=True): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thinking whether we couldn’t just remove the order_by from this function entirely and use it in the respective places. E.g. the patch operation doesn’t need the ordering at all. The oder operations (get_host_by_id and get_host_system_profile_by_id) use paginate, which is the reason for the ordering. So although repeating the oder_by wouldn’t be dry, it would fit nicely together. But this is not necessary to edit in this PR. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this is fine for now. |
||
q = Host.query.filter( | ||
(Host.account == account_number) | ||
& Host.id.in_(host_id_list) | ||
).order_by(Host.created_on, Host.id) | ||
) | ||
|
||
if order: | ||
return q.order_by(Host.created_on, Host.id) | ||
else: | ||
return q | ||
|
||
|
||
@api_operation | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import logging | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Although I like putting the event schema into a separate module instead of the ever growing app.models one, it’s currently unsystematic. The app.models module already contains many schemas that aren’t models at all, e.g. the PatchHostSchema. I’d keep everything in that bulky module for now and split it later separately. The delete method can be for now put inline into the delete_by_id operation. It’s not very nice, but it’s how we currently do it. The HTTP responses, errors and everything are composed there too. I’d rather have the code consistent than to see many first steps to various refactorings. |
||
from datetime import datetime | ||
from marshmallow import Schema, fields | ||
|
||
logger = logging.getLogger(__name__) | ||
|
||
|
||
class HostEvent(Schema): | ||
id = fields.UUID() | ||
timestamp = fields.DateTime(format="iso8601") | ||
type = fields.Str() | ||
|
||
|
||
def delete(id): | ||
return HostEvent(strict=True).dumps( | ||
{"id": id, "timestamp": datetime.utcnow(), "type": "delete"} | ||
).data |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change is unrelated to the DELETE operation.