
Sadly, as readable as the use of the uri module to do the interactions with gitea is, more reent ansible changed how subprocesses are forked and this makes iterating over all the projects in projects.yaml take an incredibly long amount of time. Instead of doing it in yaml, make a python module that takes the list one time and does looping and requests calls. This should make it be possible to run the actual gitea creation playbook in integration tests. Change-Id: Ifff3291c1092e6df09ae339c9e7dddb5ee692685
178 lines
6.0 KiB
Python
Executable File
178 lines
6.0 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
#
|
|
# Copyright 2019 Red Hat, Inc
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
# not use this file except in compliance with the License. You may obtain
|
|
# a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
# License for the specific language governing permissions and limitations
|
|
# under the License.
|
|
|
|
import time
|
|
import requests
|
|
import urllib.parse
|
|
|
|
from ansible.module_utils.basic import AnsibleModule
|
|
|
|
SB_REPO = 'https://storyboard.openstack.org/#!/project/{org}/{repo}'
|
|
SB_FORMAT = 'https://storyboard.openstack.org/#!/story/{{index}}'
|
|
LP_REPO = 'https://bugs.launchpad.net/{repo}'
|
|
LP_FORMAT = 'https://bugs.launchpad.net/{repo}/+bug/{{index}}'
|
|
|
|
|
|
|
|
class Gitea(object):
|
|
|
|
def __init__(self, url, password, always_update, projects):
|
|
self.url = url
|
|
self.password = password
|
|
self.always_update = always_update
|
|
self.projects = projects
|
|
self.orgs = { f['project'].split('/')[0] for f in self.projects }
|
|
|
|
def request(self, method, endpoint, *args, **kwargs):
|
|
resp = requests.request(
|
|
method,
|
|
urllib.parse.urljoin(self.url, endpoint),
|
|
auth=('root', self.password),
|
|
verify=False,
|
|
*args, **kwargs)
|
|
resp.raise_for_status()
|
|
return resp
|
|
|
|
def get(self, endpoint, *args, **kwargs):
|
|
return self.request('GET', endpoint, *args, **kwargs)
|
|
|
|
def post(self, endpoint, *args, **kwargs):
|
|
return self.request('POST', endpoint, *args, **kwargs)
|
|
|
|
def put(self, endpoint, *args, **kwargs):
|
|
return self.request('PUT', endpoint, *args, **kwargs)
|
|
|
|
def get_gitea_orgs(self):
|
|
orgs = self.get("/api/v1/user/orgs").json()
|
|
return [f['username'] for f in orgs]
|
|
|
|
def make_gitea_org(self, org):
|
|
self.post(
|
|
'/api/v1/admin/users/root/orgs',
|
|
json=dict(username=org))
|
|
|
|
def ensure_gitea_teams(self, org):
|
|
team_list = self.get('/api/v1/orgs/{org}/teams'.format(org=org)).json()
|
|
owner_id = [f['id'] for f in team_list if f['name'] == 'Owners'][0]
|
|
|
|
org_owners = self.get(
|
|
'/api/v1/teams/{owner_id}/members'.format(owner_id=owner_id))
|
|
if 'gerrit' not in [f['username'] for f in org_owners.json()]:
|
|
self.put('/api/v1/teams/{owner_id}/members/gerrit'.format(
|
|
owner_id=owner_id))
|
|
|
|
def get_org_repo_list(self, org):
|
|
return self.get('/api/v1/orgs/{org}/repos'.format(org=org)).json()
|
|
|
|
def get_csrf_token(self):
|
|
resp = self.get('/')
|
|
return urllib.parse.unquote(resp.cookies.get('_csrf'))
|
|
|
|
def make_gitea_project(self, project, csrf_token):
|
|
org, repo = project['project'].split('/', 1)
|
|
resp = self.post(
|
|
'/api/v1/org/{org}/repos'.format(org=org),
|
|
json=dict(
|
|
auto_init=True,
|
|
description=project.get('description', '')[:255],
|
|
name=repo,
|
|
private=False,
|
|
readme='Default'))
|
|
if project.get('use-storyboard'):
|
|
external_tracker_url = SB_REPO.format(org=org, repo=repo)
|
|
tracker_url_format = SB_FORMAT
|
|
elif project.get('groups'):
|
|
external_tracker_url = LP_REPO.format(repo=project['groups'][0])
|
|
tracker_url_format = LP_FORMAT.format(repo=project['groups'][0])
|
|
else:
|
|
external_tracker_url = LP_REPO.format(repo=repo)
|
|
tracker_url_format = LP_FORMAT.format(repo=repo)
|
|
|
|
self.post(
|
|
'/{org}/{repo}/settings'.format(org=org, repo=repo),
|
|
data=dict(
|
|
_csrf=csrf_token,
|
|
action='advanced',
|
|
# enable_pulls is not provided, which disables it
|
|
# enable_wiki is not provided, which disables it
|
|
enable_external_wiki=False,
|
|
external_wiki_url='',
|
|
# enable_issues is on so that issue links work
|
|
enable_issues='on',
|
|
enable_external_tracker=True,
|
|
external_tracker_url=external_tracker_url,
|
|
tracker_url_format=tracker_url_format,
|
|
tracker_issue_style='numeric',
|
|
))
|
|
|
|
for count in range(0, 5):
|
|
try:
|
|
return self.post(
|
|
'/{org}/{repo}/settings/branches'.format(
|
|
org=org, repo=repo),
|
|
data=dict(
|
|
_csrf=csrf_token,
|
|
action='default_branch',
|
|
branch='master',
|
|
))
|
|
except requests.exceptions.HTTPError as e:
|
|
time.sleep(3)
|
|
raise Exception("Could not update branch settings")
|
|
|
|
def run(self):
|
|
gitea_orgs = self.get_gitea_orgs()
|
|
gitea_repos = []
|
|
for org in self.orgs:
|
|
if org not in gitea_orgs:
|
|
self.make_gitea_org(org)
|
|
self.ensure_gitea_teams(org)
|
|
gitea_repos.extend(self.get_org_repo_list(org))
|
|
csrf_token = self.get_csrf_token()
|
|
|
|
for project in self.projects:
|
|
if project['project'] not in gitea_repos or self.always_update:
|
|
self.make_gitea_project(project, csrf_token)
|
|
|
|
|
|
def ansible_main():
|
|
module = AnsibleModule(
|
|
argument_spec=dict(
|
|
url=dict(required=True),
|
|
password=dict(required=True),
|
|
projects=dict(required=True, type='list'),
|
|
always_update=dict(type='bool', default=True),
|
|
)
|
|
)
|
|
|
|
p = module.params
|
|
|
|
gitea = Gitea(
|
|
url=p.get('url'),
|
|
password=p.get('password'),
|
|
always_update=p.get('always_update'),
|
|
projects=p.get('projects'),
|
|
)
|
|
try:
|
|
gitea.run()
|
|
except Exception as e:
|
|
module.fail_json(msg=str(e), changed=True)
|
|
|
|
module.exit_json(changed=True)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
ansible_main()
|