From 5df61804846c95c5a5f66aba035b568eddd2a98a Mon Sep 17 00:00:00 2001 From: Dmitriy Rabotyagov Date: Tue, 24 Mar 2020 20:15:59 +0200 Subject: [PATCH] Add lodgeit-db script Adds script that makes operations (like pastes removal) that are not secure to do via API without auth. It connects to DB and interacts directly with DB. Change-Id: I8ef65feda92387bf4dc548b8876fc9fb82dadc64 --- lodgeit/cmd/managedb.py | 143 ++++++++++++++++++++++++++++++++++++++++ setup.cfg | 2 + 2 files changed, 145 insertions(+) create mode 100644 lodgeit/cmd/managedb.py diff --git a/lodgeit/cmd/managedb.py b/lodgeit/cmd/managedb.py new file mode 100644 index 0000000..aed31d9 --- /dev/null +++ b/lodgeit/cmd/managedb.py @@ -0,0 +1,143 @@ +import os +import re +from argparse import ArgumentParser, RawTextHelpFormatter +from datetime import datetime, timedelta +from lodgeit.models import Paste +from sqlalchemy import create_engine + + +def get_args(): + """ + Parse arguments provided by user + """ + def __default_db(): + if os.getenv('LODGEIT_DBURI'): + return os.getenv('LODGEIT_DBURI') + else: + return 'sqlite:////tmp/lodgeit.db' + + parser = ArgumentParser( + description=("Local operations with lodegit database which" + "are not supported by API, ie delete pastes"), + formatter_class=RawTextHelpFormatter + ) + parser.add_argument( + "-d", "--database", + dest="dburi", + action="store", + default=__default_db(), + help="Lodgeit database connect to. [default: %(default)s]", + ) + parser.add_argument( + "-a", "--action", + dest="action", + action="store", + required=True, + choices=["delete"], + help="Action to accomplish on lodgeit DB.", + ) + parser.add_argument( + "-i", "--id", + dest="id", + action="store", + help="Apply action to specific paste ID" + ) + parser.add_argument( + "--delta", + dest="delta", + action="store", + help="Do action on pastes created during timeperiod. (h, d)", + default="1d" + ) + parser.add_argument( + "--start", + dest="start", + action="store", + help="Datetime starting from which pastes will be selected", + ) + parser.add_argument( + "--end", + dest="end", + action="store", + help="Datetime until which pastes will be selected", + ) + return parser.parse_args() + + +class Pastes(object): + def __init__(self, uri): + self.uri = uri + self.session = self._create_session() + self.pastes = Paste.__table__ + + @staticmethod + def _delta_format(delta): + """ + Parse provided delta and return timedelta prepared dictionary + """ + delta_type = re.search(r'([0-9]{1,3})([d,h])', delta) + if not delta_type: + raise SystemError( + "Delta has incorrect format." + ) + if delta_type.group(2) == 'h': + return {'hours': int(delta_type.group(1))} + elif delta_type.group(2) == 'd': + return {'days': int(delta_type.group(1))} + + def _create_session(self): + """ + Create DB connection and return session + """ + engine = create_engine(self.uri) + session = engine.connect() + return session + + def delete_by_date(self, start=str(), end=str(), delta="1d"): + """ + Delete pastes which were created during provided timeframe + """ + delta_args = self._delta_format(delta) + if not start and not end: + end = datetime.now() - timedelta(**delta_args) + start = datetime.min + elif start and not end: + end = datetime.now() + elif not start and end: + start = end - timedelta(**delta_args) + + self.session.execute( + self.pastes.delete().where( + self.pastes.c.pub_date < end + ).where( + self.pastes.c.pub_date > start + ) + ) + + def delete_by_id(self, paste_id): + """ + Delete pastes by public ID + """ + self.session.execute( + self.pastes.delete().where( + self.pastes.c.paste_id == paste_id + ) + ) + + +def main(): + args = vars(get_args()) + pastes = Pastes(args['dburi']) + if args['action'] == 'delete': + if 'id' in args: + pastes.delete_by_id(args['id']) + else: + pastes.delete_by_date( + start=args['start'] if 'start' in args else str(), + end=args['end'] if 'end' in args else str(), + delta=args['delta'], + ) + + +if __name__ == "__main__": + main() diff --git a/setup.cfg b/setup.cfg index 971f31d..1847d5b 100644 --- a/setup.cfg +++ b/setup.cfg @@ -10,3 +10,5 @@ author-email = openstack-infra@lists.openstack.org [entry_points] wsgi_scripts = lodgeit-wsgi = lodgeit.application:make_app +console_scripts = + lodgeit-managedb = lodgeit.cmd.managedb:main \ No newline at end of file