Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bind v1 and v3 namespaces if created and use v3 for provider #1881

Merged
merged 6 commits into from
Sep 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 34 additions & 17 deletions galaxy_ng/app/api/v1/serializers.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
from rest_framework import serializers

from pulpcore.plugin.util import get_url

from galaxy_ng.app.models.auth import User
from galaxy_ng.app.api.v1.models import LegacyNamespace
from galaxy_ng.app.api.v1.models import LegacyRole
Expand All @@ -9,12 +11,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
Expand All @@ -25,12 +25,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
Expand All @@ -40,20 +45,25 @@ 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:
pulp_href = get_url(obj.namespace)
providers.append({
'id': obj.namespace.id,
'name': obj.namespace.name,
'pulp_href': pulp_href,
})

return {'owners': owners, 'provider_namespaces': providers}

def get_avatar_url(self, obj):
url = f'https://github.com/{obj.name}.png'
Expand Down Expand Up @@ -233,17 +243,24 @@ 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:
pulp_href = get_url(obj.namespace.namespace)
provider_ns = {
'id': obj.namespace.namespace.id,
'name': obj.namespace.namespace.name,
'pulp_href': pulp_href
}

return {
'dependencies': dependencies,
'namespace': {
'id': obj.namespace.id,
'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')
Expand Down
11 changes: 9 additions & 2 deletions galaxy_ng/social/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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

Expand Down Expand Up @@ -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 ...
Expand Down
8 changes: 7 additions & 1 deletion galaxy_ng/tests/integration/cli/test_community.py
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ def test_import_role_fields(ansible_config):
summary_fields = result["summary_fields"]
assert summary_fields["dependencies"] == list()
assert summary_fields["namespace"]["name"] == "jctannerTEST"
assert summary_fields["provider_namespace"]["name"] == "jctannerTEST"
assert summary_fields["provider_namespace"]["name"] == "jctannertest"
assert summary_fields["repository"]["name"] == "role1"
assert summary_fields["tags"] == list()

Expand All @@ -237,12 +237,17 @@ def test_delete_role_as_not_owner(ansible_config):
role_name = "role1"
qs = f'v1/roles/?github_user={github_user}&name={role_name}'

cleanup_social_user(deleter, ansible_config)
cleanup_social_user(github_user, ansible_config)
cleanup_social_user(github_user.lower(), ansible_config)

cfg = ansible_config(github_user)
client = SocialGithubClient(config=cfg)
client.login()
token = client.get_hub_token()
assert token is not None

'''
# cleanup the role if it exists
resp = client.get(qs)
ds = resp.json()
Expand All @@ -252,6 +257,7 @@ def test_delete_role_as_not_owner(ansible_config):
role_url = f'v1/roles/{role_id}/'
resp = client.delete(role_url)
assert resp.status_code == 200
'''

# Run the import as the owner
cfg = ansible_config(github_user)
Expand Down
51 changes: 51 additions & 0 deletions galaxy_ng/tests/integration/community/test_v1_namespaces.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
"""test_community.py - Tests related to the community featureset.
"""

import pytest

from ..utils import (
ansible_galaxy,
SocialGithubClient,
)
from ..utils.legacy import (
cleanup_social_user,
)

pytestmark = pytest.mark.qa # noqa: F821


@pytest.mark.deployment_community
def test_social_auth_creates_v3_namespace_as_v1_provider(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()
Loading