Пример #1
0
def _import_project_repo(gitea_api: pygitea,
                         project: gitlab.v4.objects.Project):
    global GLOBAL_PROJECT_COUNT
    global UPDATE_PROJECT
    GLOBAL_PROJECT_COUNT += 1

    name_space = get_name_space(project.namespace['full_path'])

    is_repo_exists = repo_exists(gitea_api, name_space,
                                 name_clean(project.path))

    if UPDATE_PROJECT and is_repo_exists:
        url = "/repos/" + name_space + "/" + name_clean(project.path)
        import_response: requests.Response = gitea_api.delete(url)
        if import_response.ok:
            is_repo_exists = False
            print_info("Project " + name_clean(project.path) + " delete!")
        else:
            print_error("Project " + name_clean(project.path) +
                        " delete failed: " + import_response.text)

    if not is_repo_exists:
        clone_url = project.http_url_to_repo
        # if GITLAB_ADMIN_PASS == '' and GITLAB_ADMIN_USER == '':
        #     clone_url = project.ssh_url_to_repo
        private = project.visibility == 'private' or project.visibility == 'internal'

        # Load the owner (users and groups can both be fetched using the /users/ endpoint)
        owner = get_user_or_group(gitea_api, project)
        if owner:
            description = project.description

            if description is not None and len(description) > 255:
                description = description[:255]
                print_warning(
                    f"Description of {name_clean(project.path)} had to be truncated to 255 characters!"
                )

            import_response: requests.Response = gitea_api.post(
                "/repos/migrate",
                json={
                    # "auth_password": GITLAB_ADMIN_PASS,
                    # "auth_username": GITLAB_ADMIN_USER,
                    "auth_token": GITLAB_TOKEN,
                    "clone_addr": clone_url,
                    "description": description,
                    "mirror": False,
                    "private": private,
                    "repo_name": name_clean(project.path),
                    "uid": owner['id']
                })
            if import_response.ok:
                print_info("Project " + name_clean(project.path) +
                           " imported!")
            else:
                print_error("Project " + name_clean(project.path) +
                            " import failed: " + import_response.text)
        else:
            print_error("Failed to load project owner for project " +
                        name_clean(project.path))
Пример #2
0
def _import_project_milestones(gitea_api: pygitea, milestones: [gitlab.v4.objects.ProjectMilestone], owner: string, repo: string):
    for milestone in milestones:
        if not milestone_exists(gitea_api, owner, repo, milestone.title):                    
            due_date = None
            if milestone.due_date is not None and milestone.due_date != '':
                due_date = dateutil.parser.parse(milestone.due_date).strftime('%Y-%m-%dT%H:%M:%SZ')

            import_response: requests.Response = gitea_api.post("/repos/" + owner + "/" + repo + "/milestones", json={
                "description": milestone.description,
                "due_on": due_date,
                "title": milestone.title,
            })
            if import_response.ok:
                print_info("Milestone " + milestone.title + " imported!")
                existing_milestone = import_response.json()

                if existing_milestone:
                    # update milestone state, this cannot be done in the initial import :(
                    # TODO: gitea api ignores the closed state...
                    update_response: requests.Response = gitea_api.patch("/repos/" + owner + "/" + repo + "/milestones/" + str(existing_milestone['id']), json={
                        "description": milestone.description,
                        "due_on": due_date,
                        "title": milestone.title,
                        "state": milestone.state
                    })
                    if update_response.ok:
                        print_info("Milestone " + milestone.title + " updated!")
                    else:
                        print_error("Milestone " + milestone.title + " update failed: " + update_response.text)
            else:
                print_error("Milestone " + milestone.title + " import failed: " + import_response.text)
Пример #3
0
def _import_project_issues(gitea_api: pygitea, issues: [gitlab.v4.objects.ProjectIssue], owner: string, repo: string):
    # reload all existing milestones and labels, needed for assignment in issues
    existing_milestones = get_milestones(gitea_api, owner, repo)
    existing_labels = get_labels(gitea_api, owner, repo)

    for issue in issues:
        if not issue_exists(gitea_api, owner, repo, issue.title):
            due_date = ''
            if issue.due_date is not None:
                due_date = dateutil.parser.parse(issue.due_date).strftime('%Y-%m-%dT%H:%M:%SZ')
            
            assignee = None
            if issue.assignee is not None:
                assignee = issue.assignee['username']

            assignees = []
            for tmp_assignee in issue.assignees:
                assignees.append(tmp_assignee['username'])

            milestone = None
            if issue.milestone is not None:
                existing_milestone = next((item for item in existing_milestones if item["title"] == issue.milestone['title']), None)
                if existing_milestone:
                    milestone = existing_milestone['id']

            labels = []
            for label in issue.labels:
                existing_label = next((item for item in existing_labels if item["name"] == label), None)
                if existing_label:
                    labels.append(existing_label['id'])

            import_response: requests.Response = gitea_api.post("/repos/" + owner + "/" + repo + "/issues", json={
                "assignee": assignee,
                "assignees": assignees,
                "body": issue.description,
                "closed": issue.state == 'closed',
                "due_on": due_date,
                "labels": labels,
                "milestone": milestone,
                "title": issue.title,
            })
            if import_response.ok:
                print_info("Issue " + issue.title + " imported!")
                for note in issue.notes:
                    import_response = gitea_api.get("/repos/" + owner + "/" + repo + "/issues", json={
                        "q": issue.title,
                    })
                    if import_response.ok:
                        import_response = gitea_api.get("/repos/" + owner + "/" + repo + "/issues/" + import_response.json()["id"] + "/comments", json={
                            "body": note.body,
                        })
            else:
                print_error("Issue " + issue.title + " import failed: " + import_response.text)
