Skip to content

Resolve "Group-level compliance dashboard MVC"

Gosia Ksionek requested to merge 36524-group-level-compliance-dashboard-mvc into master

What does this MR do?

Introduces group-level compliance dashboard.

Screenshots

SQL produced by this view:

SELECT
    projects.id,
    events.target_id AS merge_request_id 
FROM
    (
        SELECT
            "projects".* 
        FROM
            "projects" 
        WHERE
            "projects"."namespace_id" IN 
            (
                WITH RECURSIVE "base_and_descendants" AS 
                (
(
                    SELECT
                        "namespaces".* 
                    FROM
                        "namespaces" 
                    WHERE
                        "namespaces"."type" IN 
                        (
                            'Group'
                        )
                        AND "namespaces"."id" = 9970) 
                    UNION
(
                    SELECT
                        "namespaces".* 
                    FROM
                        "namespaces", "base_and_descendants" 
                    WHERE
                        "namespaces"."type" IN 
                        (
                            'Group'
                        )
                        AND "namespaces"."parent_id" = "base_and_descendants"."id")
                )
                SELECT
                    "namespaces"."id" 
                FROM
                    "base_and_descendants" AS "namespaces"
            )
    )
    projects 
    JOIN
        LATERAL (
        SELECT
            "events"."created_at", "events"."target_id" 
        FROM
            "events" 
        WHERE
            (
                projects.id = project_id
            )
            AND "events"."action" = 7 
        ORDER BY
            "events"."id" DESC LIMIT 1) events 
            ON TRUE 
        ORDER BY
            events.created_at DESC

sql plan:

Sort  (cost=80975.80..80981.05 rows=2100 width=16) (actual time=133.360..133.390 rows=294 loops=1)
   Sort Key: events.created_at DESC
   Sort Method: quicksort  Memory: 38kB
   Buffers: shared hit=43264
   ->  Nested Loop  (cost=1646.49..80859.92 rows=2100 width=16) (actual time=2.999..132.954 rows=294 loops=1)
         Buffers: shared hit=43261
         ->  Nested Loop  (cost=1645.92..5999.60 rows=2100 width=4) (actual time=2.914..6.729 rows=674 loops=1)
               Buffers: shared hit=1191
               ->  HashAggregate  (cost=1645.48..1646.79 rows=131 width=4) (actual time=2.859..2.911 rows=73 loops=1)
                     Group Key: namespaces.id
                     Buffers: shared hit=296
                     ->  CTE Scan on base_and_descendants namespaces  (cost=1641.23..1643.85 rows=131 width=4) (actual time=0.095..2.769 rows=73 loops=1)
                           Buffers: shared hit=296
                           CTE base_and_descendants
                             ->  Recursive Union  (cost=0.43..1641.23 rows=131 width=323) (actual time=0.090..2.496 rows=73 loops=1)
                                   Buffers: shared hit=296
                                   ->  Index Scan using namespaces_pkey on public.namespaces namespaces_1  (cost=0.43..4.45 rows=1 width=323) (actual time=0.064..0.065 rows=1 loops=1)
                                         Index Cond: (namespaces_1.id = 9970)
                                         Filter: ((namespaces_1.type)::text = 'Group'::text)
                                         Rows Removed by Filter: 0
                                         Buffers: shared hit=4
                                   ->  Nested Loop  (cost=0.43..163.42 rows=13 width=323) (actual time=0.064..0.386 rows=14 loops=5)
                                         Buffers: shared hit=292
                                         ->  WorkTable Scan on base_and_descendants  (cost=0.00..0.20 rows=10 width=4) (actual time=0.001..0.006 rows=15 loops=5)
                                         ->  Index Scan using index_namespaces_on_parent_id_and_id on public.namespaces namespaces_2  (cost=0.43..16.31 rows=1 width=323) (actual time=0.015..0.024 rows=1 loops=73)
                                               Index Cond: (namespaces_2.parent_id = base_and_descendants.id)
                                               Filter: ((namespaces_2.type)::text = 'Group'::text)
                                               Rows Removed by Filter: 0
                                               Buffers: shared hit=292
               ->  Index Scan using index_projects_on_namespace_id on public.projects  (cost=0.43..33.07 rows=16 width=8) (actual time=0.013..0.048 rows=9 loops=73)
                     Index Cond: (projects.namespace_id = namespaces.id)
                     Buffers: shared hit=895
         ->  Limit  (cost=0.57..35.63 rows=1 width=16) (actual time=0.186..0.186 rows=0 loops=674)
               Buffers: shared hit=42070
               ->  Index Scan using index_events_on_project_id_and_id on public.events  (cost=0.57..1858.50 rows=53 width=16) (actual time=0.185..0.185 rows=0 loops=674)
                     Index Cond: (projects.id = events.project_id)
                     Filter: (events.action = 7)
                     Rows Removed by Filter: 57
                     Buffers: shared hit=42070

sql stats:

Time: 154.059 ms
  - planning: 19.713 ms
  - execution: 134.346 ms
    - I/O read: 0.000 ms
    - I/O write: 0.000 ms

Shared buffers:
  - hits: 43264 (~338.00 MiB) from the buffer pool
  - reads: 0 from the OS file cache, including disk I/O
  - dirtied: 0
  - writes: 0

Does this MR meet the acceptance criteria?

Conformity

Availability and Testing

Security

If this MR contains changes to processing or storing of credentials or tokens, authorization and authentication methods and other items described in the security review guidelines:

  • Label as security and @ mention @gitlab-com/gl-security/appsec
  • The MR includes necessary changes to maintain consistency between UI, API, email, or other methods
  • Security reports checked/validated by a reviewer from the AppSec team

Closes #36524 (closed)

Edited by Gosia Ksionek

Merge request reports