Skip to content

Add DastSchedules to PlanLimits

Aditya Tiwari requested to merge 335816-add-limit-counter-on-schedule into master

What does this MR do?

Issue: #335816 (closed)

Database

Migrate

╰─>$ rails db:migrate
== 20210819105519 AddDastSchedulesToPlanLimits: migrating =====================
-- add_column(:plan_limits, :dast_profile_schedules, :integer, {:default=>0, :null=>false})
   -> 0.0066s
== 20210819105519 AddDastSchedulesToPlanLimits: migrated (0.0066s) ============

== 20210819105904 InsertDastProfileSchedulesPlanLimits: migrating =============
-- quote_column_name("dast_profile_schedules")
   -> 0.0000s
-- quote("default")
   -> 0.0000s
-- quote(0)
   -> 0.0000s
-- execute("INSERT INTO plan_limits (plan_id, \"dast_profile_schedules\")\nSELECT id, '0' FROM plans WHERE name = 'default' LIMIT 1\nON CONFLICT (plan_id) DO UPDATE SET \"dast_profile_schedules\" = EXCLUDED.\"dast_profile_schedules\";\n")
   -> 0.0036s
-- quote_column_name("dast_profile_schedules")
   -> 0.0000s
-- quote("free")
   -> 0.0000s
-- quote(20)
   -> 0.0000s
-- execute("INSERT INTO plan_limits (plan_id, \"dast_profile_schedules\")\nSELECT id, '1' FROM plans WHERE name = 'free' LIMIT 1\nON CONFLICT (plan_id) DO UPDATE SET \"dast_profile_schedules\" = EXCLUDED.\"dast_profile_schedules\";\n")
   -> 0.0008s
-- quote_column_name("dast_profile_schedules")
   -> 0.0000s
-- quote("bronze")
   -> 0.0000s
-- quote(20)
   -> 0.0000s
-- execute("INSERT INTO plan_limits (plan_id, \"dast_profile_schedules\")\nSELECT id, '20' FROM plans WHERE name = 'bronze' LIMIT 1\nON CONFLICT (plan_id) DO UPDATE SET \"dast_profile_schedules\" = EXCLUDED.\"dast_profile_schedules\";\n")
   -> 0.0008s
-- quote_column_name("dast_profile_schedules")
   -> 0.0000s
-- quote("silver")
   -> 0.0000s
-- quote(20)
   -> 0.0000s
-- execute("INSERT INTO plan_limits (plan_id, \"dast_profile_schedules\")\nSELECT id, '20' FROM plans WHERE name = 'silver' LIMIT 1\nON CONFLICT (plan_id) DO UPDATE SET \"dast_profile_schedules\" = EXCLUDED.\"dast_profile_schedules\";\n")
   -> 0.0007s
-- quote_column_name("dast_profile_schedules")
   -> 0.0000s
-- quote("premium")
   -> 0.0000s
-- quote(20)
   -> 0.0000s
-- execute("INSERT INTO plan_limits (plan_id, \"dast_profile_schedules\")\nSELECT id, '20' FROM plans WHERE name = 'premium' LIMIT 1\nON CONFLICT (plan_id) DO UPDATE SET \"dast_profile_schedules\" = EXCLUDED.\"dast_profile_schedules\";\n")
   -> 0.0007s
-- quote_column_name("dast_profile_schedules")
   -> 0.0000s
-- quote("premium_trial")
   -> 0.0000s
-- quote(20)
   -> 0.0000s
-- execute("INSERT INTO plan_limits (plan_id, \"dast_profile_schedules\")\nSELECT id, '20' FROM plans WHERE name = 'premium_trial' LIMIT 1\nON CONFLICT (plan_id) DO UPDATE SET \"dast_profile_schedules\" = EXCLUDED.\"dast_profile_schedules\";\n")
   -> 0.0008s
-- quote_column_name("dast_profile_schedules")
   -> 0.0000s
-- quote("gold")
   -> 0.0000s
-- quote(20)
   -> 0.0000s
-- execute("INSERT INTO plan_limits (plan_id, \"dast_profile_schedules\")\nSELECT id, '20' FROM plans WHERE name = 'gold' LIMIT 1\nON CONFLICT (plan_id) DO UPDATE SET \"dast_profile_schedules\" = EXCLUDED.\"dast_profile_schedules\";\n")
   -> 0.0009s
