Skip to content

Commit 2791177

Browse files
committed
Add organization and team models
* Add new `Oranization` and `Team` models, that implement respective abstract models from DAB. * Add related database migrations and data migration, that creates a new default model. * Implement custom manager for the `Organization` model that retrieves the default organization. * Team model has a one-to-one relationship with the standard Group model. * When new Team record is created, a related Group model is automatically created as well. No-Issue
1 parent 67eab54 commit 2791177

File tree

6 files changed

+341
-45
lines changed

6 files changed

+341
-45
lines changed

galaxy_ng/app/api/resource_api.py

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
ServiceAPIConfig,
44
SharedResource,
55
)
6-
from ansible_base.resource_registry.shared_types import UserType, TeamType
6+
from ansible_base.resource_registry.shared_types import UserType, TeamType, OrganizationType
77
from galaxy_ng.app import models
88

99

@@ -14,18 +14,17 @@ class APIConfig(ServiceAPIConfig):
1414
RESOURCE_LIST = (
1515
ResourceConfig(
1616
models.auth.User,
17-
shared_resource=SharedResource(
18-
serializer=UserType,
19-
is_provider=False
20-
),
21-
name_field="username"
17+
shared_resource=SharedResource(serializer=UserType, is_provider=False),
18+
name_field="username",
2219
),
2320
ResourceConfig(
24-
models.auth.Group,
25-
shared_resource=SharedResource(
26-
serializer=TeamType,
27-
is_provider=True
28-
),
29-
name_field="name"
21+
models.Team,
22+
shared_resource=SharedResource(serializer=TeamType, is_provider=True),
23+
name_field="name",
3024
),
25+
ResourceConfig(
26+
models.Organization,
27+
shared_resource=SharedResource(serializer=OrganizationType, is_provider=False),
28+
name_field="name",
29+
)
3130
)
Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
# Generated by Django 4.2.10 on 2024-02-15 17:33
2+
3+
import django.db.models.deletion
4+
from django.conf import settings
5+
from django.db import migrations, models
6+
7+
8+
class Migration(migrations.Migration):
9+
dependencies = [
10+
("galaxy", "0048_update_collection_remote_rhcertified_url"),
11+
]
12+
13+
operations = [
14+
migrations.CreateModel(
15+
name="Organization",
16+
fields=[
17+
(
18+
"id",
19+
models.AutoField(
20+
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
21+
),
22+
),
23+
(
24+
"created_on",
25+
models.DateTimeField(
26+
default=None,
27+
editable=False,
28+
help_text="The date/time this resource was created",
29+
),
30+
),
31+
(
32+
"modified_on",
33+
models.DateTimeField(
34+
default=None,
35+
editable=False,
36+
help_text="The date/time this resource was created",
37+
),
38+
),
39+
(
40+
"name",
41+
models.CharField(
42+
help_text="The name of this resource", max_length=512, unique=True
43+
),
44+
),
45+
(
46+
"description",
47+
models.TextField(
48+
blank=True, default="", help_text="The organization description."
49+
),
50+
),
51+
(
52+
"created_by",
53+
models.ForeignKey(
54+
default=None,
55+
editable=False,
56+
help_text="The user who created this resource",
57+
null=True,
58+
on_delete=django.db.models.deletion.DO_NOTHING,
59+
related_name="%(app_label)s_%(class)s_created+",
60+
to=settings.AUTH_USER_MODEL,
61+
),
62+
),
63+
(
64+
"modified_by",
65+
models.ForeignKey(
66+
default=None,
67+
editable=False,
68+
help_text="The user who last modified this resource",
69+
null=True,
70+
on_delete=django.db.models.deletion.DO_NOTHING,
71+
related_name="%(app_label)s_%(class)s_modified+",
72+
to=settings.AUTH_USER_MODEL,
73+
),
74+
),
75+
(
76+
"users",
77+
models.ManyToManyField(
78+
help_text="The list of users in this organization.",
79+
related_name="organizations",
80+
to=settings.AUTH_USER_MODEL,
81+
),
82+
),
83+
],
84+
options={
85+
"abstract": False,
86+
},
87+
),
88+
migrations.CreateModel(
89+
name="Team",
90+
fields=[
91+
(
92+
"id",
93+
models.AutoField(
94+
auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
95+
),
96+
),
97+
(
98+
"created_on",
99+
models.DateTimeField(
100+
default=None,
101+
editable=False,
102+
help_text="The date/time this resource was created",
103+
),
104+
),
105+
(
106+
"modified_on",
107+
models.DateTimeField(
108+
default=None,
109+
editable=False,
110+
help_text="The date/time this resource was created",
111+
),
112+
),
113+
("name", models.CharField(help_text="The name of this resource", max_length=512)),
114+
(
115+
"description",
116+
models.TextField(blank=True, default="", help_text="The team description."),
117+
),
118+
(
119+
"created_by",
120+
models.ForeignKey(
121+
default=None,
122+
editable=False,
123+
help_text="The user who created this resource",
124+
null=True,
125+
on_delete=django.db.models.deletion.DO_NOTHING,
126+
related_name="%(app_label)s_%(class)s_created+",
127+
to=settings.AUTH_USER_MODEL,
128+
),
129+
),
130+
(
131+
"modified_by",
132+
models.ForeignKey(
133+
default=None,
134+
editable=False,
135+
help_text="The user who last modified this resource",
136+
null=True,
137+
on_delete=django.db.models.deletion.DO_NOTHING,
138+
related_name="%(app_label)s_%(class)s_modified+",
139+
to=settings.AUTH_USER_MODEL,
140+
),
141+
),
142+
(
143+
"organization",
144+
models.ForeignKey(
145+
help_text="The organization of this team.",
146+
on_delete=django.db.models.deletion.CASCADE,
147+
related_name="teams",
148+
to="galaxy.organization",
149+
),
150+
),
151+
(
152+
"users",
153+
models.ManyToManyField(
154+
help_text="The list of users in this team.",
155+
related_name="teams",
156+
to=settings.AUTH_USER_MODEL,
157+
),
158+
),
159+
(
160+
"group",
161+
models.OneToOneField(
162+
help_text="Related group record.",
163+
on_delete=django.db.models.deletion.CASCADE,
164+
related_name="+",
165+
to="galaxy.group",
166+
),
167+
168+
)
169+
],
170+
options={
171+
"ordering": ("organization__name", "name"),
172+
"abstract": False,
173+
"unique_together": {("organization", "name")},
174+
},
175+
),
176+
]
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
from django.conf import settings
2+
from django.db import migrations
3+
from django.utils import timezone
4+
5+
6+
def create_default_organization(apps, schema_editor):
7+
db_alias = schema_editor.connection.alias
8+
Organization = apps.get_model("galaxy", "Organization")
9+
10+
now = timezone.now()
11+
org = Organization.objects.using(db_alias).create(
12+
name=settings.DEFAULT_ORGANIZATION_NAME,
13+
description="A default organization.",
14+
created_on=now,
15+
modified_on=now,
16+
)
17+
18+
schema_editor.execute("""
19+
INSERT INTO galaxy_team (name, description, created_on, modified_on, group_id, organization_id)
20+
SELECT grp.name, '', now(), now(), grp.id, %s
21+
FROM auth_group AS grp
22+
""", (org.id,))
23+
24+
schema_editor.execute("""
25+
UPDATE auth_group SET name = %s || '::' || name
26+
""", (settings.DEFAULT_ORGANIZATION_NAME,))
27+
28+
29+
def delete_default_organization(apps, schema_editor):
30+
db_alias = schema_editor.connection.alias
31+
Team = apps.get_model("galaxy", "Team")
32+
Organization = apps.get_model("galaxy", "Organization")
33+
34+
schema_editor.execute("""
35+
UPDATE auth_group SET name = regexp_replace(name, '^.+?::', '')
36+
""")
37+
38+
Team.objects.using(db_alias).delete()
39+
40+
Organization.objects.using(db_alias).filter(
41+
name=settings.DEFAULT_ORGANIZATION_NAME
42+
).delete()
43+
44+
45+
class Migration(migrations.Migration):
46+
dependencies = [
47+
("galaxy", "0049_organization"),
48+
]
49+
50+
operations = [
51+
migrations.RunPython(
52+
code=create_default_organization,
53+
reverse_code=delete_default_organization,
54+
)
55+
]

