Add GQL API to fetch dedicated hosted runner usage

What does this MR do and why?

This merge request introduces a new GraphQL query for retrieving compute usage data for dedicated hosted runners in GitLab. It adds a new resolver, types, and database scopes to support querying usage data either aggregated at the instance level or grouped by root namespace. The changes include new GraphQL fields, arguments, and enums to allow flexible querying of usage data by billing month or year.

Additionally, it implements authorization checks to ensure only admin users on GitLab Dedicated instances can access this data. The merge request also includes corresponding test coverage for the new functionality.

References

Please include cross links to any resources that are relevant to this MR. This will give reviewers and future readers helpful context to give an efficient review of the changes introduced.

MR acceptance checklist

Please evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.

Query plans

Since this API is Dedicated specific, the data in production tables for .com is empty, but I still want to share the query plans for database review. I added around 700k rows to this table and generated the below query plans.

For INSTANCE_AGGREGATE grouping

Plan for billingMonth filter - https://console.postgres.ai/gitlab/gitlab-production-ci/sessions/36171/commands/111397

Plan for year filter - https://console.postgres.ai/gitlab/gitlab-production-ci/sessions/36171/commands/111396

For PER_ROOT_NAMESPACE grouping

Plan for billingMonth filter - https://console.postgres.ai/gitlab/gitlab-production-ci/sessions/36171/commands/111398

Plan for year filter - https://console.postgres.ai/gitlab/gitlab-production-ci/sessions/36171/commands/111399

Screenshots or screen recordings

Billing month filter with Instance aggregate Screenshot_2025-02-04_at_2.42.13_PM
Billing month filter with Per root namespace Screenshot_2025-02-04_at_2.43.22_PM
Year filter with per root namespace Screenshot_2025-02-04_at_2.44.21_PM
Year filter with instance aggregate Screenshot_2025-02-04_at_2.45.22_PM

How to set up and validate locally

  1. Create some usage entries by using the below rails console command.
Ci::Minutes::GitlabHostedRunnerMonthlyUsage.create!(
  billing_month: Date.new(2025, 2, 1),
  compute_minutes_used: 100.0, # Replace with the desired value
  runner_duration_seconds: 6000, # Replace with the desired value
  root_namespace: Namespace.first, # Replace with the desired namespace
  runner: Ci::Runner.first, # Replace with the desired runner
  project: Project.first # Replace with the desired project
)
  1. Enable GitLab dedicated setting with - Gitlab::CurrentSettings.update(gitlab_dedicated_instance: true)

  2. Use the below query as per filters in screenshots -

query {
  ciDedicatedHostedRunnerUsage(grouping: <GroupingEnum>, 
    year: <YearFilter> # or billingMonth: "2025-01-01") {
    nodes {
      billingMonth
      billingMonthIso8601
      computeMinutes
      durationSeconds
      rootNamespace {
        id
        name
      }
    }
  }
}
  1. The above steps should get you the data at instance level and at root namespace level in the response.
Edited by Rajendra Kadam

Merge request reports

Loading