add CLI and unit tests
continuous-integration/drone/pr Build is passing
Details
continuous-integration/drone/pr Build is passing
Details
This commit is contained in:
parent
a16ca8f5fd
commit
e863678236
|
@ -9,6 +9,7 @@ from .postgresql import postgresql
|
||||||
from .mailman import mailman
|
from .mailman import mailman
|
||||||
from .cloud import cloud
|
from .cloud import cloud
|
||||||
from .k8s import k8s
|
from .k8s import k8s
|
||||||
|
from .registry import registry
|
||||||
|
|
||||||
|
|
||||||
@click.group()
|
@click.group()
|
||||||
|
@ -25,3 +26,4 @@ cli.add_command(postgresql)
|
||||||
cli.add_command(mailman)
|
cli.add_command(mailman)
|
||||||
cli.add_command(cloud)
|
cli.add_command(cloud)
|
||||||
cli.add_command(k8s)
|
cli.add_command(k8s)
|
||||||
|
cli.add_command(registry)
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
import click
|
||||||
|
|
||||||
|
from ..utils import http_post
|
||||||
|
from .utils import handle_sync_response
|
||||||
|
|
||||||
|
|
||||||
|
@click.group(short_help='Manage your container registry account')
|
||||||
|
def registry():
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@registry.group(short_help='Manage your container registry project')
|
||||||
|
def project():
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@project.command(short_help='Create a registry project')
|
||||||
|
def create():
|
||||||
|
resp = http_post('/api/cloud/registry/projects')
|
||||||
|
handle_sync_response(resp)
|
||||||
|
click.echo('Congratulations! Your registry project was successfully created.')
|
|
@ -176,7 +176,7 @@ class CloudResourceManager:
|
||||||
}
|
}
|
||||||
|
|
||||||
now = utils.get_current_datetime()
|
now = utils.get_current_datetime()
|
||||||
if self._in_grace_period():
|
if self._in_grace_period(now):
|
||||||
return result
|
return result
|
||||||
|
|
||||||
# get a list of all cloud services each user is using
|
# get a list of all cloud services each user is using
|
||||||
|
|
|
@ -8,6 +8,7 @@ class MockHarborServer(MockHTTPServerBase):
|
||||||
prefix = '/api/v2.0'
|
prefix = '/api/v2.0'
|
||||||
routes = [
|
routes = [
|
||||||
web.get(prefix + '/users', self.users_get_handler),
|
web.get(prefix + '/users', self.users_get_handler),
|
||||||
|
web.get(prefix + '/projects', self.projects_get_handler),
|
||||||
web.post(prefix + '/projects', self.projects_post_handler),
|
web.post(prefix + '/projects', self.projects_post_handler),
|
||||||
web.post(prefix + '/projects/{project}/members', self.members_post_handler),
|
web.post(prefix + '/projects/{project}/members', self.members_post_handler),
|
||||||
web.get(prefix + '/projects/{project}/repositories', self.repositories_get_handler),
|
web.get(prefix + '/projects/{project}/repositories', self.repositories_get_handler),
|
||||||
|
@ -15,7 +16,7 @@ class MockHarborServer(MockHTTPServerBase):
|
||||||
web.delete(prefix + '/projects/{project}', self.projects_delete_handler),
|
web.delete(prefix + '/projects/{project}', self.projects_delete_handler),
|
||||||
# for debugging purposes
|
# for debugging purposes
|
||||||
web.post('/reset', self.reset_handler),
|
web.post('/reset', self.reset_handler),
|
||||||
web.post('/users/{username}', self.users_post_handler),
|
web.delete('/users/{username}', self.users_delete_handler),
|
||||||
]
|
]
|
||||||
super().__init__(port, routes)
|
super().__init__(port, routes)
|
||||||
|
|
||||||
|
@ -26,6 +27,12 @@ class MockHarborServer(MockHTTPServerBase):
|
||||||
'exec1': [],
|
'exec1': [],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async def projects_get_handler(self, request):
|
||||||
|
return web.json_response([
|
||||||
|
{'name': name, 'project_id': i + 1}
|
||||||
|
for i, name in enumerate(self.projects.keys())
|
||||||
|
])
|
||||||
|
|
||||||
async def projects_delete_handler(self, request):
|
async def projects_delete_handler(self, request):
|
||||||
project_name = request.match_info['project']
|
project_name = request.match_info['project']
|
||||||
if project_name not in self.projects:
|
if project_name not in self.projects:
|
||||||
|
@ -78,14 +85,17 @@ class MockHarborServer(MockHTTPServerBase):
|
||||||
self.projects[project_name] = ['repo1', 'repo2']
|
self.projects[project_name] = ['repo1', 'repo2']
|
||||||
return web.Response(text='', status=201)
|
return web.Response(text='', status=201)
|
||||||
|
|
||||||
async def users_post_handler(self, request):
|
async def users_delete_handler(self, request):
|
||||||
username = request.match_info['username']
|
username = request.match_info['username']
|
||||||
self.users.remove(username)
|
self.users.remove(username)
|
||||||
return web.Response(text='OK\n', status=201)
|
return web.Response(text='OK\n', status=201)
|
||||||
|
|
||||||
async def reset_handler(self, request):
|
def reset(self):
|
||||||
self.users.clear()
|
self.users.clear()
|
||||||
self.projects.clear()
|
self.projects.clear()
|
||||||
|
|
||||||
|
async def reset_handler(self, request):
|
||||||
|
self.reset()
|
||||||
return web.Response(text='OK\n')
|
return web.Response(text='OK\n')
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -76,3 +76,15 @@ def test_k8s_account_activate(cli_setup, new_user):
|
||||||
assert result.exit_code == 0
|
assert result.exit_code == 0
|
||||||
assert result.output == expected
|
assert result.output == expected
|
||||||
assert os.path.isfile(os.path.join(new_user.home_directory, '.kube', 'config'))
|
assert os.path.isfile(os.path.join(new_user.home_directory, '.kube', 'config'))
|
||||||
|
|
||||||
|
|
||||||
|
def test_registry_project_create(cli_setup, mock_harbor_server, new_user):
|
||||||
|
uid = new_user.uid
|
||||||
|
runner = CliRunner()
|
||||||
|
mock_harbor_server.reset()
|
||||||
|
mock_harbor_server.users.append(uid)
|
||||||
|
with gssapi_token_ctx(uid):
|
||||||
|
result = runner.invoke(cli, ['registry', 'project', 'create'])
|
||||||
|
expected = 'Congratulations! Your registry project was successfully created.\n'
|
||||||
|
assert result.exit_code == 0
|
||||||
|
assert result.output == expected
|
||||||
|
|
|
@ -35,8 +35,8 @@ def test_create_account(client, mock_cloud_server, new_user, ldap_conn):
|
||||||
|
|
||||||
|
|
||||||
def test_purge_accounts(
|
def test_purge_accounts(
|
||||||
client, mock_cloud_server, cloud_mgr, mock_mail_server, new_user,
|
client, mock_cloud_server, cloud_mgr, mock_mail_server,
|
||||||
ldap_conn,
|
mock_harbor_server, new_user, ldap_conn,
|
||||||
):
|
):
|
||||||
uid = new_user.uid
|
uid = new_user.uid
|
||||||
mock_cloud_server.clear()
|
mock_cloud_server.clear()
|
||||||
|
@ -167,12 +167,14 @@ def test_cloud_vhosts(cfg, client, new_user, ldap_conn):
|
||||||
assert status == 403
|
assert status == 403
|
||||||
|
|
||||||
|
|
||||||
def test_cloud_vhosts_purged_account(
|
def test_cloud_resources_purged_account(
|
||||||
cfg, client, mock_cloud_server, mock_mail_server, new_user, ldap_conn,
|
cfg, client, mock_cloud_server, mock_mail_server, mock_harbor_server,
|
||||||
|
new_user, ldap_conn,
|
||||||
):
|
):
|
||||||
uid = new_user.uid
|
uid = new_user.uid
|
||||||
members_domain = cfg.get('cloud vhosts_members_domain')
|
members_domain = cfg.get('cloud vhosts_members_domain')
|
||||||
mock_cloud_server.clear()
|
mock_cloud_server.clear()
|
||||||
|
mock_harbor_server.reset()
|
||||||
current_term = Term.current()
|
current_term = Term.current()
|
||||||
beginning_of_term = current_term.to_datetime()
|
beginning_of_term = current_term.to_datetime()
|
||||||
domain1 = uid + '.' + members_domain
|
domain1 = uid + '.' + members_domain
|
||||||
|
@ -182,6 +184,9 @@ def test_cloud_vhosts_purged_account(
|
||||||
client.put(
|
client.put(
|
||||||
f'/api/cloud/vhosts/{domain1}', json={'ip_address': ip1},
|
f'/api/cloud/vhosts/{domain1}', json={'ip_address': ip1},
|
||||||
principal=uid)
|
principal=uid)
|
||||||
|
mock_harbor_server.users.append(uid)
|
||||||
|
client.post('/api/cloud/registry/projects', principal=uid)
|
||||||
|
assert len(mock_harbor_server.projects) == 1
|
||||||
|
|
||||||
expire_member(new_user, ldap_conn)
|
expire_member(new_user, ldap_conn)
|
||||||
with patch.object(ceo_common_utils, 'get_current_datetime') as now_mock:
|
with patch.object(ceo_common_utils, 'get_current_datetime') as now_mock:
|
||||||
|
@ -198,6 +203,9 @@ def test_cloud_vhosts_purged_account(
|
||||||
assert status == 200
|
assert status == 200
|
||||||
assert data == {'vhosts': []}
|
assert data == {'vhosts': []}
|
||||||
|
|
||||||
|
# registry project should have been deleted
|
||||||
|
assert len(mock_harbor_server.projects) == 0
|
||||||
|
|
||||||
mock_mail_server.messages.clear()
|
mock_mail_server.messages.clear()
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
from ceo_common.errors import UserNotFoundError
|
||||||
|
|
||||||
|
|
||||||
|
def test_registry(mock_harbor_server, registry_srv):
|
||||||
|
mock_harbor_server.reset()
|
||||||
|
username = 'test1'
|
||||||
|
|
||||||
|
with pytest.raises(UserNotFoundError):
|
||||||
|
registry_srv.create_project_for_user(username)
|
||||||
|
|
||||||
|
mock_harbor_server.users.append(username)
|
||||||
|
registry_srv.create_project_for_user(username)
|
||||||
|
assert username in mock_harbor_server.projects
|
||||||
|
# trying to create a project with the same name should have no effect
|
||||||
|
registry_srv.create_project_for_user(username)
|
||||||
|
|
||||||
|
assert registry_srv.get_accounts() == [username]
|
||||||
|
|
||||||
|
registry_srv.delete_project_for_user(username)
|
||||||
|
assert username not in mock_harbor_server.projects
|
||||||
|
# trying to delete a nonexistent project should have no effect
|
||||||
|
registry_srv.delete_project_for_user(username)
|
|
@ -26,16 +26,18 @@ from .utils import ( # noqa: F401
|
||||||
from ceo_common.interfaces import IConfig, IKerberosService, ILDAPService, \
|
from ceo_common.interfaces import IConfig, IKerberosService, ILDAPService, \
|
||||||
IFileService, IMailmanService, IHTTPClient, IUWLDAPService, IMailService, \
|
IFileService, IMailmanService, IHTTPClient, IUWLDAPService, IMailService, \
|
||||||
IDatabaseService, ICloudStackService, IKubernetesService, IVHostManager, \
|
IDatabaseService, ICloudStackService, IKubernetesService, IVHostManager, \
|
||||||
ICloudResourceManager
|
ICloudResourceManager, IContainerRegistryService
|
||||||
from ceo_common.model import Config, HTTPClient, Term
|
from ceo_common.model import Config, HTTPClient, Term
|
||||||
from ceod.api import create_app
|
from ceod.api import create_app
|
||||||
from ceod.db import MySQLService, PostgreSQLService
|
from ceod.db import MySQLService, PostgreSQLService
|
||||||
from ceod.model import KerberosService, LDAPService, FileService, User, \
|
from ceod.model import KerberosService, LDAPService, FileService, User, \
|
||||||
MailmanService, Group, UWLDAPService, UWLDAPRecord, MailService, \
|
MailmanService, Group, UWLDAPService, UWLDAPRecord, MailService, \
|
||||||
CloudStackService, KubernetesService, VHostManager, CloudResourceManager
|
CloudStackService, KubernetesService, VHostManager, CloudResourceManager, \
|
||||||
|
ContainerRegistryService
|
||||||
from .MockSMTPServer import MockSMTPServer
|
from .MockSMTPServer import MockSMTPServer
|
||||||
from .MockMailmanServer import MockMailmanServer
|
from .MockMailmanServer import MockMailmanServer
|
||||||
from .MockCloudStackServer import MockCloudStackServer
|
from .MockCloudStackServer import MockCloudStackServer
|
||||||
|
from .MockHarborServer import MockHarborServer
|
||||||
from .conftest_ceod_api import client # noqa: F401
|
from .conftest_ceod_api import client # noqa: F401
|
||||||
from .conftest_ceo import cli_setup # noqa: F401
|
from .conftest_ceo import cli_setup # noqa: F401
|
||||||
|
|
||||||
|
@ -256,6 +258,21 @@ def mock_cloud_server():
|
||||||
mock_server.stop()
|
mock_server.stop()
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(scope='session')
|
||||||
|
def mock_harbor_server():
|
||||||
|
mock_server = MockHarborServer()
|
||||||
|
mock_server.start()
|
||||||
|
yield mock_server
|
||||||
|
mock_server.stop()
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(scope='session')
|
||||||
|
def registry_srv(cfg):
|
||||||
|
reg_srv = ContainerRegistryService()
|
||||||
|
component.getGlobalSiteManager().registerUtility(reg_srv, IContainerRegistryService)
|
||||||
|
return reg_srv
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope='session')
|
@pytest.fixture(scope='session')
|
||||||
def mysql_srv(cfg):
|
def mysql_srv(cfg):
|
||||||
mysql_srv = MySQLService()
|
mysql_srv = MySQLService()
|
||||||
|
@ -322,6 +339,7 @@ def app(
|
||||||
cloudstack_srv,
|
cloudstack_srv,
|
||||||
vhost_mgr,
|
vhost_mgr,
|
||||||
k8s_srv,
|
k8s_srv,
|
||||||
|
registry_srv,
|
||||||
cloud_mgr,
|
cloud_mgr,
|
||||||
):
|
):
|
||||||
app = create_app({'TESTING': True})
|
app = create_app({'TESTING': True})
|
||||||
|
|
Loading…
Reference in New Issue