Пример #4
0
def get_user_or_group(gitea_api: pygitea, project: gitlab.v4.objects.Project) -> {}:
    result = None
    response: requests.Response = gitea_api.get("/users/" + project.namespace['path'])
    if response.ok:
        result = response.json()
    else:
        response: requests.Response = gitea_api.get("/orgs/" + name_clean(project.namespace["name"]))
        if response.ok:
            result = response.json()
        else:
            print_error("Failed to load user or group " + project.namespace["name"] + "! " + response.text)

    return result
Пример #5
0
def get_user_or_group(gitea_api: pygitea, project: gitlab.v4.objects.Project) -> {}:
    result = None
    response: requests.Response = gitea_api.get("/users/" + name_clean(project.namespace['path']))
    if response.ok:
        result = response.json()

    # The api may return a 200 response, even if it's not a user but an org, let's try again!
    if result is None or result["id"] == 0:
        response: requests.Response = gitea_api.get("/orgs/" + name_clean(project.namespace["name"]))
        if response.ok:
            result = response.json()
        else:
            print_error("Failed to load user or group " + name_clean(project.namespace["name"]) + "! " + response.text)

    return result
Пример #6
0
def _import_project_repo(gitea_api: pygitea, project: gitlab.v4.objects.Project):
    if not repo_exists(gitea_api, project.namespace['name'], name_clean(project.name)):
        clone_url = project.http_url_to_repo
        if GITLAB_ADMIN_PASS == '' and GITLAB_ADMIN_USER == '':
            clone_url = project.ssh_url_to_repo
        private = project.visibility == 'private' or project.visibility == 'internal'

        # Load the owner (users and groups can both be fetched using the /users/ endpoint)
        owner = get_user_or_group(gitea_api, project)
        if owner:
            import_response: requests.Response = gitea_api.post("/repos/migrate", json={
                "auth_password": GITLAB_ADMIN_PASS,
                "auth_username": GITLAB_ADMIN_USER,
                "clone_addr": clone_url,
                "description": project.description,
                "mirror": False,
                "private": private,
                "repo_name": name_clean(project.name),
                "uid": owner['id']
            })
            if import_response.ok:
                print_info("Project " + name_clean(project.name) + " imported!")
            else:
                print_error("Project " + name_clean(project.name) + " import failed: " + import_response.text)
        else:
            print_error("Failed to load project owner for project " + name_clean(project.name))
Пример #7
0
def _import_project_repo_collaborators(gitea_api: pygitea, collaborators: [gitlab.v4.objects.ProjectMember], project: gitlab.v4.objects.Project):
    for collaborator in collaborators:
        
        if not collaborator_exists(gitea_api, project.namespace['name'], name_clean(project.name), collaborator.username):
            permission = "read"
            
            if collaborator.access_level == 10:    # guest access
                permission = "read"
            elif collaborator.access_level == 20:  # reporter access
                permission = "read"
            elif collaborator.access_level == 30:  # developer access
                permission = "write"
            elif collaborator.access_level == 40:  # maintainer access
                permission = "admin"
            elif collaborator.access_level == 50:  # owner access (only for groups)
                print_error("Groupmembers are currently not supported!")
                continue  # groups are not supported
            else:
                print_warning("Unsupported access level " + str(collaborator.access_level) + ", setting permissions to 'read'!")
            
            import_response: requests.Response = gitea_api.put("/repos/" + project.namespace['name'] +"/" + name_clean(project.name) + "/collaborators/" + collaborator.username, json={
                "permission": permission
            })
            if import_response.ok:
                print_info("Collaborator " + collaborator.username + " imported!")
            else:
                print_error("Collaborator " + collaborator.username + " import failed: " + import_response.text)
