From 4b5e834bc26011ff32a5dbebc4eb359287c18c4b Mon Sep 17 00:00:00 2001 From: Mike Date: Tue, 17 Jan 2023 22:14:46 -0800 Subject: [PATCH] Started work --- .gitignore | 2 ++ Pipfile | 12 +++++++ Pipfile.lock | 60 +++++++++++++++++++++++++++++++++ domain/Migrator.py | 67 +++++++++++++++++++++++++++++++++++++ main.py | 83 ++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 224 insertions(+) create mode 100644 .gitignore create mode 100644 Pipfile create mode 100644 Pipfile.lock create mode 100644 domain/Migrator.py create mode 100644 main.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..df30947 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ + +.idea/ diff --git a/Pipfile b/Pipfile new file mode 100644 index 0000000..ac34ddc --- /dev/null +++ b/Pipfile @@ -0,0 +1,12 @@ +[[source]] +url = "https://pypi.org/simple" +verify_ssl = true +name = "pypi" + +[packages] +giteapy = "*" + +[dev-packages] + +[requires] +python_version = "3.10" diff --git a/Pipfile.lock b/Pipfile.lock new file mode 100644 index 0000000..5fe0d49 --- /dev/null +++ b/Pipfile.lock @@ -0,0 +1,60 @@ +{ + "_meta": { + "hash": { + "sha256": "824c02127733d501ae21f3e5ccc7ee72fc4b2fe92bbca23c77ebd204d294b0fc" + }, + "pipfile-spec": 6, + "requires": { + "python_version": "3.10" + }, + "sources": [ + { + "name": "pypi", + "url": "https://pypi.org/simple", + "verify_ssl": true + } + ] + }, + "default": { + "certifi": { + "hashes": [ + "sha256:35824b4c3a97115964b408844d64aa14db1cc518f6562e8d7261699d1350a9e3", + "sha256:4ad3232f5e926d6718ec31cfc1fcadfde020920e278684144551c91769c7bc18" + ], + "markers": "python_version >= '3.6'", + "version": "==2022.12.7" + }, + "giteapy": { + "hashes": [ + "sha256:2078c802a4626bf311e911c969c34b7d19fbe9175e2910e1965b24ff69221470" + ], + "index": "pypi", + "version": "==1.0.8" + }, + "python-dateutil": { + "hashes": [ + "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86", + "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'", + "version": "==2.8.2" + }, + "six": { + "hashes": [ + "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", + "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'", + "version": "==1.16.0" + }, + "urllib3": { + "hashes": [ + "sha256:076907bf8fd355cde77728471316625a4d2f7e713c125f51953bb5b3eecf4f72", + "sha256:75edcdc2f7d85b137124a6c3c9fc3933cdeaa12ecb9a6a959f22797a0feca7e1" + ], + "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5'", + "version": "==1.26.14" + } + }, + "develop": {} +} diff --git a/domain/Migrator.py b/domain/Migrator.py new file mode 100644 index 0000000..b4f3ba7 --- /dev/null +++ b/domain/Migrator.py @@ -0,0 +1,67 @@ + + +import giteapy +import logging +import sys + + +class Migrator: + + __DEFAULT_API_PATH = "/api/v1" + + def __init__( + self, + source_host, source_port, source_token, + destination_host, destination_port, destination_token, + ): + + # noinspection PyTypeChecker + self.__logger: logging.Logger = None + self._init_logger() + + self.__source_host = source_host + self.__source_port = source_port + self.__source_token = source_token + + self.__destination_host = destination_host + self.__destination_port = destination_port + self.__destination_token = destination_token + + def _init_logger(self): + + logger = logging.Logger(name=f"{type(self).__name__}", level=logging.INFO) + + stdout_handler = logging.StreamHandler(stream=sys.stdout) + logger.addHandler(stdout_handler) + + self.__logger = logger + + def _get_org_apis(self): + + conf_source = giteapy.Configuration() + conf_source.api_key['access_token'] = self.__source_token + conf_source.host = self._make_api_base(host=self.__source_host, port=self.__source_port) + api_source = giteapy.OrganizationApi(giteapy.ApiClient(conf_source)) + + conf_destination = giteapy.Configuration() + conf_destination.api_key['access_token'] = self.__destination_token + conf_destination.host = self._make_api_base(host=self.__destination_host, port=self.__destination_port) + api_destination = giteapy.OrganizationApi(giteapy.ApiClient(conf_destination)) + + return api_source, api_destination + + def _make_api_base(self, host, port): + + base = f"https://{host}" + if port is not None: + base += f":{port}" + base += self.__DEFAULT_API_PATH + + return base + + def migrate_entire_org(self, source_org, destination_org): + + api_source, api_destination = self._get_org_apis() + + source_repos = api_source.org_list_repos(source_org) + self.__logger.info(f"Found {len(source_repos)} repos on source.") diff --git a/main.py b/main.py new file mode 100644 index 0000000..b4cfeca --- /dev/null +++ b/main.py @@ -0,0 +1,83 @@ + + +from domain.Migrator import Migrator + + +import argparse + + +def main(): + + parser = argparse.ArgumentParser( + prog="Mike's Gitea Repo Migrator - Move repositories from one Gitea instance to another" + ) + + parser.add_argument( + "--source-hostname", "--source-host", + dest="source_hostname", + required=True, + help="Hostname of the source server" + ) + parser.add_argument( + "--source-port", + dest="source_port", + required=False, + default=None, + help="Port of the source server" + ) + parser.add_argument( + "--source-token", + dest="source_token", + required=True, + help="Provide an API token for the source Gitea instance's user" + ) + parser.add_argument( + "--source-org", + dest="source_org", + required=True, + help="Name of the source organization" + ) + + parser.add_argument( + "--destination-hostname", "--dest-hostname", "--destination-host", "--dest-host", + dest="destination_hostname", + required=True, + help="Hostname of the destination server" + ) + parser.add_argument( + "--destination-port", "--dest-port", + dest="destination_port", + required=False, + default=None, + help="Port of the destination server" + ) + parser.add_argument( + "--destination-token", "--dest-token", + dest="destination_token", + required=True, + help="Provide an API token for the destination Gitea instance's user" + ) + parser.add_argument( + "--destination-org", "--dest-org", + dest="destination_org", + required=True, + help="Name of the destination organization" + ) + + args = parser.parse_args() + mig = Migrator( + source_host=args.source_hostname, + source_port=args.source_port, + source_token=args.source_token, + destination_host=args.destination_hostname, + destination_port=args.destination_port, + destination_token=args.destination_token + ) + mig.migrate_entire_org( + source_org=args.source_org, + destination_org=args.destination_org + ) + + +if __name__ == "__main__": + main()