Add ability to update DastSiteProfile with GraphQL
What does this MR do?
adds a new graphql mutation for updating dast_site_profiles
via:
- new finder (
DastSiteProfileFinder
) - new service (
DastSiteProfiles::UpdateService
) - new mutation (
Mutations::DastSiteProfiles::Update
) - new specs at the request, mutation, finder and service level
i have not added a changelog entry because the feature is behind a feature flag.
Related Issue(s)
Database Changes
- currently we see few records in those tables, when we have 15M projects for gitlab.com, it means a fraction of those projects will have multiple
dast_site_profiles
- we may open an issue to think an index for
"dast_site_profiles"."project_id" AND "dast_site_profiles"."id"
in upcoming releases
Details
Queries
# no filtering
[7] pry(main)> finder = DastSiteProfilesFinder.new
=> #<DastSiteProfilesFinder:0x00007f8a1e875de8 @params={}>
[8] pry(main)> finder.execute
DastSiteProfile Load (0.4ms) SELECT "dast_site_profiles".* FROM "dast_site_profiles"
DastSite Load (0.2ms) SELECT "dast_sites".* FROM "dast_sites" WHERE "dast_sites"."id" IN ($1, $2, $3) [["id", 1], ["id", 2], ["id", 3]]
Seq Scan on public.dast_site_profiles (cost=0.00..4.07 rows=7 width=72) (actual time=0.983..0.984 rows=5 loops=1)
Buffers: shared read=1 dirtied=1
I/O Timings: read=0.791
Seq Scan on public.dast_sites (cost=0.00..4.05 rows=3 width=64) (actual time=1.062..1.063 rows=3 loops=1)
Filter: (dast_sites.id = ANY ('{1,2,3}'::bigint[]))
Rows Removed by Filter: 1
Buffers: shared read=1
I/O Timings: read=1.045
# filtering by :id
[11] pry(main)> finder = DastSiteProfilesFinder.new(id: 1)
=> #<DastSiteProfilesFinder:0x00007f8a1ead5480 @params={:id=>1}>
[12] pry(main)> finder.execute
DastSiteProfile Load (0.4ms) SELECT "dast_site_profiles".* FROM "dast_site_profiles" WHERE "dast_site_profiles"."id" = $1 [["id", 1]]
DastSite Load (0.2ms) SELECT "dast_sites".* FROM "dast_sites" WHERE "dast_sites"."id" = $1 [["id", 1]]
Index Scan using dast_site_profiles_pkey on public.dast_site_profiles (cost=0.13..3.15 rows=1 width=72) (actual time=1.133..1.133 rows=0 loops=1)
Index Cond: (dast_site_profiles.id = 1)
Buffers: shared hit=5 read=1 dirtied=1
I/O Timings: read=1.024
Index Scan using dast_sites_pkey on public.dast_sites (cost=0.13..3.15 rows=1 width=64) (actual time=1.252..1.254 rows=1 loops=1)
Index Cond: (dast_sites.id = 1)
Buffers: shared hit=1 read=1
I/O Timings: read=1.183
# filtering by :id and :project_id
[15] pry(main)> finder = DastSiteProfilesFinder.new(id: 1, project_id: 20)
=> #<DastSiteProfilesFinder:0x00007f8a1ecc4868 @params={:id=>1, :project_id=>20}>
[16] pry(main)> finder.execute
DastSiteProfile Load (0.2ms) SELECT "dast_site_profiles".* FROM "dast_site_profiles" WHERE "dast_site_profiles"."id" = $1 AND "dast_site_profiles"."project_id" = $2 [["id", 1], ["project_id", 20]]
DastSite Load (0.2ms) SELECT "dast_sites".* FROM "dast_sites" WHERE "dast_sites"."id" = $1 [["id", 1]]
Index Scan using index_dast_site_profiles_on_project_id_and_name on public.dast_site_profiles (cost=0.13..3.15 rows=1 width=72) (actual time=1.896..1.896 rows=0 loops=1)
Index Cond: (dast_site_profiles.project_id = 278964)
Filter: (dast_site_profiles.id = 1)
Rows Removed by Filter: 0
Buffers: shared read=1
I/O Timings: read=1.855
Index Scan using dast_sites_pkey on public.dast_sites (cost=0.13..3.15 rows=1 width=64) (actual time=1.252..1.254 rows=1 loops=1)
Index Cond: (dast_sites.id = 1)
Buffers: shared hit=1 read=1
I/O Timings: read=1.183
# filtering by :project_id
[17] pry(main)> finder = DastSiteProfilesFinder.new(project_id: 20)
=> #<DastSiteProfilesFinder:0x00007f8a1edc7378 @params={:project_id=>20}>
[18] pry(main)> finder.execute
DastSiteProfile Load (0.8ms) SELECT "dast_site_profiles".* FROM "dast_site_profiles" WHERE "dast_site_profiles"."project_id" = $1 [["project_id", 20]]
DastSite Load (0.2ms) SELECT "dast_sites".* FROM "dast_sites" WHERE "dast_sites"."id" IN ($1, $2) [["id", 2], ["id", 1]]
Index Scan using index_dast_site_profiles_on_project_id_and_name on public.dast_site_profiles (cost=0.13..3.15 rows=1 width=72) (actual time=1.896..1.896 rows=0 loops=1)
Index Cond: (dast_site_profiles.project_id = 278964)
Filter: (dast_site_profiles.id = 1)
Rows Removed by Filter: 0
Buffers: shared read=1
I/O Timings: read=1.855
Seq Scan on public.dast_sites (cost=0.00..4.05 rows=2 width=64) (actual time=0.011..0.012 rows=2 loops=1)
Filter: (dast_sites.id = ANY ('{1,2}'::bigint[]))
Rows Removed by Filter: 2
Buffers: shared hit=1
Does this MR meet the acceptance criteria?
Conformity
- [-] Changelog entry behind feature flag
- [-] Documentation (if required)
-
Code review guidelines -
Merge request performance guidelines -
Style guides -
Database guides -
Separation of EE specific content
Availability and Testing
-
Review and add/update tests for this feature/bug. Consider all test levels. See the Test Planning Process. -
Tested in all supported browsers -
Informed Infrastructure department of a default or new setting change, if applicable per definition of done
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
Edited by Mayra Cabrera