diff --git a/nodes/.gitignore b/nodes/.gitignore index 342fca88..e680b52c 100644 --- a/nodes/.gitignore +++ b/nodes/.gitignore @@ -61,4 +61,5 @@ go.work dev.env prod.env test.env +.venv diff --git a/nodes/node_balancer/migrations/migrations.py b/nodes/node_balancer/migrations/migrations.py new file mode 100644 index 00000000..bb1cad90 --- /dev/null +++ b/nodes/node_balancer/migrations/migrations.py @@ -0,0 +1,119 @@ +import argparse +import csv +import json +import logging +import os +import uuid +from typing import Any, Dict, List + +from bugout.app import Bugout + +logging.basicConfig(level=logging.INFO) +logger = logging.getLogger(__name__) + + +def migration_20230522( + token_current_owner: str, token_new_owner: str, new_application_id: str +) -> None: + BUGOUT_BROOD_URL = os.environ.get("BUGOUT_BROOD_URL", "https://auth.bugout.dev") + + bc = Bugout(brood_api_url=BUGOUT_BROOD_URL) + + try: + resources = bc.list_resources(token=token_current_owner, params={}) + except Exception as err: + raise Exception(err) + + logger.info(f"Found {len(resources.resources)} resources") + + cnt = 0 + for resource in resources.resources: + resource_data = resource.resource_data + resource_data["type"] = "nodebalancer-access" + try: + new_resource = bc.create_resource( + token=token_new_owner, + application_id=new_application_id, + resource_data=resource_data, + ) + cnt += 1 + logger.info( + f"Created resource with ID {new_resource.id} and copied modified resource data" + ) + except Exception as err: + logger.error(f"Unable to copy resource with ID {resource.id}, err: {err}") + + logger.info(f"Copied {cnt} resources") + + +MIGRATIONS_LIST = { + "20230522": { + "description": "Modify existing Brood resources to Moonstream resources structure " + "with `type` key equal to `nodebalancer`. And transfer ownership to moonstream admin.", + "exec_func": migration_20230522, + "required_args": [ + "token-current-owner", + "token-new-owner", + "new-application-id", + ], + } +} + + +def list_handler(args: argparse.Namespace) -> None: + return print(MIGRATIONS_LIST) + + +def run_handler(args: argparse.Namespace) -> None: + migration = MIGRATIONS_LIST.get(args.key, None) + if migration is None: + logger.error(f"Migration with key '{args.key}' not found") + return + + migration["exec_func"]( + token_current_owner=args.token_current_owner, + token_new_owner=args.token_new_owner, + new_application_id=args.new_application_id, + ) + + +def main() -> None: + parser = argparse.ArgumentParser( + description="Moonstream mode balancer migrations CLI" + ) + parser.set_defaults(func=lambda _: parser.print_help()) + subcommands = parser.add_subparsers(description="Migration commands") + + parser_list = subcommands.add_parser("list", description="List migrations") + parser_list.set_defaults(func=list_handler) + + parser_run = subcommands.add_parser("run", description="Run migration") + parser_run.add_argument( + "-k", "--key", required=True, type=str, help="Key of migration to run" + ) + parser_run.add_argument( + "--token-current-owner", + type=str, + default=argparse.SUPPRESS, + help="Bugout access token of current resource owner", + ) + parser_run.add_argument( + "--token-new-owner", + type=str, + default=argparse.SUPPRESS, + help="Bugout access token of new resource owner", + ) + parser_run.add_argument( + "--new-application-id", + type=str, + default=argparse.SUPPRESS, + help="Bugout application ID to transfer resources", + ) + parser_run.set_defaults(func=run_handler) + + args = parser.parse_args() + args.func(args) + + +if __name__ == "__main__": + main() diff --git a/nodes/node_balancer/migrations/requirements.txt b/nodes/node_balancer/migrations/requirements.txt new file mode 100644 index 00000000..b4f97f29 --- /dev/null +++ b/nodes/node_balancer/migrations/requirements.txt @@ -0,0 +1,18 @@ +black==23.3.0 +bugout==0.2.6 +certifi==2023.5.7 +charset-normalizer==3.1.0 +click==8.1.3 +idna==3.4 +isort==5.12.0 +mypy==1.3.0 +mypy-extensions==1.0.0 +packaging==23.1 +pathspec==0.11.1 +pkg_resources==0.0.0 +platformdirs==3.5.1 +pydantic==1.10.7 +requests==2.30.0 +tomli==2.0.1 +typing_extensions==4.5.0 +urllib3==2.0.2