mirror of
https://lab.enough.community/fedeproxy/server
synced 2024-12-27 19:22:48 +01:00
implement gitlab project get/create/delete
This commit is contained in:
parent
b0bf115f64
commit
60ba328469
@ -4,6 +4,8 @@ import os
|
||||
import requests
|
||||
import time
|
||||
|
||||
from fedeproxy.common.retry import retry
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@ -38,8 +40,8 @@ class GitLab(object):
|
||||
def set_token(self, token):
|
||||
self.s.headers['Authorization'] = f'Bearer {token}'
|
||||
|
||||
def get_namespace(self, user):
|
||||
r = self.s.get(self.s.api + '/namespaces?search=' + user)
|
||||
def get_namespace_id(self, name):
|
||||
r = self.s.get(self.s.api + '/namespaces?search=' + name)
|
||||
r.raise_for_status()
|
||||
return r.json()[0]['id']
|
||||
|
||||
@ -57,23 +59,47 @@ class GitLab(object):
|
||||
user = r.json()
|
||||
return self.is_member_of_group(group, user['username'])
|
||||
|
||||
def recreate_project(self, user, project):
|
||||
namespace_id = self.get_namespace(user)
|
||||
r = self.s.get(self.s.api + '/projects/' + user + '%2F' + project)
|
||||
if r.status_code == requests.codes.ok:
|
||||
r = self.s.delete(self.s.api + '/projects/' + user + '%2F' + project)
|
||||
r.raise_for_status()
|
||||
for _ in range(10):
|
||||
r = self.s.post(self.s.api + '/projects', data={
|
||||
"name": project,
|
||||
"namespace_id": int(namespace_id),
|
||||
"visibility": "public",
|
||||
})
|
||||
time.sleep(5)
|
||||
if r.status_code == 201:
|
||||
break
|
||||
print(str(r.text))
|
||||
def project_delete(self, namespace, project):
|
||||
info = self.project_get(namespace, project)
|
||||
if info is None:
|
||||
return False
|
||||
r = self.s.delete(f'{self.s.api}/projects/{info["id"]}')
|
||||
r.raise_for_status()
|
||||
while self.project_get(namespace, project) is not None:
|
||||
time.sleep(1)
|
||||
return True
|
||||
|
||||
def project_get(self, namespace, project):
|
||||
r = self.s.get(f'{self.s.api}/projects/{namespace}%2F{project}')
|
||||
if r.status_code == requests.codes.ok:
|
||||
return r.json()
|
||||
else:
|
||||
return None
|
||||
|
||||
class DeletionInProgress(Exception):
|
||||
pass
|
||||
|
||||
@retry(DeletionInProgress, tries=5)
|
||||
def _project_create(self, namespace, project):
|
||||
namespace_id = self.get_namespace_id(namespace)
|
||||
data = {
|
||||
"name": project,
|
||||
"namespace_id": int(namespace_id),
|
||||
"visibility": "public",
|
||||
}
|
||||
r = self.s.post(f'{self.s.api}/projects', data=data)
|
||||
if r.status_code == 201:
|
||||
return r.json()
|
||||
if r.status_code == 400 and 'still being deleted' in r.text:
|
||||
raise GitLab.DeletionInProgress()
|
||||
r.raise_for_status()
|
||||
|
||||
def project_create(self, namespace, project):
|
||||
info = self.project_get(namespace, project)
|
||||
if info is None:
|
||||
return self._project_create(namespace, project)
|
||||
else:
|
||||
return info
|
||||
|
||||
def create_api_application(self, domain):
|
||||
callbacks = [
|
||||
|
29
fedeproxy/common/retry.py
Normal file
29
fedeproxy/common/retry.py
Normal file
@ -0,0 +1,29 @@
|
||||
import logging
|
||||
import time
|
||||
from functools import wraps
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class RetryException(Exception):
|
||||
pass
|
||||
|
||||
|
||||
def retry(exceptions, tries=2, delay=1):
|
||||
def deco_retry(f):
|
||||
@wraps(f)
|
||||
def f_retry(*args, **kwargs):
|
||||
mtries, mdelay = tries + 1, delay
|
||||
while mtries > 0:
|
||||
try:
|
||||
return f(*args, **kwargs)
|
||||
except exceptions as e:
|
||||
logger.info('%s: %s, Retrying in %s seconds...', f.__qualname__, e, mdelay)
|
||||
if mtries == tries + 1:
|
||||
logger.debug("", exc_info=True)
|
||||
time.sleep(mdelay)
|
||||
mtries -= 1
|
||||
mdelay *= 2
|
||||
raise RetryException("Number of retries exceeded for function " + f.__name__)
|
||||
return f_retry
|
||||
return deco_retry
|
2
tests/conftest.py
Normal file
2
tests/conftest.py
Normal file
@ -0,0 +1,2 @@
|
||||
def pytest_configure(config):
|
||||
config.addinivalue_line("markers", "gitlab: mark tests which require live GitLab instances")
|
@ -5,8 +5,11 @@ from fedeproxy.common.gitlab import GitLab
|
||||
|
||||
|
||||
@pytest.mark.gitlab
|
||||
def test_recreate_project(tmpdir):
|
||||
def test_create_project(tmpdir):
|
||||
ip = os.environ.get('FEDEPROXY_IP', '0.0.0.0')
|
||||
gitlab = GitLab(f'http://{ip}:8181')
|
||||
gitlab.login('root', 'Wrobyak4')
|
||||
gitlab.recreate_project('root', 'testproject')
|
||||
gitlab.project_delete('root', 'testproject')
|
||||
assert gitlab.project_get('root', 'testproject') is None
|
||||
p = gitlab.project_create('root', 'testproject')
|
||||
assert p['id'] == gitlab.project_create('root', 'testproject')['id']
|
||||
|
36
tests/fedeproxy/common/test_retry.py
Normal file
36
tests/fedeproxy/common/test_retry.py
Normal file
@ -0,0 +1,36 @@
|
||||
import pytest
|
||||
from enough.common import retry
|
||||
|
||||
|
||||
def test_that_retry_works_on_simple_function():
|
||||
|
||||
@retry.retry(Exception)
|
||||
def f():
|
||||
return True
|
||||
|
||||
assert f()
|
||||
|
||||
|
||||
def test_that_retry_fails():
|
||||
|
||||
@retry.retry(AssertionError)
|
||||
def f():
|
||||
assert 0
|
||||
|
||||
with pytest.raises(retry.RetryException):
|
||||
f()
|
||||
|
||||
|
||||
def test_that_retry_works_on_complex_function():
|
||||
class C():
|
||||
fail = 2
|
||||
|
||||
@retry.retry(Exception, tries=3)
|
||||
def f(self):
|
||||
self.fail -= 1
|
||||
assert self.fail == 0
|
||||
return True
|
||||
|
||||
c = C()
|
||||
assert c.f()
|
||||
assert c.fail == 0
|
Loading…
Reference in New Issue
Block a user