-- quote_column_name("dast_profile_schedules")
   -> 0.0000s
-- quote("ultimate")
   -> 0.0000s
-- quote(20)
   -> 0.0000s
-- execute("INSERT INTO plan_limits (plan_id, \"dast_profile_schedules\")\nSELECT id, '20' FROM plans WHERE name = 'ultimate' LIMIT 1\nON CONFLICT (plan_id) DO UPDATE SET \"dast_profile_schedules\" = EXCLUDED.\"dast_profile_schedules\";\n")
   -> 0.0010s
-- quote_column_name("dast_profile_schedules")
   -> 0.0000s
-- quote("ultimate_trial")
   -> 0.0000s
-- quote(20)
   -> 0.0000s
-- execute("INSERT INTO plan_limits (plan_id, \"dast_profile_schedules\")\nSELECT id, '20' FROM plans WHERE name = 'ultimate_trial' LIMIT 1\nON CONFLICT (plan_id) DO UPDATE SET \"dast_profile_schedules\" = EXCLUDED.\"dast_profile_schedules\";\n")
   -> 0.0009s
== 20210819105904 InsertDastProfileSchedulesPlanLimits: migrated (0.0112s) ====

Rollback

╰─>$ rails db:rollback STEP=2
== 20210819105904 InsertDastProfileSchedulesPlanLimits: reverting =============
-- quote_column_name("dast_profile_schedules")
   -> 0.0000s
-- quote("default")
   -> 0.0000s
-- quote(0)
   -> 0.0000s
-- execute("INSERT INTO plan_limits (plan_id, \"dast_profile_schedules\")\nSELECT id, '0' FROM plans WHERE name = 'default' LIMIT 1\nON CONFLICT (plan_id) DO UPDATE SET \"dast_profile_schedules\" = EXCLUDED.\"dast_profile_schedules\";\n")
   -> 0.0026s
-- quote_column_name("dast_profile_schedules")
   -> 0.0000s
-- quote("free")
   -> 0.0000s
-- quote(0)
   -> 0.0000s
-- execute("INSERT INTO plan_limits (plan_id, \"dast_profile_schedules\")\nSELECT id, '0' FROM plans WHERE name = 'free' LIMIT 1\nON CONFLICT (plan_id) DO UPDATE SET \"dast_profile_schedules\" = EXCLUDED.\"dast_profile_schedules\";\n")
   -> 0.0008s
-- quote_column_name("dast_profile_schedules")
   -> 0.0000s
-- quote("bronze")
   -> 0.0000s
-- quote(0)
   -> 0.0000s
-- execute("INSERT INTO plan_limits (plan_id, \"dast_profile_schedules\")\nSELECT id, '0' FROM plans WHERE name = 'bronze' LIMIT 1\nON CONFLICT (plan_id) DO UPDATE SET \"dast_profile_schedules\" = EXCLUDED.\"dast_profile_schedules\";\n")
   -> 0.0009s
-- quote_column_name("dast_profile_schedules")
   -> 0.0000s
-- quote("silver")
   -> 0.0000s
-- quote(0)
   -> 0.0000s
-- execute("INSERT INTO plan_limits (plan_id, \"dast_profile_schedules\")\nSELECT id, '0' FROM plans WHERE name = 'silver' LIMIT 1\nON CONFLICT (plan_id) DO UPDATE SET \"dast_profile_schedules\" = EXCLUDED.\"dast_profile_schedules\";\n")
   -> 0.0008s
-- quote_column_name("dast_profile_schedules")
   -> 0.0000s
-- quote("premium")
   -> 0.0000s
-- quote(0)
   -> 0.0000s
-- execute("INSERT INTO plan_limits (plan_id, \"dast_profile_schedules\")\nSELECT id, '0' FROM plans WHERE name = 'premium' LIMIT 1\nON CONFLICT (plan_id) DO UPDATE SET \"dast_profile_schedules\" = EXCLUDED.\"dast_profile_schedules\";\n")
   -> 0.0008s
-- quote_column_name("dast_profile_schedules")
   -> 0.0000s
-- quote("premium_trial")
   -> 0.0000s
-- quote(0)
   -> 0.0000s
