From 22e74013a23ff606767a9a2b698f99084557465c Mon Sep 17 00:00:00 2001 From: James Tanner Date: Mon, 11 Sep 2023 15:25:53 -0400 Subject: [PATCH] Bind the v3 namespace to the v1 namespace and use as a provider. No-Issue Signed-off-by: James Tanner --- galaxy_ng/app/api/v1/serializers.py | 50 +++++++++----- galaxy_ng/social/__init__.py | 11 ++- .../community/test_v1_namespaces.py | 69 +++++++++++++++++++ 3 files changed, 111 insertions(+), 19 deletions(-) create mode 100644 galaxy_ng/tests/integration/community/test_v1_namespaces.py diff --git a/galaxy_ng/app/api/v1/serializers.py b/galaxy_ng/app/api/v1/serializers.py index c182a855f1..c4b0f83d71 100644 --- a/galaxy_ng/app/api/v1/serializers.py +++ b/galaxy_ng/app/api/v1/serializers.py @@ -9,12 +9,10 @@ class LegacyNamespacesSerializer(serializers.ModelSerializer): summary_fields = serializers.SerializerMethodField() - # date_joined = serializers.SerializerMethodField() - # active = serializers.SerializerMethodField() name = serializers.SerializerMethodField() - # full_name = serializers.SerializerMethodField() url = serializers.SerializerMethodField() avatar_url = serializers.SerializerMethodField() + related = serializers.SerializerMethodField() class Meta: model = LegacyNamespace @@ -25,12 +23,17 @@ class Meta: 'created', 'modified', 'name', - # 'full_name', - # 'date_joined', 'avatar_url', - # 'active' + 'related', ] + def get_related(self, obj): + return { + 'provider_namespaces': None, + 'content': None, + 'owners': f'/api/v1/namespaces/{obj.id}/owners/', + } + def get_name(self, obj): if hasattr(obj, 'name'): return obj.name @@ -40,20 +43,24 @@ def get_name(self, obj): def get_url(self, obj): return '' - # def get_full_name(self, obj): - # return '' - def get_date_joined(self, obj): return obj.created def get_summary_fields(self, obj): owners = obj.owners.all() owners = [{'id': x.id, 'username': x.username} for x in owners] - return {'owners': owners} - # TODO: What does this actually mean? - # def get_active(self, obj): - # return True + # link the v1 namespace to the v3 namespace so that users + # don't need to query the database to figure it out. + providers = [] + if obj.namespace: + providers.append({ + 'id': obj.namespace.id, + 'name': obj.namespace.name, + 'pulp_href': f"/api/pulp/api/v3/pulp_ansible/namespaces/{obj.namespace.id}/", + }) + + return {'owners': owners, 'provider_namespaces': providers} def get_avatar_url(self, obj): url = f'https://github.com/{obj.name}.png' @@ -233,6 +240,18 @@ def get_summary_fields(self, obj): versions = obj.full_metadata.get('versions', []) dependencies = obj.full_metadata.get('dependencies', []) tags = obj.full_metadata.get('tags', []) + + provider_ns = None + if obj.namespace and obj.namespace.namespace: + provider_ns = { + 'id': obj.namespace.namespace.id, + 'name': obj.namespace.namespace.name, + 'pulp_href': ( + "/api/pulp/api/v3/pulp_ansible/namespaces/" + + f"{obj.namespace.namespace.id}/" + ) + } + return { 'dependencies': dependencies, 'namespace': { @@ -240,10 +259,7 @@ def get_summary_fields(self, obj): 'name': obj.namespace.name, 'avatar_url': f'https://github.com/{obj.namespace.name}.png' }, - 'provider_namespace': { - 'id': obj.namespace.id, - 'name': obj.namespace.name - }, + 'provider_namespace': provider_ns, 'repository': { 'name': obj.name, 'original_name': obj.full_metadata.get('github_repo') diff --git a/galaxy_ng/social/__init__.py b/galaxy_ng/social/__init__.py index e8deda16e1..a0ba716fcf 100644 --- a/galaxy_ng/social/__init__.py +++ b/galaxy_ng/social/__init__.py @@ -61,10 +61,11 @@ def do_auth(self, access_token, *args, **kwargs): auth_response = self.strategy.authenticate(*args, **kwargs) # create a legacynamespace? - legacy_namespace, _ = self._ensure_legacynamespace(login) + legacy_namespace, legacy_created = self._ensure_legacynamespace(login) # define namespace, validate and create ... namespace_name = self.transform_namespace_name(login) + print(f'NAMESPACE NAME: {namespace_name}') if self.validate_namespace_name(namespace_name): # Need user for group and rbac binding @@ -74,7 +75,12 @@ def do_auth(self, access_token, *args, **kwargs): group, _ = self._ensure_group(namespace_name, user) # create a v3 namespace? - namespace, _ = self._ensure_namespace(namespace_name, user, group) + v3_namespace, v3_created = self._ensure_namespace(namespace_name, user, group) + + # bind the v3 namespace to the v1 namespace + if legacy_created and v3_created: + legacy_namespace.namespace = v3_namespace + legacy_namespace.save() return auth_response @@ -111,6 +117,7 @@ def _ensure_namespace(self, name, user, group): with transaction.atomic(): namespace, created = Namespace.objects.get_or_create(name=name) + print(f'NAMESPACE:{namespace} CREATED:{created}') owners = rbac.get_v3_namespace_owners(namespace) if created or not owners: # Binding by user breaks the UI workflow ... diff --git a/galaxy_ng/tests/integration/community/test_v1_namespaces.py b/galaxy_ng/tests/integration/community/test_v1_namespaces.py new file mode 100644 index 0000000000..e80d996b3e --- /dev/null +++ b/galaxy_ng/tests/integration/community/test_v1_namespaces.py @@ -0,0 +1,69 @@ +"""test_community.py - Tests related to the community featureset. +""" + +import json +import pytest + +from urllib.parse import urlparse + +from ..utils import ( + ansible_galaxy, + build_collection, + get_client, + SocialGithubClient, + create_user, +) +from ..utils.legacy import ( + clean_all_roles, + cleanup_social_user, + wait_for_v1_task, +) + +from jsonschema import validate as validate_json + +from ..schemas import ( + schema_objectlist, +) + + +pytestmark = pytest.mark.qa # noqa: F821 + + +@pytest.mark.deployment_community +def test_social_auth_creates_v3_namespace_new(ansible_config): + + github_user = 'jctannerTEST' + github_repo = 'role1' + cleanup_social_user(github_user, ansible_config) + + cfg = ansible_config(github_user) + with SocialGithubClient(config=cfg) as client: + + # check the v1 namespace's provider namespace + resp = client.get(f'v1/namespaces/?name={github_user}') + res = resp.json() + v1_namespace = res['results'][0] + provider_namespace = v1_namespace['summary_fields']['provider_namespaces'][0] + assert provider_namespace['name'] == github_user.lower() + + # import a role + token = client.get_hub_token() + import_pid = ansible_galaxy( + f"role import {github_user} {github_repo}", + ansible_config=cfg, + token=token, + force_token=True, + cleanup=False, + check_retcode=False + ) + assert import_pid.returncode == 0 + + # check the role's provider namespace + resp = client.get(f'v1/roles/?owner__username={github_user}&name={github_repo}') + res = resp.json() + role = res['results'][0] + provider_namespace = role['summary_fields']['provider_namespace'] + assert provider_namespace['name'] == github_user.lower() + + import epdb; epdb.st() + print('done')