Пример #8
0
def _import_users(gitea_api: pygitea, users: [gitlab.v4.objects.User], notify: bool = False):
    for user in users:
        keys: [gitlab.v4.objects.UserKey] = user.keys.list(all=True)

        print("Importing user " + user.username + "...")
        print("Found " + str(len(keys)) + " public keys for user " + user.username)

        if not user_exists(gitea_api, user.username):
            tmp_password = '******' + ''.join(random.choices(string.ascii_uppercase + string.digits, k=10))
            tmp_email = user.username + '@noemail-git.local'  # Some gitlab instances do not publish user emails
            try:
                tmp_email = user.email
            except AttributeError:
                pass
            import_response: requests.Response = gitea_api.post("/admin/users", json={
                "email": tmp_email,
                "full_name": user.name,
                "login_name": user.username,
                "password": tmp_password,
                "send_notify": notify,
                "source_id": 0, # local user
                "username": user.username
            })
            if import_response.ok:
                print_info("User " + user.username + " imported, temporary password: "******"User " + user.username + " import failed: " + import_response.text)
        
        # import public keys
        _import_user_keys(gitea_api, keys, user)
Пример #9
0
def _import_group_members(gitea_api: pygitea,
                          members: [gitlab.v4.objects.GroupMember],
                          group: gitlab.v4.objects.Group):
    # TODO: create teams based on gitlab permissions (access_level of group member)
    existing_teams = get_teams(gitea_api, get_name_space(group.full_path))
    if existing_teams:
        first_team = existing_teams[0]
        print("Organization teams fetched, importing users to first team: " +
              first_team['name'])

        # add members to teams
        for member in members:
            if not member_exists(gitea_api, member.username, first_team['id']):
                import_response: requests.Response = gitea_api.put(
                    "/teams/" + str(first_team['id']) + "/members/" +
                    member.username)
                if import_response.ok:
                    print_info("Member " + member.username +
                               " added to group " +
                               get_name_space(group.full_path) + "!")
                else:
                    print_error("Failed to add member " + member.username +
                                " to group " +
                                get_name_space(group.full_path) + "!")
    else:
        print_error("Failed to import members to group " +
                    get_name_space(group.full_path) + ": no teams found!")
Пример #10
0
def _import_groups(gitea_api: pygitea, groups: [gitlab.v4.objects.Group]):
    idx = 0
    count = len(groups)
    print_info("Group Count:" + str(len(groups)) + "")
    for group in groups:
        members: [gitlab.v4.objects.GroupMember] = group.members.list(all=True)

        idx += 1
        print(
            str(idx) + "/" + str(count) + "\t Importing group " +
            get_name_space(group.full_path) + "...")
        print("Found " + str(len(members)) + " gitlab members for group " +
              get_name_space(group.full_path))

        if not organization_exists(gitea_api, get_name_space(group.full_path)):
            import_response: requests.Response = gitea_api.post(
                "/orgs",
                json={
                    "description": group.description,
                    "full_name": group.full_path,
                    "location": "",
                    "username": get_name_space(group.full_path),
                    "website": "",
                    "visibility": group.visibility,
                })
            if import_response.ok:
                print_info("Group " + get_name_space(group.full_path) +
                           " imported!")
            else:
                print_error("Group " + get_name_space(group.full_path) +
                            " import failed: " + import_response.text)

        # import group members
        _import_group_members(gitea_api, members, group)
Пример #11
0
def _import_groups(gitea_api: pygitea, groups: [gitlab.v4.objects.Group]):
    for group in groups:
        members: [gitlab.v4.objects.GroupMember] = group.members.list(all=True)

        print("Importing group " + name_clean(group.name) + "...")
        print("Found " + str(len(members)) + " gitlab members for group " +
              name_clean(group.name))

        if not organization_exists(gitea_api, name_clean(group.name)):
            import_response: requests.Response = gitea_api.post(
                "/orgs",
                json={
                    "description": group.description,
                    "full_name": group.full_name,
                    "location": "",
                    "username": name_clean(group.name),
                    "website": ""
                })
            if import_response.ok:
                print_info("Group " + name_clean(group.name) + " imported!")
            else:
                print_error("Group " + name_clean(group.name) +
                            " import failed: " + import_response.text)

        # import group members
        _import_group_members(gitea_api, members, group)
Пример #12
0
def collaborator_exists(gitea_api: pygitea, owner: string, repo: string, username: string) -> bool:
    collaborator_response: requests.Response = gitea_api.get("/repos/" + owner + "/" + repo + "/collaborators/" + username)
    if collaborator_response.ok:
        print_warning("Collaborator " + username + " does already exist in Gitea, skipping!")
    else:
        print("Collaborator " + username + " not found in Gitea, importing!")

    return collaborator_response.ok
Пример #13
0
def user_exists(gitea_api: pygitea, username: string) -> bool:
    user_response: requests.Response = gitea_api.get("/users/" + username)
    if user_response.ok:
        print_warning("User " + username + " does already exist in Gitea, skipping!")
    else:
        print("User " + username + " not found in Gitea, importing!")

    return user_response.ok