-- execute("INSERT INTO plan_limits (plan_id, \"dast_profile_schedules\")\nSELECT id, '0' FROM plans WHERE name = 'premium_trial' LIMIT 1\nON CONFLICT (plan_id) DO UPDATE SET \"dast_profile_schedules\" = EXCLUDED.\"dast_profile_schedules\";\n")
   -> 0.0007s
-- quote_column_name("dast_profile_schedules")
   -> 0.0000s
-- quote("gold")
   -> 0.0000s
-- quote(0)
   -> 0.0000s
-- execute("INSERT INTO plan_limits (plan_id, \"dast_profile_schedules\")\nSELECT id, '0' FROM plans WHERE name = 'gold' LIMIT 1\nON CONFLICT (plan_id) DO UPDATE SET \"dast_profile_schedules\" = EXCLUDED.\"dast_profile_schedules\";\n")
   -> 0.0007s
-- quote_column_name("dast_profile_schedules")
   -> 0.0000s
-- quote("ultimate")
   -> 0.0000s
-- quote(0)
   -> 0.0000s
-- execute("INSERT INTO plan_limits (plan_id, \"dast_profile_schedules\")\nSELECT id, '0' FROM plans WHERE name = 'ultimate' LIMIT 1\nON CONFLICT (plan_id) DO UPDATE SET \"dast_profile_schedules\" = EXCLUDED.\"dast_profile_schedules\";\n")
   -> 0.0007s
-- quote_column_name("dast_profile_schedules")
   -> 0.0000s
-- quote("ultimate_trial")
   -> 0.0000s
-- quote(0)
   -> 0.0000s
-- execute("INSERT INTO plan_limits (plan_id, \"dast_profile_schedules\")\nSELECT id, '0' FROM plans WHERE name = 'ultimate_trial' LIMIT 1\nON CONFLICT (plan_id) DO UPDATE SET \"dast_profile_schedules\" = EXCLUDED.\"dast_profile_schedules\";\n")
   -> 0.0007s
== 20210819105904 InsertDastProfileSchedulesPlanLimits: reverted (0.0098s) ====

== 20210819105519 AddDastSchedulesToPlanLimits: reverting =====================
-- remove_column(:plan_limits, :dast_profile_schedules, :integer, {:default=>0, :null=>false})
   -> 0.0021s
== 20210819105519 AddDastSchedulesToPlanLimits: reverted (0.0037s) ============

Steps to test

Change the limit to 1 in the local and try to create more than one schedule for different profiles.

  1. update the limit to 1 using rails console:

PlanLimits.all.map {|p| p.update!(dast_profile_schedules: 1)}
  1. Create schedules

user = User.first # root user
project = user.projects.first # find project with dast enabled
profile = Dast::Profile.find_by(project: project.id)

dast_profile1 = ::Dast::Profile.create!(
  project: project,
  name: 'tadaa1',
  description: 'adad',
  branch_name: profile.branch_name,
  dast_site_profile: profile.dast_site_profile,
  dast_scanner_profile: profile.dast_scanner_profile
)
dast_profile2 = ::Dast::Profile.create!(
  project: project,
  name: 'tadaa2',
  description: 'adad',
  branch_name: profile.branch_name,
  dast_site_profile: profile.dast_site_profile,
  dast_scanner_profile: profile.dast_scanner_profile
)

schedule1 = Dast::ProfileSchedule.create!(user_id: user.id, cron: "0 0 8 */3 *", next_run_at: Time.now.in_time_zone('Melbourne'), dast_profile_id: dast_profile1.id, project_id: project.id, starts_at: Time.zone.now, timezone: 'ETC/UTC', active: true)

schedule2 = Dast::ProfileSchedule.create!(user_id: user.id, cron: "0 0 8 */3 *", next_run_at: Time.now.in_time_zone('Melbourne'), dast_profile_id: dast_profile2.id, project_id: project.id, starts_at: Time.zone.now, timezone: 'ETC/UTC', active: true)

schedule2 should give the error.

  1. You can also try marking schedule 1 inactive and schedule2 create will pass.

How to setup and validate locally (strongly suggested)

Does this MR meet the acceptance criteria?

Conformity

Availability and Testing

Security

Does this MR contain changes to processing or storing of credentials or tokens, authorization and authentication methods or other items described in the security review guidelines? If not, then delete this Security section.

  • 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

Related to #335816 (closed)

Edited by Saikat Sarkar

Merge request reports