galaxy_ng/app/models/__init__.py

Lines changed: 30 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,40 @@
1-
from .auth import (
2-
Group,
3-
User,
4-
)
5-
from .collectionimport import (
6-
CollectionImport,
7-
)
1+
from .aiindex import AIIndexDenyList
2+
from .auth import Group, User
3+
from .collectionimport import CollectionImport
84
from .config import Setting
9-
from .namespace import (
10-
Namespace,
11-
NamespaceLink,
12-
)
13-
14-
from .synclist import (
15-
SyncList,
16-
)
17-
185
from .container import (
196
ContainerDistribution,
207
ContainerDistroReadme,
218
ContainerNamespace,
229
ContainerRegistryRemote,
23-
ContainerRegistryRepos
24-
10+
ContainerRegistryRepos,
2511
)
26-
27-
from .aiindex import AIIndexDenyList
12+
from .namespace import Namespace, NamespaceLink
13+
from .organization import Organization, Team
14+
from .synclist import SyncList
2815

2916
__all__ = (
30-
'Group',
31-
'User',
32-
'CollectionImport',
33-
'Namespace',
34-
'NamespaceLink',
35-
'Setting',
36-
'SyncList',
37-
'ContainerDistribution',
38-
'ContainerDistroReadme',
39-
'ContainerNamespace',
40-
'ContainerRegistryRemote',
41-
'ContainerRegistryRepos',
42-
'AIIndexDenyList',
17+
# aiindex
18+
"AIIndexDenyList",
19+
# auth
20+
"Group",
21+
"User",
22+
# collectionimport
23+
"CollectionImport",
24+
# config
25+
"Setting",
26+
# container
27+
"ContainerDistribution",
28+
"ContainerDistroReadme",
29+
"ContainerNamespace",
30+
"ContainerRegistryRemote",
31+
"ContainerRegistryRepos",
32+
# namespace
33+
"Namespace",
34+
"NamespaceLink",
35+
# organization
36+
"Organization",
37+
"Team",
38+
# synclist
39+
"SyncList",
4340
)

0 commit comments

Comments
 (0)