Пример #14
0
def repo_exists(gitea_api: pygitea, owner: string, repo: string) -> bool:
    repo_response: requests.Response = gitea_api.get("/repos/" + owner + "/" + repo)
    if repo_response.ok:
        print_warning("Project " + repo + " does already exist in Gitea, skipping!")
    else:
        print("Project " + repo + " not found in Gitea, importing!")

    return repo_response.ok
Пример #15
0
def organization_exists(gitea_api: pygitea, orgname: string) -> bool:
        group_response: requests.Response = gitea_api.get("/orgs/" + orgname)
        if group_response.ok:
            print_warning("Group " + orgname + " does already exist in Gitea, skipping!")
        else:
            print("Group " + orgname + " not found in Gitea, importing!")

        return group_response.ok
Пример #16
0
def get_milestones(gitea_api: pygitea, owner: string, repo: string) -> []:
    existing_milestones = []
    milestone_response: requests.Response = gitea_api.get("/repos/" + owner + "/" + repo + "/milestones")
    if milestone_response.ok:
        existing_milestones = milestone_response.json()
    else:
        print_error("Failed to load existing milestones for project " + repo + "! " + milestone_response.text)

    return existing_milestones
Пример #17
0
def get_teams(gitea_api: pygitea, orgname: string) -> []:
    existing_teams = []
    team_response: requests.Response = gitea_api.get("/orgs/" + orgname + "/teams")
    if team_response.ok:
        existing_teams = team_response.json()
    else:
        print_error("Failed to load existing teams for organization " + orgname + "! " + team_response.text)

    return existing_teams
Пример #18
0
def get_team_members(gitea_api: pygitea, teamid: int) -> []:
    existing_members = []
    member_response: requests.Response = gitea_api.get("/teams/" + str(teamid) + "/members")
    if member_response.ok:
        existing_members = member_response.json()
    else:
        print_error("Failed to load existing members for team " + str(teamid) + "! " + member_response.text)

    return existing_members
Пример #19
0
def get_collaborators(gitea_api: pygitea, owner: string, repo: string) -> []:
    existing_collaborators = []
    collaborator_response: requests.Response = gitea_api.get("/repos/" + owner+ "/" + repo + "/collaborators")
    if collaborator_response.ok:
        existing_collaborators = collaborator_response.json()
    else:
        print_error("Failed to load existing collaborators for project " + repo + "! " + collaborator_response.text)

    return existing_collaborators
Пример #20
0
def get_user_keys(gitea_api: pygitea, username: string) -> {}:
    result = []
    key_response: requests.Response = gitea_api.get("/users/" + username + "/keys")
    if key_response.ok:
        result = key_response.json()
    else:
        print_error("Failed to load user keys for user " + username + "! " + key_response.text)

    return result
Пример #21
0
def get_user_or_group(gitea_api: pygitea, name: string) -> {}:
    result = None
    response: requests.Response = gitea_api.get("/users/" + name)
    if response.ok:
        result = response.json()
    else:
        print_error("Failed to load user or group " + name + "! " +
                    response.text)

    return result
Пример #22
0
def get_issues(gitea_api: pygitea, owner: string, repo: string) -> []:
    existing_issues = []
    issue_response: requests.Response = gitea_api.get("/repos/" + owner + "/" + repo + "/issues", params={
        "state": "all",
        "page": -1
    })
    if issue_response.ok:
        existing_issues = issue_response.json()
    else:
        print_error("Failed to load existing issues for project " + repo + "! " + issue_response.text)

    return existing_issues
Пример #23
0
def _import_user_keys(gitea_api: pygitea, keys: [gitlab.v4.objects.UserKey], user: gitlab.v4.objects.User):
    for key in keys:
        if not user_key_exists(gitea_api, user.username, key.title):
            import_response: requests.Response = gitea_api.post("/admin/users/" + user.username + "/keys", json={
                "key": key.key,
                "read_only": True,
                "title": key.title,
            })
            if import_response.ok:
                print_info("Public key " + key.title + " imported!")
            else:
                print_error("Public key " + key.title + " import failed: " + import_response.text)
Пример #24
0
def _import_project_labels(gitea_api: pygitea, labels: [gitlab.v4.objects.ProjectLabel], owner: string, repo: string):
    for label in labels:
        if not label_exists(gitea_api, owner, repo, label.name):
            import_response: requests.Response = gitea_api.post("/repos/" + owner + "/" + repo + "/labels", json={
                "name": label.name,
                "color": label.color,
                "description": label.description # currently not supported
            })
            if import_response.ok:
                print_info("Label " + label.name + " imported!")
            else:
                print_error("Label " + label.name + " import failed: " + import_response.text)