Draft: Update graphql types to include project import level
What does this MR do and why?
Describe in detail what your merge request does and why.
This change updates GraphQL types to include the project_import_level
namespace setting.
It is the first of several changes required to make project_import_level
configurable through the UI or api.
See: #358750 (closed)
Testing
Enter the following query in http://gdk.test:3000/-/graphql-explorer:
{
group(fullPath: "gitlab-org") {
projectImportLevel
}
}
Result:
{
"data": {
"group": {
"projectImportLevel": "owner"
}
}
}
Query Plan
UPDATE: This association has been removed in favour of something that uses an existing method. So a Query Plan is likely no longer necessary.
There is a new association on the User
model to find all groups a user can import projects to:
has_many :import_groups,
-> {
joins(:namespace_settings)
.where("namespace_settings.project_import_level<>0 AND members.access_level>=namespace_settings.project_import_level")
},
through: :group_members, source: :group
This creates a query that looks like (using a sample User
):
SELECT "namespaces"."id", "namespaces"."name", "namespaces"."path", "namespaces"."owner_id", "namespaces"."created_at", "namespaces"."updated_at", "namespaces"."type", "namespaces"."description", "namespaces"."avatar", "namespaces"."membership_lock", "namespaces"."share_with_group_lock", "namespaces"."visibility_level", "namespaces"."request_access_enabled", "namespaces"."ldap_sync_status", "namespaces"."ldap_sync_error", "namespaces"."ldap_sync_last_update_at", "namespaces"."ldap_sync_last_successful_update_at", "namespaces"."ldap_sync_last_sync_at", "namespaces"."description_html", "namespaces"."lfs_enabled", "namespaces"."parent_id", "namespaces"."shared_runners_minutes_limit", "namespaces"."repository_size_limit", "namespaces"."require_two_factor_authentication", "namespaces"."two_factor_grace_period", "namespaces"."cached_markdown_version", "namespaces"."project_creation_level", "namespaces"."runners_token", "namespaces"."file_template_project_id", "namespaces"."saml_discovery_token", "namespaces"."runners_token_encrypted", "namespaces"."custom_project_templates_group_id", "namespaces"."auto_devops_enabled", "namespaces"."extra_shared_runners_minutes_limit", "namespaces"."last_ci_minutes_notification_at", "namespaces"."last_ci_minutes_usage_notification_level", "namespaces"."subgroup_creation_level", "namespaces"."emails_disabled", "namespaces"."max_pages_size", "namespaces"."max_artifacts_size", "namespaces"."mentions_disabled", "namespaces"."default_branch_protection", "namespaces"."unlock_membership_to_ldap", "namespaces"."max_personal_access_token_lifetime", "namespaces"."push_rule_id", "namespaces"."shared_runners_enabled", "namespaces"."allow_descendants_override_disabled_shared_runners", "namespaces"."traversal_ids"
FROM "namespaces"
INNER JOIN "members" ON "namespaces"."id" = "members"."source_id"
INNER JOIN "namespace_settings" ON "namespace_settings"."namespace_id" = "namespaces"."id"
WHERE "members"."type" = 'GroupMember'
AND "members"."source_type" = 'Namespace'
AND "namespaces"."type" = 'Group'
AND "members"."user_id" = 1
AND "members"."requested_at" IS NULL
AND (access_level >= 10)
AND (namespace_settings.project_import_level<>0)
AND (members.access_level>=namespace_settings.project_import_level)
With a plan:
https://gitlab.slack.com/files/UL8QB0T4J/F042EGKCXMW/plan-text.txt
Nested Loop (cost=1.56..13.39 rows=1 width=365) (actual time=0.096..1.302 rows=23 loops=1)
Buffers: shared hit=594
I/O Timings: read=0.000 write=0.000
-> Nested Loop (cost=1.13..12.82 rows=1 width=373) (actual time=0.076..0.756 rows=59 loops=1)
Buffers: shared hit=358
I/O Timings: read=0.000 write=0.000
-> Index Scan using index_members_on_user_id_source_id_source_type on public.members (cost=0.56..9.24 rows=1 width=8) (actual time=0.057..0.218 rows=59 loops=1)
Index Cond: ((members.user_id = 1) AND ((members.source_type)::text = 'Namespace'::text))
Filter: ((members.requested_at IS NULL) AND (members.access_level >= 10) AND ((members.type)::text = 'GroupMember'::text))
Rows Removed by Filter: 0
Buffers: shared hit=63
I/O Timings: read=0.000 write=0.000
-> Index Scan using namespaces_pkey on public.namespaces (cost=0.56..3.58 rows=1 width=365) (actual time=0.008..0.008 rows=1 loops=59)
Index Cond: (namespaces.id = members.source_id)
Filter: ((namespaces.type)::text = 'Group'::text)
Rows Removed by Filter: 0
Buffers: shared hit=295
I/O Timings: read=0.000 write=0.000
-> Index Scan using namespace_settings_pkey on public.namespace_settings (cost=0.43..0.55 rows=1 width=6) (actual time=0.008..0.009 rows=1 loops=59)
Index Cond: (namespace_settings.namespace_id = namespaces.id)
Filter: (namespace_settings.project_import_level <> 0)
Rows Removed by Filter: 0
Buffers: shared hit=236
I/O Timings: read=0.000 write=0.000
Recommendations:
Summary:
Time: 2.948 ms
planning: 1.515 ms-
execution: 1.433 msI/O read: 0.000 msI/O write: 0.000 ms
Shared buffers:
- ~~hits: 594 (~4.60 MiB) from the buffer pool~~
reads: 0 from the OS file cache, including disk I/Odirtied: 0writes: 0
Details and Visulizations: https://console.postgres.ai/gitlab/gitlab-production-tunnel-pg12/sessions/12014/commands/42620
MR acceptance checklist
This checklist encourages us to confirm any changes have been analyzed to reduce risks in quality, performance, reliability, security, and maintainability.
-
I have evaluated the MR acceptance checklist for this MR.
Related to #358750 (closed)