diff --git a/Gemfile b/Gemfile index a36a621bdab..bf6c8b45e14 100644 --- a/Gemfile +++ b/Gemfile @@ -220,7 +220,7 @@ gem 'gitlab-fog-azure-rm', '~> 2.2.0', require: 'fog/azurerm', feature_category: gem 'google-apis-storage_v1', '~> 0.29', feature_category: :shared gem 'google-cloud-storage', '~> 1.45.0', feature_category: :shared # We need >= 0.11.1 because that's when match_glob support is added to list_objects -gem 'google-apis-core', '~> 0.11.0', '>= 0.11.1', feature_category: :shared +gem 'google-apis-core', '~> 0.18.0', '>= 0.18.0', feature_category: :shared gem 'google-apis-compute_v1', '~> 0.57.0', feature_category: :shared gem 'google-apis-container_v1', '~> 0.43.0', feature_category: :shared gem 'google-apis-container_v1beta1', '~> 0.43.0', feature_category: :shared @@ -752,4 +752,4 @@ gem 'paper_trail', '~> 16.0', feature_category: :shared gem "i18n_data", "~> 0.13.1", feature_category: :system_access -gem "gitlab-cloud-connector", "~> 1.21", require: 'gitlab/cloud_connector', feature_category: :plan_provisioning +gem "gitlab-cloud-connector", "~> 1.22", require: 'gitlab/cloud_connector', feature_category: :plan_provisioning diff --git a/Gemfile.checksum b/Gemfile.checksum index 28bb9305005..07512b4ede8 100644 --- a/Gemfile.checksum +++ b/Gemfile.checksum @@ -218,7 +218,7 @@ {"name":"gitaly","version":"18.2.0","platform":"ruby","checksum":"229010b9e8a9e8de213591989795df17a3bdcc01957903bd2a2f1474bbff5578"}, {"name":"gitlab","version":"4.19.0","platform":"ruby","checksum":"3f645e3e195dbc24f0834fbf83e8ccfb2056d8e9712b01a640aad418a6949679"}, {"name":"gitlab-chronic","version":"0.10.6","platform":"ruby","checksum":"a244d11a1396d2aac6ae9b2f326adf1605ec1ad20c29f06e8b672047d415a9ac"}, -{"name":"gitlab-cloud-connector","version":"1.21.0","platform":"ruby","checksum":"16eb2a42f223c6c70efc20a8fd9e2bbe4fa91603894daa8a72f354f425a07709"}, +{"name":"gitlab-cloud-connector","version":"1.22.0","platform":"ruby","checksum":"5c9cffd0a24b7004fa7a16d0a5ef378c7192ceb11b38b8147f18c268720b2a86"}, {"name":"gitlab-crystalball","version":"1.1.1","platform":"ruby","checksum":"0464a113b0809e0e9fa7c0100bb6634fe38465af95aa04efa49541d64250b8ed"}, {"name":"gitlab-dangerfiles","version":"4.9.2","platform":"ruby","checksum":"d5c050f685d8720f6e70191a7d1216854d860dbdea5b455f87abe7542e005798"}, {"name":"gitlab-experiment","version":"0.9.1","platform":"ruby","checksum":"f230ee742154805a755d5f2539dc44d93cdff08c5bbbb7656018d61f93d01f48"}, @@ -251,7 +251,7 @@ {"name":"google-apis-compute_v1","version":"0.57.0","platform":"ruby","checksum":"404514548abc3a44f5e96393d6a6d588d287548ecb6f5a886ad76e1beea78068"}, {"name":"google-apis-container_v1","version":"0.43.0","platform":"ruby","checksum":"781d2514cb27268be9cfbae57cbc4203966afb2cf8f2c636326f5bc603862424"}, {"name":"google-apis-container_v1beta1","version":"0.43.0","platform":"ruby","checksum":"68c48fcf88db926ceab16f56890c85890269e6366b272fcde958a9b5550313d0"}, -{"name":"google-apis-core","version":"0.11.2","platform":"ruby","checksum":"ed2e4d4a2e0e241b6d5b545bfb2d7069ca8be1c6766c605a09134a9f99379eb2"}, +{"name":"google-apis-core","version":"0.18.0","platform":"ruby","checksum":"96b057816feeeab448139ed5b5c78eab7fc2a9d8958f0fbc8217dedffad054ee"}, {"name":"google-apis-dns_v1","version":"0.36.0","platform":"ruby","checksum":"5dd273d78ab37d03d1bc07837186f79ad0399e9f2b8b1ec2629ed682ea347d47"}, {"name":"google-apis-iam_v1","version":"0.36.0","platform":"ruby","checksum":"0db7e2876b5d0d636e8326baa6b9cf1cddd58b607151e5db1fe8fd00899a1f66"}, {"name":"google-apis-iamcredentials_v1","version":"0.15.0","platform":"ruby","checksum":"e9a256a6d80fbfc77d44bd7e65bc94b9e1e9863a00e6d413edc0102d6cb5551b"}, diff --git a/Gemfile.lock b/Gemfile.lock index fdfe288a520..9cfca04950c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -735,7 +735,7 @@ GEM terminal-table (>= 1.5.1) gitlab-chronic (0.10.6) numerizer (~> 0.2) - gitlab-cloud-connector (1.21.0) + gitlab-cloud-connector (1.22.0) activesupport (~> 7.0) jwt (~> 2.9.3) gitlab-crystalball (1.1.1) @@ -845,15 +845,14 @@ GEM google-apis-core (>= 0.9.1, < 2.a) google-apis-container_v1beta1 (0.43.0) google-apis-core (>= 0.9.1, < 2.a) - google-apis-core (0.11.2) + google-apis-core (0.18.0) addressable (~> 2.5, >= 2.5.1) - googleauth (>= 0.16.2, < 2.a) - httpclient (>= 2.8.1, < 3.a) + googleauth (~> 1.9) + httpclient (>= 2.8.3, < 3.a) mini_mime (~> 1.0) + mutex_m representable (~> 3.0) retriable (>= 2.0, < 4.a) - rexml - webrick google-apis-dns_v1 (0.36.0) google-apis-core (>= 0.11.0, < 2.a) google-apis-iam_v1 (0.36.0) @@ -2153,7 +2152,7 @@ DEPENDENCIES gitlab-active-context! gitlab-backup-cli! gitlab-chronic (~> 0.10.5) - gitlab-cloud-connector (~> 1.21) + gitlab-cloud-connector (~> 1.22) gitlab-crystalball (~> 1.1.0) gitlab-dangerfiles (~> 4.9.0) gitlab-duo-workflow-service-client (~> 0.2)! @@ -2189,7 +2188,7 @@ DEPENDENCIES google-apis-compute_v1 (~> 0.57.0) google-apis-container_v1 (~> 0.43.0) google-apis-container_v1beta1 (~> 0.43.0) - google-apis-core (~> 0.11.0, >= 0.11.1) + google-apis-core (~> 0.18.0, >= 0.18.0) google-apis-iam_v1 (~> 0.36.0) google-apis-serviceusage_v1 (~> 0.28.0) google-apis-sqladmin_v1beta4 (~> 0.41.0) diff --git a/Gemfile.next.checksum b/Gemfile.next.checksum index 4bdb5640aa0..a47d597d85e 100644 --- a/Gemfile.next.checksum +++ b/Gemfile.next.checksum @@ -218,7 +218,7 @@ {"name":"gitaly","version":"18.2.0","platform":"ruby","checksum":"229010b9e8a9e8de213591989795df17a3bdcc01957903bd2a2f1474bbff5578"}, {"name":"gitlab","version":"4.19.0","platform":"ruby","checksum":"3f645e3e195dbc24f0834fbf83e8ccfb2056d8e9712b01a640aad418a6949679"}, {"name":"gitlab-chronic","version":"0.10.6","platform":"ruby","checksum":"a244d11a1396d2aac6ae9b2f326adf1605ec1ad20c29f06e8b672047d415a9ac"}, -{"name":"gitlab-cloud-connector","version":"1.21.0","platform":"ruby","checksum":"16eb2a42f223c6c70efc20a8fd9e2bbe4fa91603894daa8a72f354f425a07709"}, +{"name":"gitlab-cloud-connector","version":"1.22.0","platform":"ruby","checksum":"5c9cffd0a24b7004fa7a16d0a5ef378c7192ceb11b38b8147f18c268720b2a86"}, {"name":"gitlab-crystalball","version":"1.1.1","platform":"ruby","checksum":"0464a113b0809e0e9fa7c0100bb6634fe38465af95aa04efa49541d64250b8ed"}, {"name":"gitlab-dangerfiles","version":"4.9.2","platform":"ruby","checksum":"d5c050f685d8720f6e70191a7d1216854d860dbdea5b455f87abe7542e005798"}, {"name":"gitlab-experiment","version":"0.9.1","platform":"ruby","checksum":"f230ee742154805a755d5f2539dc44d93cdff08c5bbbb7656018d61f93d01f48"}, @@ -251,7 +251,7 @@ {"name":"google-apis-compute_v1","version":"0.57.0","platform":"ruby","checksum":"404514548abc3a44f5e96393d6a6d588d287548ecb6f5a886ad76e1beea78068"}, {"name":"google-apis-container_v1","version":"0.43.0","platform":"ruby","checksum":"781d2514cb27268be9cfbae57cbc4203966afb2cf8f2c636326f5bc603862424"}, {"name":"google-apis-container_v1beta1","version":"0.43.0","platform":"ruby","checksum":"68c48fcf88db926ceab16f56890c85890269e6366b272fcde958a9b5550313d0"}, -{"name":"google-apis-core","version":"0.11.2","platform":"ruby","checksum":"ed2e4d4a2e0e241b6d5b545bfb2d7069ca8be1c6766c605a09134a9f99379eb2"}, +{"name":"google-apis-core","version":"0.18.0","platform":"ruby","checksum":"96b057816feeeab448139ed5b5c78eab7fc2a9d8958f0fbc8217dedffad054ee"}, {"name":"google-apis-dns_v1","version":"0.36.0","platform":"ruby","checksum":"5dd273d78ab37d03d1bc07837186f79ad0399e9f2b8b1ec2629ed682ea347d47"}, {"name":"google-apis-iam_v1","version":"0.36.0","platform":"ruby","checksum":"0db7e2876b5d0d636e8326baa6b9cf1cddd58b607151e5db1fe8fd00899a1f66"}, {"name":"google-apis-iamcredentials_v1","version":"0.15.0","platform":"ruby","checksum":"e9a256a6d80fbfc77d44bd7e65bc94b9e1e9863a00e6d413edc0102d6cb5551b"}, diff --git a/Gemfile.next.lock b/Gemfile.next.lock index c76dfd82e0e..ea75ca100df 100644 --- a/Gemfile.next.lock +++ b/Gemfile.next.lock @@ -729,7 +729,7 @@ GEM terminal-table (>= 1.5.1) gitlab-chronic (0.10.6) numerizer (~> 0.2) - gitlab-cloud-connector (1.21.0) + gitlab-cloud-connector (1.22.0) activesupport (~> 7.0) jwt (~> 2.9.3) gitlab-crystalball (1.1.1) @@ -839,15 +839,14 @@ GEM google-apis-core (>= 0.9.1, < 2.a) google-apis-container_v1beta1 (0.43.0) google-apis-core (>= 0.9.1, < 2.a) - google-apis-core (0.11.2) + google-apis-core (0.18.0) addressable (~> 2.5, >= 2.5.1) - googleauth (>= 0.16.2, < 2.a) - httpclient (>= 2.8.1, < 3.a) + googleauth (~> 1.9) + httpclient (>= 2.8.3, < 3.a) mini_mime (~> 1.0) + mutex_m representable (~> 3.0) retriable (>= 2.0, < 4.a) - rexml - webrick google-apis-dns_v1 (0.36.0) google-apis-core (>= 0.11.0, < 2.a) google-apis-iam_v1 (0.36.0) @@ -2148,7 +2147,7 @@ DEPENDENCIES gitlab-active-context! gitlab-backup-cli! gitlab-chronic (~> 0.10.5) - gitlab-cloud-connector (~> 1.21) + gitlab-cloud-connector (~> 1.22) gitlab-crystalball (~> 1.1.0) gitlab-dangerfiles (~> 4.9.0) gitlab-duo-workflow-service-client (~> 0.2)! @@ -2184,7 +2183,7 @@ DEPENDENCIES google-apis-compute_v1 (~> 0.57.0) google-apis-container_v1 (~> 0.43.0) google-apis-container_v1beta1 (~> 0.43.0) - google-apis-core (~> 0.11.0, >= 0.11.1) + google-apis-core (~> 0.18.0, >= 0.18.0) google-apis-iam_v1 (~> 0.36.0) google-apis-serviceusage_v1 (~> 0.28.0) google-apis-sqladmin_v1beta4 (~> 0.41.0) diff --git a/app/assets/javascripts/ci/job_details/components/sidebar/sidebar_job_details_container.vue b/app/assets/javascripts/ci/job_details/components/sidebar/sidebar_job_details_container.vue index 8af5142fff1..b257030f1c3 100644 --- a/app/assets/javascripts/ci/job_details/components/sidebar/sidebar_job_details_container.vue +++ b/app/assets/javascripts/ci/job_details/components/sidebar/sidebar_job_details_container.vue @@ -128,7 +128,7 @@ export default { api: s__('JobSource|API'), chat: s__('JobSource|Chat'), container_registry_push: s__('JobSource|Container Registry Push'), - duo_workflow: s__('JobSource|Duo Workflow'), + duo_workflow: s__('JobSource|Duo Agent Platform'), external: s__('JobSource|External'), external_pull_request_event: s__('JobSource|External Pull Request'), merge_request_event: s__('JobSource|Merge Request'), diff --git a/app/assets/javascripts/projects/pipelines/charts/components/pipelines_dashboard_clickhouse_filters.vue b/app/assets/javascripts/projects/pipelines/charts/components/pipelines_dashboard_clickhouse_filters.vue index 1f9796ac90c..a41c0b90c23 100644 --- a/app/assets/javascripts/projects/pipelines/charts/components/pipelines_dashboard_clickhouse_filters.vue +++ b/app/assets/javascripts/projects/pipelines/charts/components/pipelines_dashboard_clickhouse_filters.vue @@ -57,7 +57,7 @@ const sourcesItems = [ text: s__('PipelineSource|Scheduled Scan Execution Policy'), }, { value: SOURCE_CONTAINER_REGISTRY_PUSH, text: s__('PipelineSource|Container Registry Push') }, - { value: SOURCE_DUO_WORKFLOW, text: s__('PipelineSource|Duo Workflow') }, + { value: SOURCE_DUO_WORKFLOW, text: s__('PipelineSource|Duo Agent Platform') }, { value: SOURCE_PIPELINE_EXECUTION_POLICY_SCHEDULE, text: s__('PipelineSource|Scheduled Pipeline Execution Policy'), diff --git a/app/presenters/observability/observability_presenter.rb b/app/presenters/observability/observability_presenter.rb new file mode 100644 index 00000000000..295f8d9c2dd --- /dev/null +++ b/app/presenters/observability/observability_presenter.rb @@ -0,0 +1,66 @@ +# frozen_string_literal: true + +module Observability + class ObservabilityPresenter + PATHS = { + 'services' => 'Services', + 'traces-explorer' => 'Traces Explorer', + 'logs/logs-explorer' => 'Logs Explorer', + 'metrics-explorer/summary' => 'Metrics Explorer', + 'infrastructure-monitoring/hosts' => 'Infrastructure Monitoring', + 'dashboard' => 'Dashboard', + 'messaging-queues' => 'Messaging Queues', + 'api-monitoring/explorer' => 'API Monitoring', + 'alerts' => 'Alerts', + 'exceptions' => 'Exceptions', + 'service-map' => 'Service Map', + 'settings' => 'Settings' + }.freeze + + def initialize(group, path) + @group = group + @path = path + end + + def title + PATHS.fetch(@path, 'Observability') + end + + def auth_tokens + formatted_auth_tokens + end + + def to_h + { + o11y_url: observability_setting&.o11y_service_url, + path: @path, + auth_tokens: formatted_auth_tokens, + title: title, + encryption_key: observability_setting&.o11y_service_post_message_encryption_key + } + end + + private + + attr_reader :group, :path + + def observability_setting + @observability_setting ||= @group.observability_group_o11y_setting + end + + def formatted_auth_tokens + return {} unless observability_setting + + begin + tokens = Observability::O11yToken.generate_tokens(observability_setting) + rescue StandardError => e + Gitlab::ErrorTracking.log_exception(e) + return {} + end + + return {} if tokens.blank? + + tokens.transform_keys { |key| key.to_s.underscore } + end + end +end diff --git a/config/metrics/counts_all/20210502050942_ci_runners_online.yml b/config/metrics/counts_all/20210502050942_ci_runners_online.yml index b5ef3ef15a6..f610cbde30d 100644 --- a/config/metrics/counts_all/20210502050942_ci_runners_online.yml +++ b/config/metrics/counts_all/20210502050942_ci_runners_online.yml @@ -12,6 +12,7 @@ milestone: "13.12" introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/58197 time_frame: all data_source: database +instrumentation_class: CountCiRunnersOnlineMetric tiers: - free - premium diff --git a/doc/operations/observability.md b/doc/operations/observability.md index f5a30a9f809..ce58c5bac93 100644 --- a/doc/operations/observability.md +++ b/doc/operations/observability.md @@ -349,6 +349,34 @@ To add OpenTelemetry instrumentation to your applications: Refer to the [OpenTelemetry documentation](https://opentelemetry.io/docs/instrumentation/) for language-specific guidelines. +## GitLab Observability Templates + +GitLab provides pre-built dashboard templates to help you get started with observability quickly. These templates are available at [Experimental Observability O11y Templates](https://gitlab.com/gitlab-org/embody-team/experimental-observability/o11y-templates/). + +### Available templates + +**Standard OpenTelemetry dashboards**: If you instrument your application with standard OpenTelemetry libraries, you can use these plug-and-play dashboard templates: + +- Application performance monitoring dashboards +- Service dependency visualizations +- Error rate and latency tracking + +**GitLab-specific dashboards**: When you send GitLab OpenTelemetry data to your GitLab O11y instance, use these dashboards for out-of-the-box insights: + +- GitLab application performance metrics +- GitLab service health monitoring +- GitLab-specific trace analysis + +**CI/CD observability**: The repository includes an example GitLab CI/CD pipeline with OpenTelemetry instrumentation that works with the GitLab O11y CI/CD dashboard template JSON file. This helps you monitor your CI/CD pipeline performance and identify bottlenecks. + +### Using the templates + +1. Clone or download the templates from the repository. +1. Update the service name in the example application dashboards to match your service name. +1. Import the JSON files into your GitLab O11y instance. +1. Configure your applications to send telemetry data using standard OpenTelemetry libraries as described in the [Instrument your application](#instrument-your-application) section. +1. The dashboards are now available with your application's telemetry data in GitLab O11y. + ## Troubleshooting ### GitLab Observability instance issues diff --git a/lib/gitlab/usage/metrics/instrumentations/count_ci_runners_online_metric.rb b/lib/gitlab/usage/metrics/instrumentations/count_ci_runners_online_metric.rb new file mode 100644 index 00000000000..da506fea2a0 --- /dev/null +++ b/lib/gitlab/usage/metrics/instrumentations/count_ci_runners_online_metric.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +module Gitlab + module Usage + module Metrics + module Instrumentations + class CountCiRunnersOnlineMetric < DatabaseMetric + operation :count + + relation { ::Ci::Runner.online } + end + end + end + end +end diff --git a/locale/gitlab.pot b/locale/gitlab.pot index f6c3c3dad33..c7967b153a2 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -2544,6 +2544,9 @@ msgstr "" msgid "AICatalog|You are an expert in [domain]. Your communication style is [style]. When helping users, you should always... Your key strengths include... You approach problems by..." msgstr "" +msgid "AICatalog|cannot be changed from public to private as it has catalog consumers" +msgstr "" + msgid "AICatalog|e.g., Research Assistant, Creative Writer, Code Helper" msgstr "" @@ -6000,7 +6003,7 @@ msgstr "" msgid "AiPowered|Amazon Q Setup" msgstr "" -msgid "AiPowered|Are you sure you want to turn off GitLab Duo Workflow?" +msgid "AiPowered|Are you sure you want to turn off GitLab Duo Agent Platform?" msgstr "" msgid "AiPowered|Assign models to AI-native features." @@ -6099,7 +6102,7 @@ msgstr "" msgid "AiPowered|Explore GitLab Duo Core" msgstr "" -msgid "AiPowered|Failed to disable GitLab Duo Workflow." +msgid "AiPowered|Failed to disable GitLab Duo Agent Platform." msgstr "" msgid "AiPowered|Failed to enable GitLab Duo Agent Platform." @@ -6123,6 +6126,12 @@ msgstr "" msgid "AiPowered|GitLab Duo Agent Platform" msgstr "" +msgid "AiPowered|GitLab Duo Agent Platform has successfully been turned off." +msgstr "" + +msgid "AiPowered|GitLab Duo Agent Platform is an AI-native coding agent in the Visual Studio Code (VS Code) IDE." +msgstr "" + msgid "AiPowered|GitLab Duo Agent Platform is now on for the instance and the service account (%{accountId}) was created. To use Agent Platform in your groups, you must turn on AI features for specific groups." msgstr "" @@ -6144,9 +6153,6 @@ msgstr "" msgid "AiPowered|GitLab Duo Self-Hosted" msgstr "" -msgid "AiPowered|GitLab Duo Workflow has successfully been turned off." -msgstr "" - msgid "AiPowered|GitLab Duo availability" msgstr "" @@ -6231,13 +6237,10 @@ msgstr "" msgid "AiPowered|This setting requires GitLab Duo availability to be on or off by default." msgstr "" -msgid "AiPowered|Turn off GitLab Duo Workflow" +msgid "AiPowered|Turn off GitLab Duo Agent Platform" msgstr "" -msgid "AiPowered|Turn off Workflow" -msgstr "" - -msgid "AiPowered|Turn on GitLab Duo Workflow" +msgid "AiPowered|Turn on GitLab Duo Agent Platform" msgstr "" msgid "AiPowered|Turn on IDE features" @@ -6267,7 +6270,7 @@ msgstr "" msgid "AiPowered|View configuration" msgstr "" -msgid "AiPowered|What is this service account?" +msgid "AiPowered|What is the Duo Agent Platform service account?" msgstr "" msgid "AiPowered|When GitLab Duo is not available, experiment and beta features cannot be turned on." @@ -6282,13 +6285,10 @@ msgstr "" msgid "AiPowered|When you save, GitLab Duo will be turned off for all groups, subgroups, and projects." msgstr "" -msgid "AiPowered|When you turn off Workflow, users can no longer use it to solve coding tasks. Are you sure?" +msgid "AiPowered|When you turn off GitLab Duo Agent Platform, users can no longer use it to solve coding tasks. Are you sure?" msgstr "" -msgid "AiPowered|When you turn on GitLab Duo Workflow, a service account is created." -msgstr "" - -msgid "AiPowered|Workflow is an AI-native coding agent in the Visual Studio Code (VS Code) IDE." +msgid "AiPowered|When you turn on GitLab Duo Agent Platform, a service account is created." msgstr "" msgid "AiPowered|You now have access to GitLab Duo Chat and Code Suggestions in supported IDEs. To start using these features, %{link1Start}install the GitLab extension in your IDE%{link1End}. If you already have this extension installed, %{link2Start}explore what you can do with GitLab Duo Core%{link2End}." @@ -16169,6 +16169,9 @@ msgstr "" msgid "ComplianceReport|Action" msgstr "" +msgid "ComplianceReport|Activity" +msgstr "" + msgid "ComplianceReport|All frameworks" msgstr "" @@ -22863,7 +22866,7 @@ msgstr "" msgid "Details block" msgstr "" -msgid "Details of vio-%{violationId}" +msgid "Details of violation-%{violationId}" msgstr "" msgid "Detect host keys" @@ -24263,7 +24266,7 @@ msgstr "" msgid "DuoWorkflowSettings|Model Context Protocol" msgstr "" -msgid "DuoWorkflowSettings|Turn on MCP support for GitLab Duo Agentic Chat and GitLab Duo Workflow" +msgid "DuoWorkflowSettings|Turn on MCP support for GitLab Duo Agentic Chat and GitLab Duo Agent Platform" msgstr "" msgid "DuoWorkflowSettings|Turn on Model Context Protocol (MCP) support" @@ -35678,6 +35681,9 @@ msgstr "" msgid "JobSource|Container Registry Push" msgstr "" +msgid "JobSource|Duo Agent Platform" +msgstr "" + msgid "JobSource|Duo Workflow" msgstr "" @@ -45990,7 +45996,7 @@ msgstr "" msgid "PipelineSource|Container Registry Push" msgstr "" -msgid "PipelineSource|Duo Workflow" +msgid "PipelineSource|Duo Agent Platform" msgstr "" msgid "PipelineSource|External" diff --git a/package.json b/package.json index 344c1e6ff57..dfb8f30de90 100644 --- a/package.json +++ b/package.json @@ -60,7 +60,7 @@ "@gitlab/application-sdk-browser": "^0.3.4", "@gitlab/at.js": "1.5.7", "@gitlab/cluster-client": "^3.0.0", - "@gitlab/duo-ui": "^10.5.0", + "@gitlab/duo-ui": "^10.6.0", "@gitlab/favicon-overlay": "2.0.0", "@gitlab/fonts": "^1.3.0", "@gitlab/query-language-rust": "0.13.1", diff --git a/spec/frontend/ci/job_details/components/sidebar/sidebar_job_details_container_spec.js b/spec/frontend/ci/job_details/components/sidebar/sidebar_job_details_container_spec.js index 29091eb6d43..bfe8dc42468 100644 --- a/spec/frontend/ci/job_details/components/sidebar/sidebar_job_details_container_spec.js +++ b/spec/frontend/ci/job_details/components/sidebar/sidebar_job_details_container_spec.js @@ -83,7 +83,7 @@ describe('Job Sidebar Details Container', () => { ['api', 'Source: API'], ['chat', 'Source: Chat'], ['container_registry_push', 'Source: Container Registry Push'], - ['duo_workflow', 'Source: Duo Workflow'], + ['duo_workflow', 'Source: Duo Agent Platform'], ['external', 'Source: External'], ['external_pull_request_event', 'Source: External Pull Request'], ['merge_request_event', 'Source: Merge Request'], diff --git a/spec/frontend/projects/pipelines/charts/components/pipelines_dashboard_clickhouse_filters_spec.js b/spec/frontend/projects/pipelines/charts/components/pipelines_dashboard_clickhouse_filters_spec.js index 937f52a73ea..6516747af1f 100644 --- a/spec/frontend/projects/pipelines/charts/components/pipelines_dashboard_clickhouse_filters_spec.js +++ b/spec/frontend/projects/pipelines/charts/components/pipelines_dashboard_clickhouse_filters_spec.js @@ -83,7 +83,7 @@ describe('PipelinesDashboardClickhouseFilters', () => { 'On-Demand DAST Validation', 'Scheduled Scan Execution Policy', 'Container Registry Push', - 'Duo Workflow', + 'Duo Agent Platform', 'Scheduled Pipeline Execution Policy', 'Unknown', ]); diff --git a/spec/lib/gitlab/usage/metrics/instrumentations/count_ci_runners_group_type_active_metric_spec.rb b/spec/lib/gitlab/usage/metrics/instrumentations/count_ci_runners_group_type_active_metric_spec.rb index c1313961202..da50108f08e 100644 --- a/spec/lib/gitlab/usage/metrics/instrumentations/count_ci_runners_group_type_active_metric_spec.rb +++ b/spec/lib/gitlab/usage/metrics/instrumentations/count_ci_runners_group_type_active_metric_spec.rb @@ -8,6 +8,7 @@ RSpec.describe Gitlab::Usage::Metrics::Instrumentations::CountCiRunnersGroupType before do create(:ci_runner, :group, groups: [group]) + create(:ci_runner, :group, :paused, groups: [group]) end it_behaves_like 'a correct instrumented metric value', { time_frame: 'all', data_source: 'database' } diff --git a/spec/lib/gitlab/usage/metrics/instrumentations/count_ci_runners_group_type_active_online_metric_spec.rb b/spec/lib/gitlab/usage/metrics/instrumentations/count_ci_runners_group_type_active_online_metric_spec.rb index 37d31e32581..fbbc291fad5 100644 --- a/spec/lib/gitlab/usage/metrics/instrumentations/count_ci_runners_group_type_active_online_metric_spec.rb +++ b/spec/lib/gitlab/usage/metrics/instrumentations/count_ci_runners_group_type_active_online_metric_spec.rb @@ -7,7 +7,9 @@ RSpec.describe Gitlab::Usage::Metrics::Instrumentations::CountCiRunnersGroupType let(:expected_value) { 1 } before do - create(:ci_runner, :group, groups: [group], contacted_at: 1.second.ago) + create(:ci_runner, :group, :online, groups: [group]) + create(:ci_runner, :group, :online, :paused, groups: [group]) + create(:ci_runner, :group, :offline, groups: [group]) end it_behaves_like 'a correct instrumented metric value', { time_frame: 'all', data_source: 'database' } diff --git a/spec/lib/gitlab/usage/metrics/instrumentations/count_ci_runners_instance_type_active_metric_spec.rb b/spec/lib/gitlab/usage/metrics/instrumentations/count_ci_runners_instance_type_active_metric_spec.rb index ae4829cceef..fd401f95917 100644 --- a/spec/lib/gitlab/usage/metrics/instrumentations/count_ci_runners_instance_type_active_metric_spec.rb +++ b/spec/lib/gitlab/usage/metrics/instrumentations/count_ci_runners_instance_type_active_metric_spec.rb @@ -7,6 +7,7 @@ RSpec.describe Gitlab::Usage::Metrics::Instrumentations::CountCiRunnersInstanceT before do create(:ci_runner) + create(:ci_runner, :paused) end it_behaves_like 'a correct instrumented metric value', { time_frame: 'all', data_source: 'database' } diff --git a/spec/lib/gitlab/usage/metrics/instrumentations/count_ci_runners_instance_type_active_online_metric_spec.rb b/spec/lib/gitlab/usage/metrics/instrumentations/count_ci_runners_instance_type_active_online_metric_spec.rb index 389eb07bf80..5fdb998e0bc 100644 --- a/spec/lib/gitlab/usage/metrics/instrumentations/count_ci_runners_instance_type_active_online_metric_spec.rb +++ b/spec/lib/gitlab/usage/metrics/instrumentations/count_ci_runners_instance_type_active_online_metric_spec.rb @@ -7,6 +7,8 @@ RSpec.describe Gitlab::Usage::Metrics::Instrumentations::CountCiRunnersInstanceT before do create(:ci_runner, :online) + create(:ci_runner, :offline) + create(:ci_runner, :paused) end it_behaves_like 'a correct instrumented metric value', { time_frame: 'all', data_source: 'database' } diff --git a/spec/lib/gitlab/usage/metrics/instrumentations/count_ci_runners_online_metric_spec.rb b/spec/lib/gitlab/usage/metrics/instrumentations/count_ci_runners_online_metric_spec.rb new file mode 100644 index 00000000000..f5385830a53 --- /dev/null +++ b/spec/lib/gitlab/usage/metrics/instrumentations/count_ci_runners_online_metric_spec.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Gitlab::Usage::Metrics::Instrumentations::CountCiRunnersOnlineMetric, feature_category: :runner do + let_it_be(:group) { create(:group) } + let(:expected_value) { 1 } + + before do + create(:ci_runner, :group, :online, groups: [group]) + create(:ci_runner, :group, :offline, groups: [group]) + end + + it_behaves_like 'a correct instrumented metric value', { time_frame: 'all', data_source: 'database' } +end diff --git a/spec/lib/gitlab/usage/metrics/instrumentations/count_ci_runners_project_type_active_metric_spec.rb b/spec/lib/gitlab/usage/metrics/instrumentations/count_ci_runners_project_type_active_metric_spec.rb index 811dcfccc0e..27579b8e6df 100644 --- a/spec/lib/gitlab/usage/metrics/instrumentations/count_ci_runners_project_type_active_metric_spec.rb +++ b/spec/lib/gitlab/usage/metrics/instrumentations/count_ci_runners_project_type_active_metric_spec.rb @@ -8,7 +8,9 @@ RSpec.describe Gitlab::Usage::Metrics::Instrumentations::CountCiRunnersProjectTy let(:expected_value) { 1 } before do + create(:ci_runner) create(:ci_runner, :project, projects: [project]) + create(:ci_runner, :project, :paused, projects: [project]) end it_behaves_like 'a correct instrumented metric value', { time_frame: 'all', data_source: 'database' } diff --git a/spec/lib/gitlab/usage/metrics/instrumentations/count_ci_runners_project_type_active_online_metric_spec.rb b/spec/lib/gitlab/usage/metrics/instrumentations/count_ci_runners_project_type_active_online_metric_spec.rb index ecc5b46582e..d74ca83426d 100644 --- a/spec/lib/gitlab/usage/metrics/instrumentations/count_ci_runners_project_type_active_online_metric_spec.rb +++ b/spec/lib/gitlab/usage/metrics/instrumentations/count_ci_runners_project_type_active_online_metric_spec.rb @@ -8,7 +8,10 @@ RSpec.describe Gitlab::Usage::Metrics::Instrumentations::CountCiRunnersProjectTy let(:expected_value) { 1 } before do - create(:ci_runner, :project, projects: [project], contacted_at: 1.second.ago) + create(:ci_runner) + create(:ci_runner, :project, :online, projects: [project]) + create(:ci_runner, :project, :online, :paused, projects: [project]) + create(:ci_runner, :project, :offline, projects: [project]) end it_behaves_like 'a correct instrumented metric value', { time_frame: 'all', data_source: 'database' } diff --git a/spec/presenters/observability/observability_presenter_spec.rb b/spec/presenters/observability/observability_presenter_spec.rb new file mode 100644 index 00000000000..0d5913a272a --- /dev/null +++ b/spec/presenters/observability/observability_presenter_spec.rb @@ -0,0 +1,151 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Observability::ObservabilityPresenter, feature_category: :observability do + let(:group) { build_stubbed(:group) } + let(:path) { 'services' } + let(:presenter) { described_class.new(group, path) } + + let!(:observability_setting) do + build_stubbed(:observability_group_o11y_setting, + group: group, + o11y_service_url: 'https://observability.example.com', + o11y_service_post_message_encryption_key: 'test-key') + end + + before do + allow(group).to receive(:observability_group_o11y_setting).and_return(observability_setting) + allow(Observability::O11yToken).to receive(:generate_tokens) + .with(observability_setting) + .and_return({ 'testToken' => 'value' }) + end + + describe '#title' do + context 'with a valid path' do + it 'returns the correct title' do + expect(presenter.title).to eq('Services') + end + end + + context 'with an invalid path' do + let(:path) { 'invalid-path' } + + it 'returns the default title' do + expect(presenter.title).to eq('Observability') + end + end + + context 'with different valid paths' do + described_class::PATHS.each do |path_key, expected_title| + context "with path #{path_key}" do + let(:path) { path_key } + + it "returns #{expected_title}" do + expect(presenter.title).to eq(expected_title) + end + end + end + end + end + + describe '#auth_tokens' do + it 'returns formatted auth tokens' do + expect(presenter.auth_tokens).to eq({ 'test_token' => 'value' }) + end + + context 'when auth tokens are blank' do + before do + allow(Observability::O11yToken).to receive(:generate_tokens) + .with(observability_setting) + .and_return(nil) + end + + it 'returns empty hash' do + expect(presenter.auth_tokens).to eq({}) + end + end + + context 'when Observability::O11yToken.generate_tokens raises an exception' do + let(:exception) { StandardError.new('Token generation failed') } + + before do + allow(Observability::O11yToken).to receive(:generate_tokens) + .with(observability_setting) + .and_raise(exception) + allow(Gitlab::ErrorTracking).to receive(:log_exception) + end + + it 'returns empty hash and logs the exception' do + expect(Gitlab::ErrorTracking).to receive(:log_exception).with(exception) + expect(presenter.auth_tokens).to eq({}) + end + end + end + + describe '#to_h' do + it 'returns a hash with all required keys' do + result = presenter.to_h + + expect(result).to include( + o11y_url: 'https://observability.example.com', + path: 'services', + auth_tokens: { 'test_token' => 'value' }, + title: 'Services', + encryption_key: 'test-key' + ) + end + + context 'when group has no observability settings' do + let(:group_without_settings) { build_stubbed(:group) } + let(:presenter_without_settings) { described_class.new(group_without_settings, path) } + + before do + allow(group_without_settings).to receive(:observability_group_o11y_setting).and_return(nil) + end + + it 'returns nil values for observability-specific fields' do + result = presenter_without_settings.to_h + + expect(result).to include( + o11y_url: nil, + path: 'services', + auth_tokens: {}, + title: 'Services', + encryption_key: nil + ) + end + end + + context 'when auth tokens are blank' do + before do + allow(Observability::O11yToken).to receive(:generate_tokens) + .with(observability_setting) + .and_return(nil) + end + + it 'returns empty hash for auth_tokens' do + result = presenter.to_h + + expect(result[:auth_tokens]).to eq({}) + end + end + + context 'when auth tokens have camelCase keys' do + before do + allow(Observability::O11yToken).to receive(:generate_tokens) + .with(observability_setting) + .and_return({ 'testToken' => 'value', 'anotherKey' => 'another_value' }) + end + + it 'transforms keys to snake_case' do + result = presenter.to_h + + expect(result[:auth_tokens]).to eq({ + 'test_token' => 'value', + 'another_key' => 'another_value' + }) + end + end + end +end diff --git a/spec/support/shared_examples/config/metrics/every_metric_definition_shared_examples.rb b/spec/support/shared_examples/config/metrics/every_metric_definition_shared_examples.rb index d26719718ed..4c78ce6d28e 100644 --- a/spec/support/shared_examples/config/metrics/every_metric_definition_shared_examples.rb +++ b/spec/support/shared_examples/config/metrics/every_metric_definition_shared_examples.rb @@ -20,7 +20,6 @@ RSpec.shared_examples 'every metric definition' do let(:ignored_metric_files_key_patterns) do %w[ - ci_runners_online mock_ci mock_monitoring user_auth_by_provider diff --git a/yarn.lock b/yarn.lock index acac15930b7..4ce82bd5a0b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1382,10 +1382,10 @@ core-js "^3.29.1" mitt "^3.0.1" -"@gitlab/duo-ui@^10.5.0": - version "10.5.0" - resolved "https://registry.yarnpkg.com/@gitlab/duo-ui/-/duo-ui-10.5.0.tgz#dcaadac9b57eaf7a5aecb95ce03e8e4378b9298b" - integrity sha512-ANSngN/nJLQ21EYXyYmYWRFqWOXEZXdHYL1Sn7/hxwhXXMq9uKziSYN7GlXmn1TRh7qJy+dx1xAY/o9METD+Fw== +"@gitlab/duo-ui@^10.6.0": + version "10.6.0" + resolved "https://registry.yarnpkg.com/@gitlab/duo-ui/-/duo-ui-10.6.0.tgz#42e3410ccae2aa72c456c7b9b3059276f3242bc8" + integrity sha512-oCcjI9CeNBhO/GLkwKMfF6rXBXbJLSa86NjEtTxuFyYH/yCXTPXfBtY+NmPReEqWXRYcXtd+jpbozESB1eKvwg== dependencies: "@floating-ui/dom" "1.7.2" echarts "^5.3.2" @@ -1425,7 +1425,7 @@ resolved "https://registry.yarnpkg.com/@gitlab/fonts/-/fonts-1.3.0.tgz#df89c1bb6714e4a8a5d3272568aa4de7fb337267" integrity sha512-DoMUIN3DqjEn7wvcxBg/b7Ite5fTdF5EmuOZoBRo2j0UBGweDXmNBi+9HrTZs4cBU660dOxcf1hATFcG3npbPg== -"@gitlab/noop@^1.0.1": +"@gitlab/noop@^1.0.1", jackspeak@^3.1.2, "jackspeak@npm:@gitlab/noop@1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@gitlab/noop/-/noop-1.0.1.tgz#71a831146ee02732b4a61d2d3c11204564753454" integrity sha512-s++4wjMYeDvBp9IO59DBrWjy8SE/gFkjTDO5ck2W0S6Vv7OlqgErwL7pHngAnrSmTJAzyUG8wHGqo0ViS4jn5Q== @@ -9495,11 +9495,6 @@ istanbul-reports@^3.1.3: html-escaper "^2.0.0" istanbul-lib-report "^3.0.0" -jackspeak@^3.1.2, "jackspeak@npm:@gitlab/noop@1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@gitlab/noop/-/noop-1.0.1.tgz#71a831146ee02732b4a61d2d3c11204564753454" - integrity sha512-s++4wjMYeDvBp9IO59DBrWjy8SE/gFkjTDO5ck2W0S6Vv7OlqgErwL7pHngAnrSmTJAzyUG8wHGqo0ViS4jn5Q== - jed@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/jed/-/jed-1.1.1.tgz#7a549bbd9ffe1585b0cd0a191e203055bee574b4"