diff --git a/.rubocop_todo/gitlab/bounded_contexts.yml b/.rubocop_todo/gitlab/bounded_contexts.yml
index 5c7d8b5247d848b87a2735cd40bf826a44e91e8d..db6973711f991fca7b5ac330d473367f49424a96 100644
--- a/.rubocop_todo/gitlab/bounded_contexts.yml
+++ b/.rubocop_todo/gitlab/bounded_contexts.yml
@@ -995,7 +995,6 @@ Gitlab/BoundedContexts:
- 'app/models/generic_commit_status.rb'
- 'app/models/gpg_key.rb'
- 'app/models/gpg_key_subkey.rb'
- - 'app/models/grafana_integration.rb'
- 'app/models/group.rb'
- 'app/models/group/crm_settings.rb'
- 'app/models/group_custom_attribute.rb'
@@ -1274,7 +1273,6 @@ Gitlab/BoundedContexts:
- 'app/policies/event_policy.rb'
- 'app/policies/external_issue_policy.rb'
- 'app/policies/global_policy.rb'
- - 'app/policies/grafana_integration_policy.rb'
- 'app/policies/group_deploy_key_policy.rb'
- 'app/policies/group_deploy_keys_group_policy.rb'
- 'app/policies/group_group_link_policy.rb'
@@ -3853,9 +3851,6 @@ Gitlab/BoundedContexts:
- 'lib/gitlab_settings/settings.rb'
- 'lib/google_api/auth.rb'
- 'lib/google_api/cloud_platform/client.rb'
- - 'lib/grafana/client.rb'
- - 'lib/grafana/time_window.rb'
- - 'lib/grafana/validator.rb'
- 'lib/initializer_connections.rb'
- 'lib/json_web_token/hmac_token.rb'
- 'lib/json_web_token/rsa_token.rb'
diff --git a/.rubocop_todo/gitlab/namespaced_class.yml b/.rubocop_todo/gitlab/namespaced_class.yml
index 9737aacfae0fbae2d050b457b8b5cbdfb9e6f690..40efd2eee767a1f84a150c53d2381f8672eabfe0 100644
--- a/.rubocop_todo/gitlab/namespaced_class.yml
+++ b/.rubocop_todo/gitlab/namespaced_class.yml
@@ -162,7 +162,6 @@ Gitlab/NamespacedClass:
- 'app/models/generic_commit_status.rb'
- 'app/models/gpg_key.rb'
- 'app/models/gpg_key_subkey.rb'
- - 'app/models/grafana_integration.rb'
- 'app/models/group.rb'
- 'app/models/group_custom_attribute.rb'
- 'app/models/group_deletion_schedule.rb'
@@ -357,7 +356,6 @@ Gitlab/NamespacedClass:
- 'app/policies/environment_policy.rb'
- 'app/policies/external_issue_policy.rb'
- 'app/policies/global_policy.rb'
- - 'app/policies/grafana_integration_policy.rb'
- 'app/policies/group_deploy_key_policy.rb'
- 'app/policies/group_deploy_keys_group_policy.rb'
- 'app/policies/group_label_policy.rb'
diff --git a/.rubocop_todo/gitlab/rails/attr_encrypted.yml b/.rubocop_todo/gitlab/rails/attr_encrypted.yml
index f71caaf65d3eef404b39905e7e0c2210d9240487..0e308a739dc97eb67ed45980a222f1bcafdb4824 100644
--- a/.rubocop_todo/gitlab/rails/attr_encrypted.yml
+++ b/.rubocop_todo/gitlab/rails/attr_encrypted.yml
@@ -22,7 +22,6 @@ Gitlab/Rails/AttrEncrypted:
- 'app/models/concerns/packages/debian/distribution_key.rb'
- 'app/models/concerns/web_hooks/hook.rb'
- 'app/models/error_tracking/project_error_tracking_setting.rb'
- - 'app/models/grafana_integration.rb'
- 'app/models/incident_management/project_incident_management_setting.rb'
- 'app/models/integrations/issue_tracker_data.rb'
- 'app/models/integrations/jira_tracker_data.rb'
diff --git a/.rubocop_todo/gitlab/strong_memoize_attr.yml b/.rubocop_todo/gitlab/strong_memoize_attr.yml
index 6f4b560d379452f2b59249579140f6bdbf7e7053..74c6a058b41a8d6c7b263fe606b578cf8cce1841 100644
--- a/.rubocop_todo/gitlab/strong_memoize_attr.yml
+++ b/.rubocop_todo/gitlab/strong_memoize_attr.yml
@@ -545,7 +545,6 @@ Gitlab/StrongMemoizeAttr:
- 'lib/gitlab/wiki_pages/front_matter_parser.rb'
- 'lib/gitlab/x509/signature.rb'
- 'lib/gitlab/x509/tag.rb'
- - 'lib/grafana/time_window.rb'
- 'lib/object_storage/direct_upload.rb'
- 'lib/safe_zip/extract_params.rb'
- 'lib/sidebars/projects/menus/analytics_menu.rb'
diff --git a/.rubocop_todo/layout/line_end_string_concatenation_indentation.yml b/.rubocop_todo/layout/line_end_string_concatenation_indentation.yml
index 1f525038c70fb671550a343eb77e12389220dae3..ed03484e59feae3f58430d2a734046ed8cea47d0 100644
--- a/.rubocop_todo/layout/line_end_string_concatenation_indentation.yml
+++ b/.rubocop_todo/layout/line_end_string_concatenation_indentation.yml
@@ -565,7 +565,6 @@ Layout/LineEndStringConcatenationIndentation:
- 'spec/services/web_hook_service_spec.rb'
- 'spec/services/work_items/related_work_item_links/destroy_service_spec.rb'
- 'spec/support/database/prevent_cross_joins.rb'
- - 'spec/support/helpers/grafana_api_helpers.rb'
- 'spec/support/helpers/graphql/subscriptions/action_cable/mock_action_cable.rb'
- 'spec/support/helpers/graphql/subscriptions/action_cable/mock_gitlab_schema.rb'
- 'spec/support/helpers/redis_without_keys.rb'
diff --git a/.rubocop_todo/layout/line_length.yml b/.rubocop_todo/layout/line_length.yml
index 8d239f460305198cc2f4b6c84b0d1bbe63ee86e7..c02db93f82cc4cd64ddc459ad6fc9b72660fb635 100644
--- a/.rubocop_todo/layout/line_length.yml
+++ b/.rubocop_todo/layout/line_length.yml
@@ -3227,7 +3227,6 @@ Layout/LineLength:
- 'spec/lib/gitlab/x509/signature_spec.rb'
- 'spec/lib/gitlab_spec.rb'
- 'spec/lib/google_api/cloud_platform/client_spec.rb'
- - 'spec/lib/grafana/validator_spec.rb'
- 'spec/lib/kramdown/kramdown_spec.rb'
- 'spec/lib/kramdown/parser/atlassian_document_format_spec.rb'
- 'spec/lib/mattermost/command_spec.rb'
@@ -3316,7 +3315,6 @@ Layout/LineLength:
- 'spec/models/error_tracking/error_spec.rb'
- 'spec/models/event_spec.rb'
- 'spec/models/gpg_key_spec.rb'
- - 'spec/models/grafana_integration_spec.rb'
- 'spec/models/group_deploy_key_spec.rb'
- 'spec/models/group_spec.rb'
- 'spec/models/identity_spec.rb'
diff --git a/.rubocop_todo/lint/unused_method_argument.yml b/.rubocop_todo/lint/unused_method_argument.yml
index 2c4f839b8a5b8093995c7553c76bfe270056e279..16aedbd94c6d1e61214a970a265285cada1feceb 100644
--- a/.rubocop_todo/lint/unused_method_argument.yml
+++ b/.rubocop_todo/lint/unused_method_argument.yml
@@ -30,7 +30,6 @@ Lint/UnusedMethodArgument:
- 'app/graphql/resolvers/merge_request_resolver.rb'
- 'app/graphql/resolvers/project_resolver.rb'
- 'app/graphql/resolvers/projects/branch_rules_resolver.rb'
- - 'app/graphql/resolvers/projects/grafana_integration_resolver.rb'
- 'app/graphql/resolvers/release_milestones_resolver.rb'
- 'app/graphql/resolvers/users/group_count_resolver.rb'
- 'app/graphql/resolvers/users/participants_resolver.rb'
diff --git a/.rubocop_todo/rails/time_zone.yml b/.rubocop_todo/rails/time_zone.yml
index b7330788d73befa0de707ee50ddc0a48f470d4b3..6c11aca3d43589a336728e459c1ad0d2a7684e9c 100644
--- a/.rubocop_todo/rails/time_zone.yml
+++ b/.rubocop_todo/rails/time_zone.yml
@@ -30,7 +30,6 @@ Rails/TimeZone:
- 'lib/gitlab/loop_helpers.rb'
- 'lib/gitlab/prometheus_client.rb'
- 'lib/gitlab/task_helpers.rb'
- - 'lib/grafana/time_window.rb'
- 'lib/json_web_token/token.rb'
- 'lib/object_storage/direct_upload.rb'
- 'lib/tasks/gitlab/assets.rake'
@@ -70,6 +69,5 @@ Rails/TimeZone:
- 'spec/lib/gitlab/sidekiq_logging/json_formatter_spec.rb'
- 'spec/lib/gitlab/utils/json_size_estimator_spec.rb'
- 'spec/lib/gitlab/x509/signature_spec.rb'
- - 'spec/lib/grafana/time_window_spec.rb'
- 'spec/lib/json_web_token/hmac_token_spec.rb'
- 'spec/models/merge_request_diff_commit_spec.rb'
diff --git a/.rubocop_todo/rspec/be_eq.yml b/.rubocop_todo/rspec/be_eq.yml
index cf64309b4ca7108af0eb67450a8ce9d66b802710..c38611c34a861697be01b3fc0091b5587087407f 100644
--- a/.rubocop_todo/rspec/be_eq.yml
+++ b/.rubocop_todo/rspec/be_eq.yml
@@ -568,7 +568,6 @@ RSpec/BeEq:
- 'spec/graphql/resolvers/feature_flag_resolver_spec.rb'
- 'spec/graphql/resolvers/import/source_users_resolver_spec.rb'
- 'spec/graphql/resolvers/kas/agent_configurations_resolver_spec.rb'
- - 'spec/graphql/resolvers/projects/grafana_integration_resolver_spec.rb'
- 'spec/graphql/resolvers/repository_branch_names_resolver_spec.rb'
- 'spec/graphql/resolvers/snippets/blobs_resolver_spec.rb'
- 'spec/graphql/subscriptions/issuable_updated_spec.rb'
diff --git a/.rubocop_todo/rspec/context_wording.yml b/.rubocop_todo/rspec/context_wording.yml
index 77ebb45adff21bcb34468389ccac6525d9311d91..def479bfd027877c94a4f644e9ee25c174cd12c3 100644
--- a/.rubocop_todo/rspec/context_wording.yml
+++ b/.rubocop_todo/rspec/context_wording.yml
@@ -1909,7 +1909,6 @@ RSpec/ContextWording:
- 'spec/models/error_tracking/error_spec.rb'
- 'spec/models/event_spec.rb'
- 'spec/models/gpg_key_spec.rb'
- - 'spec/models/grafana_integration_spec.rb'
- 'spec/models/group_label_spec.rb'
- 'spec/models/group_spec.rb'
- 'spec/models/hooks/system_hook_spec.rb'
diff --git a/.rubocop_todo/rspec/example_without_description.yml b/.rubocop_todo/rspec/example_without_description.yml
index 8a0824e4f97df65d0721246580e6ab79d19ab0c7..f8afc318d88dea956646f9a7c996b76a2689995d 100644
--- a/.rubocop_todo/rspec/example_without_description.yml
+++ b/.rubocop_todo/rspec/example_without_description.yml
@@ -360,7 +360,6 @@ RSpec/ExampleWithoutDescription:
- 'spec/lib/gitlab/user_access_spec.rb'
- 'spec/lib/gitlab/utils/lazy_attributes_spec.rb'
- 'spec/lib/gitlab/wiki_pages/front_matter_parser_spec.rb'
- - 'spec/lib/grafana/client_spec.rb'
- 'spec/lib/json_web_token/rsa_token_spec.rb'
- 'spec/lib/release_highlights/validator/entry_spec.rb'
- 'spec/lib/sbom/package_url/decoder_spec.rb'
diff --git a/.rubocop_todo/rspec/feature_category.yml b/.rubocop_todo/rspec/feature_category.yml
index 2fc43bbda9af76793cd666d30056109c4323161d..1842cea83a5c7f3a3b4572822c69c407af45edfd 100644
--- a/.rubocop_todo/rspec/feature_category.yml
+++ b/.rubocop_todo/rspec/feature_category.yml
@@ -1391,7 +1391,6 @@ RSpec/FeatureCategory:
- 'spec/graphql/resolvers/project_packages_resolver_spec.rb'
- 'spec/graphql/resolvers/project_resolver_spec.rb'
- 'spec/graphql/resolvers/projects/fork_targets_resolver_spec.rb'
- - 'spec/graphql/resolvers/projects/grafana_integration_resolver_spec.rb'
- 'spec/graphql/resolvers/projects/services_resolver_spec.rb'
- 'spec/graphql/resolvers/projects/snippets_resolver_spec.rb'
- 'spec/graphql/resolvers/recent_boards_resolver_spec.rb'
@@ -2918,9 +2917,6 @@ RSpec/FeatureCategory:
- 'spec/lib/gitlab_edition_spec.rb'
- 'spec/lib/google_api/auth_spec.rb'
- 'spec/lib/google_api/cloud_platform/client_spec.rb'
- - 'spec/lib/grafana/client_spec.rb'
- - 'spec/lib/grafana/time_window_spec.rb'
- - 'spec/lib/grafana/validator_spec.rb'
- 'spec/lib/initializer_connections_spec.rb'
- 'spec/lib/json_web_token/hmac_token_spec.rb'
- 'spec/lib/json_web_token/token_spec.rb'
@@ -3138,7 +3134,6 @@ RSpec/FeatureCategory:
- 'spec/models/generic_commit_status_spec.rb'
- 'spec/models/gpg_key_spec.rb'
- 'spec/models/gpg_key_subkey_spec.rb'
- - 'spec/models/grafana_integration_spec.rb'
- 'spec/models/group_custom_attribute_spec.rb'
- 'spec/models/group_deploy_key_spec.rb'
- 'spec/models/group_deploy_keys_group_spec.rb'
diff --git a/.rubocop_todo/rspec/named_subject.yml b/.rubocop_todo/rspec/named_subject.yml
index 5e9f186cc6173cd320719c6f9a347eec75996d9d..940e16518791e2c457f2c859e228e43c7695e3c6 100644
--- a/.rubocop_todo/rspec/named_subject.yml
+++ b/.rubocop_todo/rspec/named_subject.yml
@@ -2155,8 +2155,6 @@ RSpec/NamedSubject:
- 'spec/lib/gitlab_spec.rb'
- 'spec/lib/google_api/auth_spec.rb'
- 'spec/lib/google_api/cloud_platform/client_spec.rb'
- - 'spec/lib/grafana/time_window_spec.rb'
- - 'spec/lib/grafana/validator_spec.rb'
- 'spec/lib/json_web_token/rsa_token_spec.rb'
- 'spec/lib/kramdown/kramdown_spec.rb'
- 'spec/lib/mattermost/client_spec.rb'
diff --git a/.rubocop_todo/style/guard_clause.yml b/.rubocop_todo/style/guard_clause.yml
index 903193da4906b7fc3a003bb95eb8632b2d2061b2..c32c03e01f071b372e73340944897b201aac6a69 100644
--- a/.rubocop_todo/style/guard_clause.yml
+++ b/.rubocop_todo/style/guard_clause.yml
@@ -73,7 +73,6 @@ Style/GuardClause:
- 'app/models/environment.rb'
- 'app/models/error_tracking/project_error_tracking_setting.rb'
- 'app/models/generic_commit_status.rb'
- - 'app/models/grafana_integration.rb'
- 'app/models/integrations/datadog.rb'
- 'app/models/internal_id.rb'
- 'app/models/issue.rb'
diff --git a/.rubocop_todo/style/if_unless_modifier.yml b/.rubocop_todo/style/if_unless_modifier.yml
index 6690357a514584f4274b3e7fc49518e305faa360..665977dfa43313ffb3a3fb112a22bc740b9f3934 100644
--- a/.rubocop_todo/style/if_unless_modifier.yml
+++ b/.rubocop_todo/style/if_unless_modifier.yml
@@ -29,7 +29,6 @@ Style/IfUnlessModifier:
- 'app/models/environment.rb'
- 'app/models/error_tracking/project_error_tracking_setting.rb'
- 'app/models/generic_commit_status.rb'
- - 'app/models/grafana_integration.rb'
- 'app/models/integrations/datadog.rb'
- 'app/models/issue.rb'
- 'app/models/issue_email_participant.rb'
diff --git a/.rubocop_todo/style/string_concatenation.yml b/.rubocop_todo/style/string_concatenation.yml
index 10dc434cb643fd1408c9213521c90458a289d058..547fae8bb7cd9b6da61af293deaef70963183f49 100644
--- a/.rubocop_todo/style/string_concatenation.yml
+++ b/.rubocop_todo/style/string_concatenation.yml
@@ -175,7 +175,6 @@ Style/StringConcatenation:
- 'spec/models/concerns/pg_full_text_searchable_spec.rb'
- 'spec/models/container_repository_spec.rb'
- 'spec/models/custom_emoji_spec.rb'
- - 'spec/models/grafana_integration_spec.rb'
- 'spec/models/integrations/campfire_spec.rb'
- 'spec/models/integrations/chat_message/pipeline_message_spec.rb'
- 'spec/models/integrations/chat_message/push_message_spec.rb'
diff --git a/app/graphql/resolvers/projects/grafana_integration_resolver.rb b/app/graphql/resolvers/projects/grafana_integration_resolver.rb
deleted file mode 100644
index 030139734ed18d2eab57b2aa37f808d648484816..0000000000000000000000000000000000000000
--- a/app/graphql/resolvers/projects/grafana_integration_resolver.rb
+++ /dev/null
@@ -1,17 +0,0 @@
-# frozen_string_literal: true
-
-module Resolvers
- module Projects
- class GrafanaIntegrationResolver < BaseResolver
- type Types::GrafanaIntegrationType, null: true
-
- alias_method :project, :object
-
- def resolve(**args)
- return unless project.is_a? Project
-
- project.grafana_integration
- end
- end
- end
-end
diff --git a/app/graphql/types/grafana_integration_type.rb b/app/graphql/types/grafana_integration_type.rb
index 8426506d95423f92d05f0f329c483002fb1b991b..eb77f22486bb23efe365c5fef64717757cf2241c 100644
--- a/app/graphql/types/grafana_integration_type.rb
+++ b/app/graphql/types/grafana_integration_type.rb
@@ -1,5 +1,7 @@
# frozen_string_literal: true
+# Deprecated:
+# Remove alongside query during any major release.
module Types
class GrafanaIntegrationType < ::Types::BaseObject
graphql_name 'GrafanaIntegration'
diff --git a/app/graphql/types/project_type.rb b/app/graphql/types/project_type.rb
index a46dd747f58de5b7f71ffe8f32e5709de6684c8a..c2cbcd1bca6cb1e5205561488d3c807126fdfbd9 100644
--- a/app/graphql/types/project_type.rb
+++ b/app/graphql/types/project_type.rb
@@ -478,7 +478,10 @@ def self.authorization_scopes
field :grafana_integration, Types::GrafanaIntegrationType,
null: true,
description: 'Grafana integration details for the project.',
- resolver: Resolvers::Projects::GrafanaIntegrationResolver
+ deprecated: {
+ reason: 'Feature was removed in 16.0. Always returns null',
+ milestone: '18.3'
+ }
field :snippets, Types::SnippetType.connection_type,
null: true,
@@ -1075,6 +1078,8 @@ def permanent_deletion_date
permanent_deletion_date_formatted(project) || permanent_deletion_date_formatted
end
+ def grafana_integration; end
+
private
def project
diff --git a/app/models/grafana_integration.rb b/app/models/grafana_integration.rb
deleted file mode 100644
index be157065a44d3f488d7785c45461faf26f299ceb..0000000000000000000000000000000000000000
--- a/app/models/grafana_integration.rb
+++ /dev/null
@@ -1,62 +0,0 @@
-# frozen_string_literal: true
-
-class GrafanaIntegration < ApplicationRecord
- include Gitlab::EncryptedAttribute
-
- belongs_to :project
-
- attr_encrypted :token,
- mode: :per_attribute_iv,
- algorithm: 'aes-256-gcm',
- key: :db_key_base_32
-
- before_validation :check_token_changes
-
- validates :grafana_url,
- length: { maximum: 1024 },
- addressable_url: { enforce_sanitization: true, ascii_only: true }
-
- validates :encrypted_token, :project, presence: true
-
- validates :enabled, inclusion: { in: [true, false] }
-
- before_validation :reset_token
-
- scope :enabled, -> { where(enabled: true) }
-
- def client
- return unless enabled?
-
- @client ||= ::Grafana::Client.new(api_url: grafana_url.chomp('/'), token: token)
- end
-
- def masked_token
- mask(encrypted_token)
- end
-
- def masked_token_was
- mask(encrypted_token_was)
- end
-
- private
-
- def reset_token
- if grafana_url_changed? && !encrypted_token_changed?
- self.token = nil
- end
- end
-
- def token
- attr_encrypted_decrypt(:token, encrypted_token)
- end
-
- def check_token_changes
- return unless [encrypted_token_was, masked_token_was].include?(token)
-
- clear_attribute_changes [:token, :encrypted_token, :encrypted_token_iv]
- end
-
- def mask(token)
- token&.squish&.gsub(/./, '*')
- end
-end
diff --git a/app/models/project.rb b/app/models/project.rb
index 096446555d0583e2eec5f907eb8b0855af105b19..c4999976abf0e55e44b001ca924421ba5468cf5a 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -312,7 +312,6 @@ def self.integration_association_name(name)
has_one :project_repository, inverse_of: :project
has_one :incident_management_setting, inverse_of: :project, class_name: 'IncidentManagement::ProjectIncidentManagementSetting'
has_one :error_tracking_setting, inverse_of: :project, class_name: 'ErrorTracking::ProjectErrorTrackingSetting'
- has_one :grafana_integration, inverse_of: :project
has_one :project_setting, inverse_of: :project, autosave: true
has_one :alerting_setting, inverse_of: :project, class_name: 'Alerting::ProjectAlertingSetting'
has_one :service_desk_setting, class_name: 'ServiceDeskSetting'
@@ -534,7 +533,6 @@ def with_developer_access
accepts_nested_attributes_for :incident_management_setting, update_only: true
accepts_nested_attributes_for :error_tracking_setting, update_only: true
- accepts_nested_attributes_for :grafana_integration, update_only: true, allow_destroy: true
accepts_nested_attributes_for :prometheus_integration, update_only: true
accepts_nested_attributes_for :alerting_setting, update_only: true
diff --git a/app/policies/grafana_integration_policy.rb b/app/policies/grafana_integration_policy.rb
deleted file mode 100644
index 529a1fe04936bcc0b4e34c23aebb98ed7f6b3fc5..0000000000000000000000000000000000000000
--- a/app/policies/grafana_integration_policy.rb
+++ /dev/null
@@ -1,5 +0,0 @@
-# frozen_string_literal: true
-
-class GrafanaIntegrationPolicy < BasePolicy
- delegate { @subject.project }
-end
diff --git a/app/policies/project_policy.rb b/app/policies/project_policy.rb
index f6f244c62aa2903dccb8c1230c41031748c64621..618e6bed0dba73dbfe62026034c8d56c4ac8c5f7 100644
--- a/app/policies/project_policy.rb
+++ b/app/policies/project_policy.rb
@@ -436,8 +436,6 @@ class ProjectPolicy < BasePolicy
rule { guest & can?(:download_code) }.enable :build_download_code
rule { guest & can?(:read_container_image) }.enable :build_read_container_image
- rule { guest & ~public_project }.enable :read_grafana
-
rule { can?(:reporter_access) }.policy do
enable :admin_issue_board
enable :read_code
@@ -471,7 +469,6 @@ class ProjectPolicy < BasePolicy
enable :read_ci_cd_analytics
enable :read_external_emails
enable :read_internal_note
- enable :read_grafana
enable :export_work_items
enable :create_design
enable :update_design
diff --git a/db/docs/grafana_integrations.yml b/db/docs/deleted_tables/grafana_integrations.yml
similarity index 74%
rename from db/docs/grafana_integrations.yml
rename to db/docs/deleted_tables/grafana_integrations.yml
index b3bc8f35da26d9bc2bbfd4978760369fe4f112dc..6a1e31aa6cc40effe7ae3ff63def273f00346e0c 100644
--- a/db/docs/grafana_integrations.yml
+++ b/db/docs/deleted_tables/grafana_integrations.yml
@@ -11,3 +11,5 @@ gitlab_schema: gitlab_main_cell
sharding_key:
project_id: projects
table_size: small
+removed_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/199243
+removed_in_milestone: '18.3'
diff --git a/db/post_migrate/20250725071156_remove_grafana_integrations_fk_project_id.rb b/db/post_migrate/20250725071156_remove_grafana_integrations_fk_project_id.rb
new file mode 100644
index 0000000000000000000000000000000000000000..0046419c8ecca175f33518af548bc2dc61d37053
--- /dev/null
+++ b/db/post_migrate/20250725071156_remove_grafana_integrations_fk_project_id.rb
@@ -0,0 +1,29 @@
+# frozen_string_literal: true
+
+class RemoveGrafanaIntegrationsFkProjectId < Gitlab::Database::Migration[2.3]
+ milestone '18.3'
+ disable_ddl_transaction!
+
+ CONSTRAINT_NAME = 'fk_rails_18d0e2b564'
+
+ def up
+ with_lock_retries do
+ remove_foreign_key_if_exists(
+ :grafana_integrations,
+ column: :project_id,
+ on_delete: :cascade,
+ name: CONSTRAINT_NAME
+ )
+ end
+ end
+
+ def down
+ add_concurrent_foreign_key(
+ :grafana_integrations,
+ :projects,
+ column: :project_id,
+ on_delete: :cascade,
+ name: CONSTRAINT_NAME
+ )
+ end
+end
diff --git a/db/post_migrate/20250725071302_remove_grafana_integrations.rb b/db/post_migrate/20250725071302_remove_grafana_integrations.rb
new file mode 100644
index 0000000000000000000000000000000000000000..5f3800d5256f9c94560f90ced504c87212a7de1e
--- /dev/null
+++ b/db/post_migrate/20250725071302_remove_grafana_integrations.rb
@@ -0,0 +1,41 @@
+# frozen_string_literal: true
+
+class RemoveGrafanaIntegrations < Gitlab::Database::Migration[2.3]
+ milestone '18.3'
+
+ def up
+ drop_table :grafana_integrations
+ end
+
+ def down
+ execute <<~SQL
+ CREATE TABLE grafana_integrations (
+ id bigint NOT NULL,
+ project_id bigint NOT NULL,
+ created_at timestamp with time zone NOT NULL,
+ updated_at timestamp with time zone NOT NULL,
+ encrypted_token character varying(255) NOT NULL,
+ encrypted_token_iv character varying(255) NOT NULL,
+ grafana_url character varying(1024) NOT NULL,
+ enabled boolean DEFAULT false NOT NULL
+ );
+
+ CREATE SEQUENCE grafana_integrations_id_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+ ALTER SEQUENCE grafana_integrations_id_seq OWNED BY grafana_integrations.id;
+
+ ALTER TABLE ONLY grafana_integrations ALTER COLUMN id SET DEFAULT nextval('grafana_integrations_id_seq'::regclass);
+
+ ALTER TABLE ONLY grafana_integrations ADD CONSTRAINT grafana_integrations_pkey PRIMARY KEY (id);
+
+ CREATE INDEX index_grafana_integrations_on_enabled ON grafana_integrations USING btree (enabled) WHERE (enabled IS TRUE);
+
+ CREATE INDEX index_grafana_integrations_on_project_id ON grafana_integrations USING btree (project_id);
+ SQL
+ end
+end
diff --git a/db/schema_migrations/20250725071156 b/db/schema_migrations/20250725071156
new file mode 100644
index 0000000000000000000000000000000000000000..d31eb24786e0c063b65fca448e4dc6d5076e63bd
--- /dev/null
+++ b/db/schema_migrations/20250725071156
@@ -0,0 +1 @@
+96431864166b88fa736d6730fc3429c696084b32f64db695ed22474f02466ba0
\ No newline at end of file
diff --git a/db/schema_migrations/20250725071302 b/db/schema_migrations/20250725071302
new file mode 100644
index 0000000000000000000000000000000000000000..dbf08c4f8a43815a538da45c56a72071b6e27f95
--- /dev/null
+++ b/db/schema_migrations/20250725071302
@@ -0,0 +1 @@
+aa36dc97300cb6cbc57d12367f40fa22046920a248829b007ff6583936cd62ff
\ No newline at end of file
diff --git a/db/structure.sql b/db/structure.sql
index a87a45b39b8286acf840800b8ebdbe0092fa7dbd..efe9ce9036523961e27ea96c1253de1e1f55c227 100644
--- a/db/structure.sql
+++ b/db/structure.sql
@@ -15369,26 +15369,6 @@ CREATE SEQUENCE gpg_signatures_id_seq
ALTER SEQUENCE gpg_signatures_id_seq OWNED BY gpg_signatures.id;
-CREATE TABLE grafana_integrations (
- id bigint NOT NULL,
- project_id bigint NOT NULL,
- created_at timestamp with time zone NOT NULL,
- updated_at timestamp with time zone NOT NULL,
- encrypted_token character varying(255) NOT NULL,
- encrypted_token_iv character varying(255) NOT NULL,
- grafana_url character varying(1024) NOT NULL,
- enabled boolean DEFAULT false NOT NULL
-);
-
-CREATE SEQUENCE grafana_integrations_id_seq
- START WITH 1
- INCREMENT BY 1
- NO MINVALUE
- NO MAXVALUE
- CACHE 1;
-
-ALTER SEQUENCE grafana_integrations_id_seq OWNED BY grafana_integrations.id;
-
CREATE TABLE group_crm_settings (
group_id bigint NOT NULL,
created_at timestamp with time zone NOT NULL,
@@ -28130,8 +28110,6 @@ ALTER TABLE ONLY gpg_keys ALTER COLUMN id SET DEFAULT nextval('gpg_keys_id_seq':
ALTER TABLE ONLY gpg_signatures ALTER COLUMN id SET DEFAULT nextval('gpg_signatures_id_seq'::regclass);
-ALTER TABLE ONLY grafana_integrations ALTER COLUMN id SET DEFAULT nextval('grafana_integrations_id_seq'::regclass);
-
ALTER TABLE ONLY group_crm_settings ALTER COLUMN group_id SET DEFAULT nextval('group_crm_settings_group_id_seq'::regclass);
ALTER TABLE ONLY group_custom_attributes ALTER COLUMN id SET DEFAULT nextval('group_custom_attributes_id_seq'::regclass);
@@ -30650,9 +30628,6 @@ ALTER TABLE ONLY gpg_keys
ALTER TABLE ONLY gpg_signatures
ADD CONSTRAINT gpg_signatures_pkey PRIMARY KEY (id);
-ALTER TABLE ONLY grafana_integrations
- ADD CONSTRAINT grafana_integrations_pkey PRIMARY KEY (id);
-
ALTER TABLE ONLY group_audit_events
ADD CONSTRAINT group_audit_events_pkey PRIMARY KEY (id, created_at);
@@ -36101,10 +36076,6 @@ CREATE INDEX index_gpg_signatures_on_gpg_key_subkey_id ON gpg_signatures USING b
CREATE INDEX index_gpg_signatures_on_project_id ON gpg_signatures USING btree (project_id);
-CREATE INDEX index_grafana_integrations_on_enabled ON grafana_integrations USING btree (enabled) WHERE (enabled IS TRUE);
-
-CREATE INDEX index_grafana_integrations_on_project_id ON grafana_integrations USING btree (project_id);
-
CREATE INDEX index_group_crm_settings_on_group_id ON group_crm_settings USING btree (group_id);
CREATE INDEX index_group_crm_settings_on_source_group_id ON group_crm_settings USING btree (source_group_id);
@@ -45282,9 +45253,6 @@ ALTER TABLE ONLY audit_events_streaming_http_group_namespace_filters
ALTER TABLE ONLY cluster_providers_aws
ADD CONSTRAINT fk_rails_18983d9ea4 FOREIGN KEY (cluster_id) REFERENCES clusters(id) ON DELETE CASCADE;
-ALTER TABLE ONLY grafana_integrations
- ADD CONSTRAINT fk_rails_18d0e2b564 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
-
ALTER TABLE ONLY queries_service_pings
ADD CONSTRAINT fk_rails_18dedc7d8e FOREIGN KEY (organization_id) REFERENCES organizations(id) ON DELETE CASCADE;
diff --git a/doc/api/graphql/reference/_index.md b/doc/api/graphql/reference/_index.md
index b95df0efde29da0ea532e3bb23a2eea85924b3e0..d0502161d9490f120bd182603f079aa0d9547903 100644
--- a/doc/api/graphql/reference/_index.md
+++ b/doc/api/graphql/reference/_index.md
@@ -37292,7 +37292,7 @@ Project-level settings for product analytics provider.
| `forksCount` | [`Int!`](#int) | Number of times the project has been forked. |
| `fullPath` | [`ID!`](#id) | Full path of the project. |
| `googleCloudArtifactRegistryRepository` {{< icon name="warning-solid" >}} | [`GoogleCloudArtifactRegistryRepository`](#googlecloudartifactregistryrepository) | **Introduced** in GitLab 16.10. **Status**: Experiment. Google Artifact Registry repository. Returns `null` if the GitLab instance is not a SaaS instance. |
-| `grafanaIntegration` | [`GrafanaIntegration`](#grafanaintegration) | Grafana integration details for the project. |
+| `grafanaIntegration` {{< icon name="warning-solid" >}} | [`GrafanaIntegration`](#grafanaintegration) | **Deprecated** in GitLab 18.3. Feature was removed in 16.0. Always returns null. |
| `group` | [`Group`](#group) | Group of the project. |
| `hasJiraVulnerabilityIssueCreationEnabled` | [`Boolean!`](#boolean) | Indicates whether Jira issue creation from vulnerabilities is enabled. |
| `httpUrlToRepo` | [`String`](#string) | URL to connect to the project via HTTPS. |
diff --git a/lib/grafana/client.rb b/lib/grafana/client.rb
deleted file mode 100644
index 44808f8bb5a54e22e0199f42de4ba28b11305a33..0000000000000000000000000000000000000000
--- a/lib/grafana/client.rb
+++ /dev/null
@@ -1,79 +0,0 @@
-# frozen_string_literal: true
-
-module Grafana
- class Client
- Error = Class.new(StandardError)
-
- # @param api_url [String] Base URL of the Grafana instance
- # @param token [String] Admin-level API token for instance
- def initialize(api_url:, token:)
- @api_url = api_url
- @token = token
- end
-
- # @param uid [String] Unique identifier for a Grafana dashboard
- def get_dashboard(uid:)
- http_get("#{@api_url}/api/dashboards/uid/#{uid}")
- end
-
- # @param name [String] Unique identifier for a Grafana datasource
- def get_datasource(name:)
- # CGI#escape formats strings such that the Grafana endpoint
- # will not recognize the dashboard name. Prefer Addressable::URI#encode_component.
- http_get("#{@api_url}/api/datasources/name/#{Addressable::URI.encode_component(name)}")
- end
-
- # @param datasource_id [String] Grafana ID for the datasource
- # @param proxy_path [String] Path to proxy - ex) 'api/v1/query_range'
- def proxy_datasource(datasource_id:, proxy_path:, query: {})
- http_get("#{@api_url}/api/datasources/proxy/#{datasource_id}/#{proxy_path}", query: query)
- end
-
- private
-
- def http_get(url, params = {})
- response = handle_request_exceptions do
- Gitlab::HTTP.get(url, **request_params.merge(params))
- end
-
- handle_response(response)
- end
-
- def request_params
- {
- headers: {
- 'Authorization' => "Bearer #{@token}",
- 'Accept' => 'application/json',
- 'Content-Type' => 'application/json'
- },
- follow_redirects: false
- }
- end
-
- def handle_request_exceptions
- yield
- rescue Gitlab::HTTP::Error
- raise_error 'Error when connecting to Grafana'
- rescue Net::OpenTimeout
- raise_error 'Connection to Grafana timed out'
- rescue SocketError
- raise_error 'Received SocketError when trying to connect to Grafana'
- rescue OpenSSL::SSL::SSLError
- raise_error 'Grafana returned invalid SSL data'
- rescue Errno::ECONNREFUSED
- raise_error 'Connection refused'
- rescue StandardError => e
- raise_error "Grafana request failed due to #{e.class}"
- end
-
- def handle_response(response)
- return response if response.code == 200
-
- raise_error "Grafana response status code: #{response.code}, Message: #{response.body}"
- end
-
- def raise_error(message)
- raise Client::Error, message
- end
- end
-end
diff --git a/lib/grafana/time_window.rb b/lib/grafana/time_window.rb
deleted file mode 100644
index 6cc757d77c553a92d20b46861000d32ae730b8d9..0000000000000000000000000000000000000000
--- a/lib/grafana/time_window.rb
+++ /dev/null
@@ -1,130 +0,0 @@
-# frozen_string_literal: true
-
-module Grafana
- # Allows for easy formatting and manipulations of timestamps
- # coming from a Grafana url
- class TimeWindow
- include ::Gitlab::Utils::StrongMemoize
-
- def initialize(from, to)
- @from = from
- @to = to
- end
-
- def formatted
- {
- start: window[:from].formatted,
- end: window[:to].formatted
- }
- end
-
- def in_milliseconds
- window.transform_values(&:to_ms)
- end
-
- private
-
- def window
- strong_memoize(:window) do
- specified_window
- rescue Timestamp::Error
- default_window
- end
- end
-
- def specified_window
- RangeWithDefaults.new(
- from: Timestamp.from_ms_since_epoch(@from),
- to: Timestamp.from_ms_since_epoch(@to)
- ).to_hash
- end
-
- def default_window
- RangeWithDefaults.new.to_hash
- end
- end
-
- # For incomplete time ranges, adds default parameters to
- # achieve a complete range. If both full range is provided,
- # range will be returned.
- class RangeWithDefaults
- DEFAULT_RANGE = 8.hours
-
- # @param from [Grafana::Timestamp, nil] Start of the expected range
- # @param to [Grafana::Timestamp, nil] End of the expected range
- def initialize(from: nil, to: nil)
- @from = from
- @to = to
-
- apply_defaults!
- end
-
- def to_hash
- { from: @from, to: @to }.compact
- end
-
- private
-
- def apply_defaults!
- @to ||= @from ? relative_end : Timestamp.new(Time.now)
- @from ||= relative_start
- end
-
- def relative_start
- Timestamp.new(DEFAULT_RANGE.before(@to.time))
- end
-
- def relative_end
- Timestamp.new(DEFAULT_RANGE.since(@from.time))
- end
- end
-
- # Offers a consistent API for timestamps originating from
- # Grafana or other sources, allowing for formatting of timestamps
- # as consumed by Grafana-related utilities
- class Timestamp
- Error = Class.new(StandardError)
-
- attr_accessor :time
-
- # @param timestamp [Time]
- def initialize(time)
- @time = time
- end
-
- # Formats a timestamp from Grafana for compatibility with
- # parsing in JS via `new Date(timestamp)`
- def formatted
- time.utc.strftime('%FT%TZ')
- end
-
- # Converts to milliseconds since epoch
- def to_ms
- time.to_i * 1000
- end
-
- class << self
- # @param time [String] Representing milliseconds since epoch.
- # This is what JS "decided" unix is.
- def from_ms_since_epoch(time)
- return if time.nil?
-
- raise Error, 'Expected milliseconds since epoch' unless ms_since_epoch?(time)
-
- new(cast_ms_to_time(time))
- end
-
- private
-
- def cast_ms_to_time(time)
- Time.at(time.to_i / 1000.0)
- end
-
- def ms_since_epoch?(time)
- ms = time.to_i
-
- ms.to_s == time && ms.bit_length < 64
- end
- end
- end
-end
diff --git a/lib/grafana/validator.rb b/lib/grafana/validator.rb
deleted file mode 100644
index a6386a3939489177eeb98001846123d359c8553d..0000000000000000000000000000000000000000
--- a/lib/grafana/validator.rb
+++ /dev/null
@@ -1,95 +0,0 @@
-# frozen_string_literal: true
-
-# Performs checks on whether resources from Grafana can be handled
-# We have certain restrictions on which formats we accept.
-# Some are technical requirements, others are simplifications.
-module Grafana
- class Validator
- Error = Class.new(StandardError)
-
- attr_reader :grafana_dashboard, :datasource, :panel, :query_params
-
- UNSUPPORTED_GRAFANA_GLOBAL_VARS = %w[
- $__interval_ms
- $__timeFilter
- $__name
- $timeFilter
- $interval
- ].freeze
-
- def initialize(grafana_dashboard, datasource, panel, query_params)
- @grafana_dashboard = grafana_dashboard
- @datasource = datasource
- @panel = panel
- @query_params = query_params
- end
-
- def validate!
- validate_query_params!
- validate_panel_type!
- validate_variable_definitions!
- validate_global_variables!
- validate_datasource! if datasource
- end
-
- def valid?
- validate!
-
- true
- rescue ::Grafana::Validator::Error
- false
- end
-
- private
-
- def validate_query_params!
- return if [:from, :to].all? { |param| query_params.include?(param) }
-
- raise_error 'Grafana query parameters must include from and to.'
- end
-
- # We may choose to support other panel types in future.
- def validate_panel_type!
- return if panel && panel[:type] == 'graph' && panel[:lines]
-
- raise_error 'Panel type must be a line graph.'
- end
-
- # We must require variable definitions to create valid prometheus queries.
- def validate_variable_definitions!
- return unless grafana_dashboard[:dashboard][:templating]
-
- return if grafana_dashboard[:dashboard][:templating][:list].all? do |variable|
- query_params[:"var-#{variable[:name]}"].present?
- end
-
- raise_error 'All Grafana variables must be defined in the query parameters.'
- end
-
- # We may choose to support further Grafana variables in future.
- def validate_global_variables!
- return unless panel_contains_unsupported_vars?
-
- raise_error "Prometheus must not include #{UNSUPPORTED_GRAFANA_GLOBAL_VARS}"
- end
-
- # We may choose to support additional datasources in future.
- def validate_datasource!
- return if datasource[:access] == 'proxy' && datasource[:type] == 'prometheus'
-
- raise_error 'Only Prometheus datasources with proxy access in Grafana are supported.'
- end
-
- def panel_contains_unsupported_vars?
- panel[:targets].any? do |target|
- UNSUPPORTED_GRAFANA_GLOBAL_VARS.any? do |variable|
- target[:expr].include?(variable)
- end
- end
- end
-
- def raise_error(message)
- raise Validator::Error, message
- end
- end
-end
diff --git a/spec/benchmarks/banzai_benchmark.rb b/spec/benchmarks/banzai_benchmark.rb
index f46c9ac7e8f3e34a9ae97c8e46f1c43a3c8a7d99..095ee308568db794ace084a0b360409022d437d3 100644
--- a/spec/benchmarks/banzai_benchmark.rb
+++ b/spec/benchmarks/banzai_benchmark.rb
@@ -34,7 +34,6 @@
let_it_be(:wiki_page) { feature.wiki_page }
let_it_be(:markdown_text) { feature.raw_markdown }
let_it_be(:glfm_engine) { Banzai::Filter::MarkdownFilter::GLFM_ENGINE }
- let_it_be(:grafana_integration) { create(:grafana_integration, project: project) }
let_it_be(:default_context) do
{
project: project,
diff --git a/spec/factories/grafana_integrations.rb b/spec/factories/grafana_integrations.rb
deleted file mode 100644
index a647ef8d2ecc83d4b13c0ee993497e5a6bef00f0..0000000000000000000000000000000000000000
--- a/spec/factories/grafana_integrations.rb
+++ /dev/null
@@ -1,10 +0,0 @@
-# frozen_string_literal: true
-
-FactoryBot.define do
- factory :grafana_integration, class: 'GrafanaIntegration' do
- project
- grafana_url { 'https://grafana.example.com' }
- token { SecureRandom.hex(10) }
- enabled { true }
- end
-end
diff --git a/spec/factories/usage_data.rb b/spec/factories/usage_data.rb
index f99217b0b557b5a8c552a020de3ed6b282282049..a8ec96c6bb121effafb9176607bdcd289354b5bc 100644
--- a/spec/factories/usage_data.rb
+++ b/spec/factories/usage_data.rb
@@ -77,10 +77,6 @@
# Cluster Integrations
create(:clusters_integrations_prometheus, cluster: gcp_cluster)
- create(:grafana_integration, project: projects[0], enabled: true)
- create(:grafana_integration, project: projects[1], enabled: true)
- create(:grafana_integration, project: projects[2], enabled: false)
-
create(:generic_package, project: projects[0], created_at: 3.days.ago)
create(:generic_package, project: projects[0], created_at: 3.days.ago)
create(:generic_package, project: projects[1], created_at: 3.days.ago)
diff --git a/spec/fixtures/grafana/dashboard_response.json b/spec/fixtures/grafana/dashboard_response.json
deleted file mode 100644
index c0dd77e2fdcbd6e5590ddccb15b8b4c6ea638ba3..0000000000000000000000000000000000000000
--- a/spec/fixtures/grafana/dashboard_response.json
+++ /dev/null
@@ -1,764 +0,0 @@
-{
- "meta": {
- "type": "db",
- "canSave": true,
- "canEdit": true,
- "canAdmin": true,
- "canStar": true,
- "slug": "gitlab-omnibus-redis",
- "url": "/-/grafana/d/XDaNK6amz/gitlab-omnibus-redis",
- "expires": "0001-01-01T00:00:00Z",
- "created": "2019-10-04T13:43:20Z",
- "updated": "2019-10-04T13:43:20Z",
- "updatedBy": "Anonymous",
- "createdBy": "Anonymous",
- "version": 1,
- "hasAcl": false,
- "isFolder": false,
- "folderId": 1,
- "folderTitle": "GitLab Omnibus",
- "folderUrl": "/-/grafana/dashboards/f/l2EpNh2Zk/gitlab-omnibus",
- "provisioned": true,
- "provisionedExternalId": "redis.json"
- },
- "dashboard": {
- "annotations": {
- "list": [
- {
- "builtIn": 1,
- "datasource": "-- Grafana --",
- "enable": true,
- "hide": true,
- "iconColor": "rgba(0, 211, 255, 1)",
- "name": "Annotations \u0026 Alerts",
- "type": "dashboard"
- }
- ]
- },
- "description": "GitLab Omnibus dashboard for Redis servers",
- "editable": true,
- "gnetId": 763,
- "graphTooltip": 0,
- "id": 3,
- "iteration": 1556027798221,
- "links": [],
- "panels": [
- {
- "cacheTimeout": null,
- "colorBackground": false,
- "colorValue": false,
- "colors": ["rgba(245, 54, 54, 0.9)", "rgba(237, 129, 40, 0.89)", "rgba(50, 172, 45, 0.97)"],
- "datasource": "GitLab Omnibus",
- "decimals": 0,
- "editable": true,
- "error": false,
- "format": "dtdurations",
- "gauge": {
- "maxValue": 100,
- "minValue": 0,
- "show": false,
- "thresholdLabels": false,
- "thresholdMarkers": true
- },
- "gridPos": { "h": 3, "w": 4, "x": 0, "y": 0 },
- "id": 9,
- "interval": null,
- "isNew": true,
- "links": [],
- "mappingType": 1,
- "mappingTypes": [
- { "name": "value to text", "value": 1 },
- { "name": "range to text", "value": 2 }
- ],
- "maxDataPoints": 100,
- "nullPointMode": "connected",
- "nullText": null,
- "postfix": "",
- "postfixFontSize": "50%",
- "prefix": "",
- "prefixFontSize": "50%",
- "rangeMaps": [{ "from": "null", "text": "N/A", "to": "null" }],
- "sparkline": {
- "fillColor": "rgba(31, 118, 189, 0.18)",
- "full": false,
- "lineColor": "rgb(31, 120, 193)",
- "show": false
- },
- "tableColumn": "addr",
- "targets": [
- {
- "expr": "avg(time() - redis_start_time_seconds{instance=~\"$instance\"})",
- "format": "time_series",
- "instant": true,
- "interval": "",
- "intervalFactor": 2,
- "legendFormat": "",
- "metric": "",
- "refId": "A",
- "step": 1800
- }
- ],
- "thresholds": "",
- "title": "Uptime",
- "type": "singlestat",
- "valueFontSize": "70%",
- "valueMaps": [{ "op": "=", "text": "N/A", "value": "null" }],
- "valueName": "current"
- },
- {
- "cacheTimeout": null,
- "colorBackground": false,
- "colorValue": false,
- "colors": ["rgba(245, 54, 54, 0.9)", "rgba(237, 129, 40, 0.89)", "rgba(50, 172, 45, 0.97)"],
- "datasource": "GitLab Omnibus",
- "decimals": 0,
- "editable": true,
- "error": false,
- "format": "none",
- "gauge": {
- "maxValue": 100,
- "minValue": 0,
- "show": false,
- "thresholdLabels": false,
- "thresholdMarkers": true
- },
- "gridPos": { "h": 3, "w": 4, "x": 4, "y": 0 },
- "hideTimeOverride": true,
- "id": 12,
- "interval": null,
- "isNew": true,
- "links": [],
- "mappingType": 1,
- "mappingTypes": [
- { "name": "value to text", "value": 1 },
- { "name": "range to text", "value": 2 }
- ],
- "maxDataPoints": 100,
- "nullPointMode": "connected",
- "nullText": null,
- "postfix": "",
- "postfixFontSize": "50%",
- "prefix": "",
- "prefixFontSize": "50%",
- "rangeMaps": [{ "from": "null", "text": "N/A", "to": "null" }],
- "sparkline": {
- "fillColor": "rgba(31, 118, 189, 0.18)",
- "full": false,
- "lineColor": "rgb(31, 120, 193)",
- "show": true
- },
- "tableColumn": "",
- "targets": [
- {
- "expr": "sum(\n avg_over_time(redis_connected_clients{instance=~\"$instance\"}[$__interval])\n)",
- "format": "time_series",
- "interval": "1m",
- "intervalFactor": 2,
- "legendFormat": "",
- "metric": "",
- "refId": "A",
- "step": 2
- }
- ],
- "thresholds": "",
- "timeFrom": "1m",
- "timeShift": null,
- "title": "Clients",
- "type": "singlestat",
- "valueFontSize": "80%",
- "valueMaps": [{ "op": "=", "text": "N/A", "value": "null" }],
- "valueName": "avg"
- },
- {
- "aliasColors": {},
- "bars": false,
- "dashLength": 10,
- "dashes": false,
- "datasource": "GitLab Omnibus",
- "editable": true,
- "error": false,
- "fill": 1,
- "grid": {},
- "gridPos": { "h": 6, "w": 8, "x": 8, "y": 0 },
- "id": 2,
- "isNew": true,
- "legend": {
- "avg": false,
- "current": false,
- "max": false,
- "min": false,
- "show": false,
- "total": false,
- "values": false
- },
- "lines": true,
- "linewidth": 2,
- "links": [],
- "nullPointMode": "connected",
- "paceLength": 10,
- "percentage": false,
- "pointradius": 5,
- "points": false,
- "renderer": "flot",
- "seriesOverrides": [],
- "spaceLength": 10,
- "stack": false,
- "steppedLine": false,
- "targets": [
- {
- "expr": "sum(\n rate(redis_commands_processed_total{instance=~\"$instance\"}[$__interval])\n)",
- "format": "time_series",
- "interval": "1m",
- "intervalFactor": 2,
- "legendFormat": "",
- "metric": "A",
- "refId": "A",
- "step": 240,
- "target": ""
- }
- ],
- "thresholds": [],
- "timeFrom": null,
- "timeRegions": [],
- "timeShift": null,
- "title": "Commands Executed",
- "tooltip": { "msResolution": false, "shared": true, "sort": 0, "value_type": "cumulative" },
- "type": "graph",
- "xaxis": { "buckets": null, "mode": "time", "name": null, "show": true, "values": [] },
- "yaxes": [
- { "format": "reqps", "label": null, "logBase": 1, "max": null, "min": "0", "show": true },
- { "format": "short", "label": null, "logBase": 1, "max": null, "min": null, "show": true }
- ],
- "yaxis": { "align": false, "alignLevel": null }
- },
- {
- "aliasColors": {},
- "bars": false,
- "dashLength": 10,
- "dashes": false,
- "datasource": "GitLab Omnibus",
- "decimals": 2,
- "editable": true,
- "error": false,
- "fill": 1,
- "grid": {},
- "gridPos": { "h": 6, "w": 8, "x": 16, "y": 0 },
- "id": 1,
- "isNew": true,
- "legend": {
- "avg": false,
- "current": false,
- "max": false,
- "min": false,
- "show": false,
- "total": false,
- "values": false
- },
- "lines": true,
- "linewidth": 2,
- "links": [],
- "nullPointMode": "connected",
- "paceLength": 10,
- "percentage": true,
- "pointradius": 5,
- "points": false,
- "renderer": "flot",
- "seriesOverrides": [],
- "spaceLength": 10,
- "stack": false,
- "steppedLine": false,
- "targets": [
- {
- "expr": "sum(\n rate(redis_keyspace_hits_total{instance=~\"$instance\"}[$__interval])\n)",
- "format": "time_series",
- "hide": false,
- "interval": "1m",
- "intervalFactor": 1,
- "legendFormat": "hits",
- "metric": "",
- "refId": "A",
- "step": 240,
- "target": ""
- },
- {
- "expr": "sum(\n rate(redis_keyspace_misses_total{instance=~\"$instance\"}[$__interval])\n)",
- "format": "time_series",
- "hide": false,
- "interval": "1m",
- "intervalFactor": 1,
- "legendFormat": "misses",
- "metric": "",
- "refId": "B",
- "step": 240,
- "target": ""
- }
- ],
- "thresholds": [],
- "timeFrom": null,
- "timeRegions": [],
- "timeShift": null,
- "title": "Hits, Misses per Second",
- "tooltip": { "msResolution": false, "shared": true, "sort": 0, "value_type": "individual" },
- "type": "graph",
- "xaxis": { "buckets": null, "mode": "time", "name": null, "show": true, "values": [] },
- "yaxes": [
- { "format": "short", "label": "", "logBase": 1, "max": null, "min": 0, "show": true },
- { "format": "short", "label": null, "logBase": 1, "max": null, "min": null, "show": true }
- ],
- "yaxis": { "align": false, "alignLevel": null }
- },
- {
- "aliasColors": { "max": "#BF1B00" },
- "bars": false,
- "dashLength": 10,
- "dashes": false,
- "datasource": "GitLab Omnibus",
- "editable": true,
- "error": false,
- "fill": 1,
- "grid": {},
- "gridPos": { "h": 10, "w": 8, "x": 0, "y": 3 },
- "id": 7,
- "isNew": true,
- "legend": {
- "avg": false,
- "current": false,
- "hideEmpty": false,
- "hideZero": false,
- "max": false,
- "min": false,
- "show": true,
- "total": false,
- "values": false
- },
- "lines": true,
- "linewidth": 2,
- "links": [],
- "nullPointMode": "null as zero",
- "paceLength": 10,
- "percentage": false,
- "pointradius": 5,
- "points": false,
- "renderer": "flot",
- "seriesOverrides": [{ "alias": "/max - .*/", "dashes": true }],
- "spaceLength": 10,
- "stack": false,
- "steppedLine": false,
- "targets": [
- {
- "expr": "redis_memory_used_bytes{instance=~\"$instance\"}",
- "format": "time_series",
- "intervalFactor": 2,
- "legendFormat": "used - {{instance}}",
- "metric": "",
- "refId": "A",
- "step": 240,
- "target": ""
- },
- {
- "expr": "redis_config_maxmemory{instance=~\"$instance\"} \u003e 0",
- "format": "time_series",
- "hide": false,
- "intervalFactor": 2,
- "legendFormat": "max - {{instance}}",
- "refId": "B",
- "step": 240
- }
- ],
- "thresholds": [],
- "timeFrom": null,
- "timeRegions": [],
- "timeShift": null,
- "title": "Memory Usage",
- "tooltip": { "msResolution": false, "shared": true, "sort": 0, "value_type": "cumulative" },
- "type": "graph",
- "xaxis": { "buckets": null, "mode": "time", "name": null, "show": true, "values": [] },
- "yaxes": [
- { "format": "bytes", "label": null, "logBase": 1, "max": null, "min": 0, "show": true },
- { "format": "short", "label": null, "logBase": 1, "max": null, "min": null, "show": true }
- ],
- "yaxis": { "align": false, "alignLevel": null }
- },
- {
- "aliasColors": {
- "evicts": "#890F02",
- "memcached_items_evicted_total{instance=\"172.17.0.1:9150\",job=\"prometheus\"}": "#890F02",
- "reclaims": "#3F6833"
- },
- "bars": false,
- "dashLength": 10,
- "dashes": false,
- "datasource": "GitLab Omnibus",
- "editable": true,
- "error": false,
- "fill": 1,
- "grid": {},
- "gridPos": { "h": 7, "w": 8, "x": 8, "y": 6 },
- "id": 8,
- "isNew": true,
- "legend": {
- "avg": false,
- "current": false,
- "max": false,
- "min": false,
- "show": true,
- "total": false,
- "values": false
- },
- "lines": true,
- "linewidth": 2,
- "links": [],
- "nullPointMode": "connected",
- "paceLength": 10,
- "percentage": false,
- "pointradius": 5,
- "points": false,
- "renderer": "flot",
- "seriesOverrides": [{ "alias": "reclaims", "yaxis": 2 }],
- "spaceLength": 10,
- "stack": false,
- "steppedLine": false,
- "targets": [
- {
- "expr": "sum(rate(redis_expired_keys_total{instance=~\"$instance\"}[$__interval]))",
- "format": "time_series",
- "interval": "1m",
- "intervalFactor": 2,
- "legendFormat": "expired - {{ test_attribute }}",
- "metric": "",
- "refId": "A",
- "step": 240,
- "target": ""
- },
- {
- "expr": "sum(rate(redis_evicted_keys_total{instance=~\"$instance\"}[$__interval]))",
- "format": "time_series",
- "interval": "1m",
- "intervalFactor": 2,
- "legendFormat": "evicted",
- "refId": "B",
- "step": 240
- }
- ],
- "thresholds": [],
- "timeFrom": null,
- "timeRegions": [],
- "timeShift": null,
- "title": "Expired / Evicted",
- "tooltip": { "msResolution": false, "shared": true, "sort": 0, "value_type": "cumulative" },
- "type": "graph",
- "xaxis": { "buckets": null, "mode": "time", "name": null, "show": true, "values": [] },
- "yaxes": [
- { "format": "short", "label": null, "logBase": 1, "max": null, "min": "0", "show": true },
- { "format": "short", "label": null, "logBase": 1, "max": null, "min": null, "show": true }
- ],
- "yaxis": { "align": false, "alignLevel": null }
- },
- {
- "aliasColors": {},
- "bars": false,
- "dashLength": 10,
- "dashes": false,
- "datasource": "GitLab Omnibus",
- "editable": true,
- "error": false,
- "fill": 1,
- "grid": {},
- "gridPos": { "h": 7, "w": 8, "x": 16, "y": 6 },
- "id": 10,
- "isNew": true,
- "legend": {
- "avg": false,
- "current": false,
- "max": false,
- "min": false,
- "show": true,
- "total": false,
- "values": false
- },
- "lines": true,
- "linewidth": 2,
- "links": [],
- "nullPointMode": "connected",
- "paceLength": 10,
- "percentage": false,
- "pointradius": 5,
- "points": false,
- "renderer": "flot",
- "seriesOverrides": [],
- "spaceLength": 10,
- "stack": false,
- "steppedLine": false,
- "targets": [
- {
- "expr": "sum(\n rate(redis_net_input_bytes_total{instance=~\"$instance\"}[$__interval])\n)",
- "format": "time_series",
- "interval": "1m",
- "intervalFactor": 2,
- "legendFormat": "In",
- "refId": "A",
- "step": 240
- },
- {
- "expr": "sum(\n rate(redis_net_output_bytes_total{instance=~\"$instance\"}[$__interval])\n)",
- "format": "time_series",
- "interval": "1m",
- "intervalFactor": 2,
- "legendFormat": "Out",
- "refId": "B",
- "step": 240
- }
- ],
- "thresholds": [],
- "timeFrom": null,
- "timeRegions": [],
- "timeShift": null,
- "title": "Network I/O",
- "tooltip": { "msResolution": true, "shared": true, "sort": 0, "value_type": "cumulative" },
- "type": "graph",
- "xaxis": { "buckets": null, "mode": "time", "name": null, "show": true, "values": [] },
- "yaxes": [
- { "format": "Bps", "label": null, "logBase": 1, "max": null, "min": "0", "show": true },
- { "format": "short", "label": null, "logBase": 1, "max": null, "min": null, "show": true }
- ],
- "yaxis": { "align": false, "alignLevel": null }
- },
- {
- "aliasColors": {},
- "bars": false,
- "dashLength": 10,
- "dashes": false,
- "datasource": "GitLab Omnibus",
- "editable": true,
- "error": false,
- "fill": 8,
- "grid": {},
- "gridPos": { "h": 7, "w": 16, "x": 0, "y": 13 },
- "id": 14,
- "isNew": true,
- "legend": {
- "alignAsTable": true,
- "avg": true,
- "current": true,
- "max": true,
- "min": false,
- "rightSide": true,
- "show": true,
- "total": false,
- "values": true
- },
- "lines": true,
- "linewidth": 1,
- "links": [],
- "nullPointMode": "connected",
- "paceLength": 10,
- "percentage": false,
- "pointradius": 5,
- "points": false,
- "renderer": "flot",
- "seriesOverrides": [],
- "spaceLength": 10,
- "stack": true,
- "steppedLine": false,
- "targets": [
- {
- "expr": "sum without (instance) (\n rate(redis_commands_total{instance=~\"$instance\"}[$__interval])\n) \u003e 0",
- "format": "time_series",
- "interval": "1m",
- "intervalFactor": 2,
- "legendFormat": "{{ cmd }}",
- "metric": "redis_command_calls_total",
- "refId": "A",
- "step": 240
- }
- ],
- "thresholds": [],
- "timeFrom": null,
- "timeRegions": [],
- "timeShift": null,
- "title": "Command Calls / sec",
- "tooltip": { "msResolution": true, "shared": true, "sort": 2, "value_type": "individual" },
- "type": "graph",
- "xaxis": { "buckets": null, "mode": "time", "name": null, "show": true, "values": [] },
- "yaxes": [
- { "format": "short", "label": null, "logBase": 1, "max": null, "min": "0", "show": true },
- { "format": "short", "label": null, "logBase": 1, "max": null, "min": null, "show": true }
- ],
- "yaxis": { "align": false, "alignLevel": null }
- },
- {
- "aliasColors": {},
- "bars": false,
- "dashLength": 10,
- "dashes": false,
- "datasource": "GitLab Omnibus",
- "editable": true,
- "error": false,
- "fill": 7,
- "grid": {},
- "gridPos": { "h": 7, "w": 8, "x": 16, "y": 13 },
- "id": 13,
- "isNew": true,
- "legend": {
- "avg": false,
- "current": false,
- "max": false,
- "min": false,
- "show": true,
- "total": false,
- "values": false
- },
- "lines": true,
- "linewidth": 2,
- "links": [],
- "nullPointMode": "connected",
- "paceLength": 10,
- "percentage": false,
- "pointradius": 5,
- "points": false,
- "renderer": "flot",
- "seriesOverrides": [],
- "spaceLength": 10,
- "stack": true,
- "steppedLine": false,
- "targets": [
- {
- "expr": "sum(redis_db_keys{instance=~\"$instance\"} - redis_db_keys_expiring{instance=~\"$instance\"}) ",
- "format": "time_series",
- "interval": "",
- "intervalFactor": 2,
- "legendFormat": "not expiring",
- "refId": "A",
- "step": 240,
- "target": ""
- },
- {
- "expr": "sum(redis_db_keys_expiring{instance=~\"$instance\"})",
- "format": "time_series",
- "interval": "",
- "intervalFactor": 2,
- "legendFormat": "expiring",
- "metric": "",
- "refId": "B",
- "step": 240
- }
- ],
- "thresholds": [],
- "timeFrom": null,
- "timeRegions": [],
- "timeShift": null,
- "title": "Expiring vs Not-Expiring Keys",
- "tooltip": { "msResolution": false, "shared": true, "sort": 0, "value_type": "individual" },
- "type": "graph",
- "xaxis": { "buckets": null, "mode": "time", "name": null, "show": true, "values": [] },
- "yaxes": [
- { "format": "short", "label": null, "logBase": 1, "max": null, "min": "0", "show": true },
- { "format": "short", "label": null, "logBase": 1, "max": null, "min": null, "show": true }
- ],
- "yaxis": { "align": false, "alignLevel": null }
- },
- {
- "aliasColors": {},
- "bars": false,
- "dashLength": 10,
- "dashes": false,
- "datasource": "GitLab Omnibus",
- "editable": true,
- "error": false,
- "fill": 7,
- "grid": {},
- "gridPos": { "h": 7, "w": 16, "x": 0, "y": 20 },
- "id": 5,
- "isNew": true,
- "legend": {
- "alignAsTable": true,
- "avg": false,
- "current": true,
- "max": false,
- "min": false,
- "rightSide": true,
- "show": true,
- "total": false,
- "values": true
- },
- "lines": true,
- "linewidth": 2,
- "links": [],
- "nullPointMode": "connected",
- "paceLength": 10,
- "percentage": false,
- "pointradius": 5,
- "points": false,
- "renderer": "flot",
- "seriesOverrides": [],
- "spaceLength": 10,
- "stack": true,
- "steppedLine": false,
- "targets": [
- {
- "expr": "sum by (db) (\n redis_db_keys{instance=~\"$instance\"}\n)",
- "format": "time_series",
- "interval": "",
- "intervalFactor": 2,
- "legendFormat": "{{ db }} ",
- "refId": "A",
- "step": 240,
- "target": ""
- }
- ],
- "thresholds": [],
- "timeFrom": null,
- "timeRegions": [],
- "timeShift": null,
- "title": "Items per DB",
- "tooltip": { "msResolution": false, "shared": true, "sort": 0, "value_type": "individual" },
- "type": "graph",
- "xaxis": { "buckets": null, "mode": "time", "name": null, "show": true, "values": [] },
- "yaxes": [
- { "format": "none", "label": null, "logBase": 1, "max": null, "min": "0", "show": true },
- { "format": "short", "label": null, "logBase": 1, "max": null, "min": null, "show": true }
- ],
- "yaxis": { "align": false, "alignLevel": null }
- }
- ],
- "refresh": "1m",
- "schemaVersion": 18,
- "style": "dark",
- "tags": ["redis"],
- "templating": {
- "list": [
- {
- "allValue": null,
- "current": { "tags": [], "text": "All", "value": "$__all" },
- "datasource": "GitLab Omnibus",
- "definition": "",
- "hide": 0,
- "includeAll": true,
- "label": null,
- "multi": false,
- "name": "instance",
- "options": [],
- "query": "label_values(up{job=\"redis\"}, instance)",
- "refresh": 1,
- "regex": "",
- "skipUrlSync": false,
- "sort": 0,
- "tagValuesQuery": "",
- "tags": [],
- "tagsQuery": "",
- "type": "query",
- "useTags": false
- }
- ]
- },
- "time": { "from": "now-24h", "to": "now" },
- "timepicker": {
- "refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"],
- "time_options": ["5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d"]
- },
- "timezone": "",
- "title": "GitLab Omnibus - Redis",
- "uid": "XDaNK6amz",
- "version": 1
- }
-}
diff --git a/spec/fixtures/grafana/datasource_response.json b/spec/fixtures/grafana/datasource_response.json
deleted file mode 100644
index 07c075beb3565d8dab7b966681fb450323e94777..0000000000000000000000000000000000000000
--- a/spec/fixtures/grafana/datasource_response.json
+++ /dev/null
@@ -1,21 +0,0 @@
-{
- "id": 1,
- "orgId": 1,
- "name": "GitLab Omnibus",
- "type": "prometheus",
- "typeLogoUrl": "",
- "access": "proxy",
- "url": "http://localhost:9090",
- "password": "",
- "user": "",
- "database": "",
- "basicAuth": false,
- "basicAuthUser": "",
- "basicAuthPassword": "",
- "withCredentials": false,
- "isDefault": true,
- "jsonData": {},
- "secureJsonFields": {},
- "version": 1,
- "readOnly": true
-}
diff --git a/spec/fixtures/grafana/expected_grafana_embed.json b/spec/fixtures/grafana/expected_grafana_embed.json
deleted file mode 100644
index 0cee03858862428bac3a94a4d45e4cfca5f24e6e..0000000000000000000000000000000000000000
--- a/spec/fixtures/grafana/expected_grafana_embed.json
+++ /dev/null
@@ -1,25 +0,0 @@
-{
- "panel_groups": [
- {
- "panels": [
- {
- "title": "Network I/O",
- "type": "area-chart",
- "y_label": "",
- "metrics": [
- {
- "id": "In_0",
- "query_range": "sum( rate(redis_net_input_bytes_total{instance=~\"localhost:9121\"}[1m]))",
- "label": "In"
- },
- {
- "id": "Out_1",
- "query_range": "sum( rate(redis_net_output_bytes_total{instance=~\"localhost:9121\"}[1m]))",
- "label": "Out"
- }
- ]
- }
- ]
- }
- ]
-}
diff --git a/spec/fixtures/grafana/proxy_response.json b/spec/fixtures/grafana/proxy_response.json
deleted file mode 100644
index b9f34abcaaf06c2db44efb7370e6bac6925dc2dd..0000000000000000000000000000000000000000
--- a/spec/fixtures/grafana/proxy_response.json
+++ /dev/null
@@ -1,459 +0,0 @@
-{
- "status": "success",
- "data": {
- "resultType": "matrix",
- "result": [
- {
- "metric": {
- "test_attribute": "test-attribute-value"
- },
- "values": [
- [1570768177, "54"],
- [1570768237, "54"],
- [1570768297, "54"],
- [1570768357, "54"],
- [1570768417, "54"],
- [1570768477, "54"],
- [1570768537, "54"],
- [1570768597, "54"],
- [1570768657, "54"],
- [1570768717, "54"],
- [1570768777, "54"],
- [1570768837, "54"],
- [1570768897, "54"],
- [1570768957, "54"],
- [1570769017, "54"],
- [1570769077, "54"],
- [1570769377, "54"],
- [1570769437, "54"],
- [1570769497, "54"],
- [1570769557, "54"],
- [1570769617, "54"],
- [1570769677, "54"],
- [1570769737, "54"],
- [1570769797, "54"],
- [1570769857, "54"],
- [1570769917, "54"],
- [1570769977, "54"],
- [1570770037, "54"],
- [1570770097, "54"],
- [1570770157, "54"],
- [1570770217, "54"],
- [1570770277, "54"],
- [1570770337, "54"],
- [1570770397, "54"],
- [1570770457, "54"],
- [1570770517, "54"],
- [1570770577, "54"],
- [1570770637, "54"],
- [1570770697, "54"],
- [1570770757, "54"],
- [1570770817, "54"],
- [1570770877, "54"],
- [1570770937, "54"],
- [1570770997, "54"],
- [1570771057, "54"],
- [1570771117, "54"],
- [1570771177, "54"],
- [1570771237, "54"],
- [1570771297, "54"],
- [1570771357, "54"],
- [1570771417, "54"],
- [1570771477, "54"],
- [1570771537, "54"],
- [1570771597, "54"],
- [1570771657, "54"],
- [1570771717, "54"],
- [1570771777, "54"],
- [1570771837, "54"],
- [1570771897, "54"],
- [1570771957, "54"],
- [1570772017, "54"],
- [1570772077, "54"],
- [1570772137, "54"],
- [1570772197, "54"],
- [1570772257, "54"],
- [1570772317, "54"],
- [1570772377, "54"],
- [1570772437, "54"],
- [1570772497, "54"],
- [1570772557, "54"],
- [1570772617, "54"],
- [1570772677, "54"],
- [1570772737, "54"],
- [1570772797, "54"],
- [1570772857, "54"],
- [1570772917, "54"],
- [1570772977, "54"],
- [1570773037, "54"],
- [1570773097, "54"],
- [1570773157, "54"],
- [1570773217, "54"],
- [1570773277, "54"],
- [1570773337, "54"],
- [1570773397, "54"],
- [1570773457, "54"],
- [1570773517, "54"],
- [1570773577, "54"],
- [1570773637, "54"],
- [1570773697, "54"],
- [1570773757, "54"],
- [1570773817, "54"],
- [1570773877, "54"],
- [1570773937, "54"],
- [1570773997, "54"],
- [1570774057, "54"],
- [1570774117, "54"],
- [1570774177, "54"],
- [1570774237, "54"],
- [1570774297, "54"],
- [1570774357, "54"],
- [1570774417, "54"],
- [1570774477, "54"],
- [1570774537, "54"],
- [1570774597, "54"],
- [1570774657, "54"],
- [1570774717, "54"],
- [1570774777, "54"],
- [1570774837, "54"],
- [1570774897, "54"],
- [1570774957, "54"],
- [1570775017, "54"],
- [1570775077, "54"],
- [1570775137, "54"],
- [1570776937, "54"],
- [1570776997, "54"],
- [1570777057, "54"],
- [1570777117, "54"],
- [1570777177, "54"],
- [1570777237, "54"],
- [1570777297, "54"],
- [1570777357, "54"],
- [1570777417, "54"],
- [1570777477, "54"],
- [1570777537, "54"],
- [1570777597, "54"],
- [1570777657, "54"],
- [1570777717, "54"],
- [1570778017, "54"],
- [1570778077, "54"],
- [1570778137, "54"],
- [1570778197, "54"],
- [1570778257, "54"],
- [1570778317, "54"],
- [1570778377, "54"],
- [1570778437, "54"],
- [1570778497, "54"],
- [1570778557, "54"],
- [1570778617, "54"],
- [1570778677, "54"],
- [1570778737, "54"],
- [1570778797, "54"],
- [1570778857, "54"],
- [1570778917, "54"],
- [1570778977, "54"],
- [1570779037, "54"],
- [1570779097, "54"],
- [1570779157, "54"],
- [1570779217, "54"],
- [1570779277, "54"],
- [1570779337, "54"],
- [1570779397, "54"],
- [1570779457, "54"],
- [1570779517, "54"],
- [1570779577, "54"],
- [1570779637, "54"],
- [1570779697, "54"],
- [1570779757, "54"],
- [1570779817, "54"],
- [1570779877, "54"],
- [1570779937, "54"],
- [1570779997, "54"],
- [1570780057, "54"],
- [1570780117, "54"],
- [1570780177, "54"],
- [1570780237, "54"],
- [1570780297, "54"],
- [1570780357, "54"],
- [1570780417, "54"],
- [1570780477, "54"],
- [1570780537, "54"],
- [1570780597, "54"],
- [1570780657, "54"],
- [1570780717, "54"],
- [1570780777, "54"],
- [1570780837, "54"],
- [1570780897, "54"],
- [1570780957, "54"],
- [1570781017, "54"],
- [1570781077, "54"],
- [1570781137, "54"],
- [1570781197, "54"],
- [1570781257, "54"],
- [1570781317, "54"],
- [1570781377, "54"],
- [1570781437, "54"],
- [1570781497, "54"],
- [1570781557, "54"],
- [1570781617, "54"],
- [1570781677, "54"],
- [1570781737, "54"],
- [1570781797, "54"],
- [1570781857, "54"],
- [1570781917, "54"],
- [1570781977, "54"],
- [1570782037, "54"],
- [1570782097, "54"],
- [1570782157, "54"],
- [1570782217, "54"],
- [1570782277, "54"],
- [1570782337, "54"],
- [1570782397, "54"],
- [1570782457, "54"],
- [1570782517, "54"],
- [1570782577, "54"],
- [1570782637, "54"],
- [1570782697, "54"],
- [1570782757, "54"],
- [1570782817, "54"],
- [1570782877, "54"],
- [1570782937, "54"],
- [1570782997, "54"],
- [1570783057, "54"],
- [1570783117, "54"],
- [1570783177, "54"],
- [1570783237, "54"],
- [1570783297, "54"],
- [1570783357, "54"],
- [1570783417, "54"],
- [1570783477, "54"],
- [1570783537, "54"],
- [1570783597, "54"],
- [1570783657, "54"],
- [1570783717, "54"],
- [1570783777, "54"],
- [1570783837, "54"],
- [1570783897, "54"],
- [1570783957, "54"],
- [1570784017, "54"],
- [1570784077, "54"],
- [1570784137, "54"],
- [1570784197, "54"],
- [1570784257, "54"],
- [1570784317, "54"],
- [1570784377, "54"],
- [1570784437, "54"],
- [1570784497, "54"],
- [1570784557, "54"],
- [1570784617, "54"],
- [1570784677, "54"],
- [1570784737, "54"],
- [1570784797, "54"],
- [1570784857, "54"],
- [1570784917, "54"],
- [1570784977, "54"],
- [1570785037, "54"],
- [1570785097, "54"],
- [1570785157, "54"],
- [1570785217, "54"],
- [1570785277, "54"],
- [1570785337, "54"],
- [1570785397, "54"],
- [1570785457, "54"],
- [1570785517, "54"],
- [1570785577, "54"],
- [1570785637, "54"],
- [1570785697, "54"],
- [1570785757, "54"],
- [1570785817, "54"],
- [1570785877, "54"],
- [1570785937, "54"],
- [1570785997, "54"],
- [1570786057, "54"],
- [1570786117, "54"],
- [1570786177, "54"],
- [1570786237, "54"],
- [1570786297, "54"],
- [1570786357, "54"],
- [1570786417, "54"],
- [1570786477, "54"],
- [1570786537, "54"],
- [1570786597, "54"],
- [1570786657, "54"],
- [1570786717, "54"],
- [1570786777, "54"],
- [1570786837, "54"],
- [1570786897, "54"],
- [1570786957, "53"],
- [1570787017, "54"],
- [1570787077, "54"],
- [1570787137, "54"],
- [1570787197, "54"],
- [1570787257, "54"],
- [1570787317, "54"],
- [1570787377, "54"],
- [1570787437, "54"],
- [1570787497, "54"],
- [1570787557, "54"],
- [1570787617, "54"],
- [1570787677, "54"],
- [1570787737, "54"],
- [1570787797, "54"],
- [1570787857, "54"],
- [1570787917, "54"],
- [1570787977, "54"],
- [1570788037, "54"],
- [1570788097, "54"],
- [1570788157, "54"],
- [1570788217, "54"],
- [1570788277, "54"],
- [1570788337, "54"],
- [1570788397, "54"],
- [1570788457, "54"],
- [1570788517, "54"],
- [1570788577, "54"],
- [1570788637, "54"],
- [1570788697, "54"],
- [1570788757, "54"],
- [1570788817, "54"],
- [1570788877, "54"],
- [1570788937, "54"],
- [1570788997, "54"],
- [1570789057, "54"],
- [1570789117, "54"],
- [1570789177, "54"],
- [1570789237, "54"],
- [1570789297, "54"],
- [1570789357, "54"],
- [1570789417, "54"],
- [1570789477, "54"],
- [1570789537, "54"],
- [1570789597, "54"],
- [1570789657, "54"],
- [1570789717, "54"],
- [1570789777, "54"],
- [1570789837, "54"],
- [1570789897, "54"],
- [1570789957, "54"],
- [1570790017, "54"],
- [1570790077, "54"],
- [1570790137, "54"],
- [1570790197, "54"],
- [1570790257, "54"],
- [1570790317, "54"],
- [1570790377, "54"],
- [1570790437, "54"],
- [1570790497, "54"],
- [1570790557, "54"],
- [1570790617, "54"],
- [1570790677, "54"],
- [1570790737, "54"],
- [1570790797, "54"],
- [1570790857, "54"],
- [1570790917, "54"],
- [1570790977, "54"],
- [1570791037, "54"],
- [1570791097, "54"],
- [1570791157, "54"],
- [1570791217, "54"],
- [1570791277, "54"],
- [1570791337, "54"],
- [1570791397, "54"],
- [1570791457, "54"],
- [1570791517, "54"],
- [1570791577, "54"],
- [1570791637, "54"],
- [1570791697, "54"],
- [1570791757, "54"],
- [1570791817, "54"],
- [1570791877, "54"],
- [1570791937, "54"],
- [1570791997, "54"],
- [1570792057, "54"],
- [1570792117, "54"],
- [1570792177, "54"],
- [1570792237, "54"],
- [1570792297, "54"],
- [1570792357, "54"],
- [1570792417, "54"],
- [1570792477, "54"],
- [1570792537, "54"],
- [1570792597, "54"],
- [1570792657, "54"],
- [1570792717, "54"],
- [1570792777, "54"],
- [1570792837, "54"],
- [1570792897, "54"],
- [1570792957, "54"],
- [1570793017, "54"],
- [1570793077, "54"],
- [1570793137, "54"],
- [1570793197, "54"],
- [1570793257, "54"],
- [1570793317, "54"],
- [1570793377, "54"],
- [1570793437, "54"],
- [1570793497, "54"],
- [1570793557, "54"],
- [1570793617, "54"],
- [1570793677, "54"],
- [1570793737, "54"],
- [1570793797, "54"],
- [1570793857, "54"],
- [1570793917, "54"],
- [1570793977, "54"],
- [1570794037, "54"],
- [1570794097, "54"],
- [1570794157, "54"],
- [1570794217, "54"],
- [1570794277, "54"],
- [1570794337, "54"],
- [1570794397, "54"],
- [1570794457, "54"],
- [1570794517, "54"],
- [1570794577, "54"],
- [1570794637, "54"],
- [1570794697, "54"],
- [1570794757, "54"],
- [1570794817, "54"],
- [1570794877, "54"],
- [1570794937, "54"],
- [1570794997, "54"],
- [1570795057, "54"],
- [1570795117, "54"],
- [1570795177, "54"],
- [1570795237, "54"],
- [1570795297, "54"],
- [1570795357, "54"],
- [1570795417, "54"],
- [1570795477, "54"],
- [1570795537, "54"],
- [1570795597, "54"],
- [1570795657, "54"],
- [1570795717, "54"],
- [1570795777, "54"],
- [1570795837, "54"],
- [1570795897, "54"],
- [1570795957, "54"],
- [1570796017, "54"],
- [1570796077, "54"],
- [1570796137, "54"],
- [1570796197, "54"],
- [1570796257, "54"],
- [1570796317, "54"],
- [1570796377, "54"],
- [1570796437, "55"],
- [1570796497, "54"],
- [1570796557, "54"],
- [1570796617, "54"],
- [1570796677, "54"],
- [1570796737, "54"],
- [1570796797, "54"],
- [1570796857, "54"],
- [1570796917, "54"],
- [1570796977, "54"]
- ]
- }
- ]
- }
-}
diff --git a/spec/fixtures/grafana/simplified_dashboard_response.json b/spec/fixtures/grafana/simplified_dashboard_response.json
deleted file mode 100644
index b450fda082b257938ed46120b17f519141fe457e..0000000000000000000000000000000000000000
--- a/spec/fixtures/grafana/simplified_dashboard_response.json
+++ /dev/null
@@ -1,40 +0,0 @@
-{
- "dashboard": {
- "panels": [
- {
- "datasource": "GitLab Omnibus",
- "id": 8,
- "lines": true,
- "targets": [
- {
- "expr": "sum(\n rate(redis_net_input_bytes_total{instance=~\"$instance\"}[$__interval])\n)",
- "format": "time_series",
- "interval": "1m",
- "legendFormat": "In",
- "refId": "A"
- },
- {
- "expr": "sum(\n rate(redis_net_output_bytes_total{instance=~\"[[instance]]\"}[$__interval])\n)",
- "format": "time_series",
- "interval": "1m",
- "legendFormat": "Out",
- "refId": "B"
- }
- ],
- "title": "Network I/O",
- "type": "graph",
- "yaxes": [{ "format": "Bps" }, { "format": "short" }]
- }
- ],
- "templating": {
- "list": [
- {
- "current": {
- "value": "localhost:9121"
- },
- "name": "instance"
- }
- ]
- }
- }
-}
diff --git a/spec/graphql/resolvers/projects/grafana_integration_resolver_spec.rb b/spec/graphql/resolvers/projects/grafana_integration_resolver_spec.rb
deleted file mode 100644
index 546b85925468f0913f25ce9b25255be1338b4d51..0000000000000000000000000000000000000000
--- a/spec/graphql/resolvers/projects/grafana_integration_resolver_spec.rb
+++ /dev/null
@@ -1,29 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Resolvers::Projects::GrafanaIntegrationResolver do
- include GraphqlHelpers
-
- let_it_be(:project) { create(:project) }
- let_it_be(:current_user) { create(:user) }
- let_it_be(:grafana_integration) { create(:grafana_integration, project: project) }
-
- describe '#resolve' do
- context 'when object is not a project' do
- it { expect(resolve_integration(obj: current_user)).to eq nil }
- end
-
- context 'when object is a project' do
- it { expect(resolve_integration(obj: project)).to eq grafana_integration }
- end
-
- context 'when object is nil' do
- it { expect(resolve_integration(obj: nil)).to eq nil }
- end
- end
-
- def resolve_integration(obj: project, context: { current_user: current_user })
- resolve(described_class, obj: obj, ctx: context)
- end
-end
diff --git a/spec/graphql/types/project_type_spec.rb b/spec/graphql/types/project_type_spec.rb
index 7ce3f4c675ce19466f45bc5a55758d110d78e444..ddece705ebe612b8fcc34b0ea73f86d3afa56bbd 100644
--- a/spec/graphql/types/project_type_spec.rb
+++ b/spec/graphql/types/project_type_spec.rb
@@ -405,7 +405,7 @@
subject { described_class.fields['grafanaIntegration'] }
it { is_expected.to have_graphql_type(Types::GrafanaIntegrationType) }
- it { is_expected.to have_graphql_resolver(Resolvers::Projects::GrafanaIntegrationResolver) }
+ it { is_expected.to have_graphql_resolver(nil) }
end
describe 'environments field' do
diff --git a/spec/lib/gitlab/doctor/secrets_spec.rb b/spec/lib/gitlab/doctor/secrets_spec.rb
index 64995298bf29dadce77da6fe728a3d23a5f9f08c..f5d9e20f16722a3931568d1b83620fc1e7961641 100644
--- a/spec/lib/gitlab/doctor/secrets_spec.rb
+++ b/spec/lib/gitlab/doctor/secrets_spec.rb
@@ -6,7 +6,6 @@
let!(:user) { create(:user, otp_secret: "test") }
let!(:group) { create(:group, :allow_runner_registration_token, runners_token: "test") }
let!(:project) { create(:project) }
- let!(:grafana_integration) { create(:grafana_integration, project: project, token: "test") }
let!(:integration) { create(:integration, project: project, properties: { test_key: "test_value" }) }
let!(:webhook) { create(:project_hook, project: project) }
let(:logger) { instance_double(Logger).as_null_object }
@@ -105,14 +104,6 @@
end
end
- context 'when GrafanaIntegration token is set via private method' do
- it 'can access GrafanaIntegration token value' do
- expect(logger).to receive(:info).with(/GrafanaIntegration failures: 0/)
-
- doctor_secrets
- end
- end
-
context 'when secrets doctor is called' do
it 'meets the necessary Ci::Build prerequisites' do
subj = described_class.new(logger)
diff --git a/spec/lib/gitlab/import_export/all_models.yml b/spec/lib/gitlab/import_export/all_models.yml
index 99095ac909c317fceeb023bb909f82e2a7bf010f..af76636d8f1fb9a41123d5b8293ef305eba0fc4c 100644
--- a/spec/lib/gitlab/import_export/all_models.yml
+++ b/spec/lib/gitlab/import_export/all_models.yml
@@ -831,7 +831,6 @@ project:
- designs
- project_aliases
- external_pull_requests
-- grafana_integration
- remove_source_branch_after_merge
- deleting_user
- upstream_projects
diff --git a/spec/lib/grafana/client_spec.rb b/spec/lib/grafana/client_spec.rb
deleted file mode 100644
index 13fe9acc6e9127d2c91ebcd7c1848da8dad594ff..0000000000000000000000000000000000000000
--- a/spec/lib/grafana/client_spec.rb
+++ /dev/null
@@ -1,131 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Grafana::Client do
- let(:grafana_url) { 'https://grafanatest.com/-/grafana-project' }
- let(:token) { 'test-token' }
-
- subject(:client) { described_class.new(api_url: grafana_url, token: token) }
-
- shared_examples 'calls grafana api' do
- let!(:grafana_api_request) { stub_grafana_request(grafana_api_url) }
-
- it 'calls grafana api' do
- subject
-
- expect(grafana_api_request).to have_been_requested
- end
- end
-
- shared_examples 'no redirects' do
- let(:redirect_to) { 'https://redirected.example.com' }
- let(:other_url) { 'https://grafana.example.org' }
-
- let!(:redirected_req_stub) { stub_grafana_request(other_url) }
-
- let!(:redirect_req_stub) do
- stub_grafana_request(
- grafana_api_url,
- status: 302,
- headers: { location: redirect_to }
- )
- end
-
- it 'does not follow redirects' do
- expect { subject }.to raise_exception(
- Grafana::Client::Error,
- 'Grafana response status code: 302, Message: {}'
- )
-
- expect(redirect_req_stub).to have_been_requested
- expect(redirected_req_stub).not_to have_been_requested
- end
- end
-
- shared_examples 'handles exceptions' do
- exceptions = {
- Gitlab::HTTP::Error => 'Error when connecting to Grafana',
- Net::OpenTimeout => 'Connection to Grafana timed out',
- SocketError => 'Received SocketError when trying to connect to Grafana',
- OpenSSL::SSL::SSLError => 'Grafana returned invalid SSL data',
- Errno::ECONNREFUSED => 'Connection refused',
- StandardError => 'Grafana request failed due to StandardError'
- }
-
- exceptions.each do |exception, message|
- context exception.to_s do
- before do
- stub_request(:get, grafana_api_url).to_raise(exception)
- end
-
- it do
- expect { subject }
- .to raise_exception(Grafana::Client::Error, message)
- end
- end
- end
- end
-
- describe '#get_dashboard' do
- let(:grafana_api_url) { 'https://grafanatest.com/-/grafana-project/api/dashboards/uid/FndfgnX' }
-
- subject do
- client.get_dashboard(uid: 'FndfgnX')
- end
-
- it_behaves_like 'calls grafana api'
- it_behaves_like 'no redirects'
- it_behaves_like 'handles exceptions'
- end
-
- describe '#get_datasource' do
- let(:grafana_api_url) { 'https://grafanatest.com/-/grafana-project/api/datasources/name/Test%20Name' }
-
- subject do
- client.get_datasource(name: 'Test Name')
- end
-
- it_behaves_like 'calls grafana api'
- it_behaves_like 'no redirects'
- it_behaves_like 'handles exceptions'
- end
-
- describe '#proxy_datasource' do
- let(:grafana_api_url) do
- 'https://grafanatest.com/-/grafana-project/' \
- 'api/datasources/proxy/' \
- '1/api/v1/query_range' \
- '?query=rate(relevant_metric)' \
- '&start=1570441248&end=1570444848&step=900'
- end
-
- subject do
- client.proxy_datasource(
- datasource_id: '1',
- proxy_path: 'api/v1/query_range',
- query: {
- query: 'rate(relevant_metric)',
- start: 1570441248,
- end: 1570444848,
- step: 900
- }
- )
- end
-
- it_behaves_like 'calls grafana api'
- it_behaves_like 'no redirects'
- it_behaves_like 'handles exceptions'
- end
-
- private
-
- def stub_grafana_request(url, body: {}, status: 200, headers: {})
- stub_request(:get, url)
- .to_return(
- status: status,
- headers: { 'Content-Type' => 'application/json' }.merge(headers),
- body: body.to_json
- )
- end
-end
diff --git a/spec/lib/grafana/time_window_spec.rb b/spec/lib/grafana/time_window_spec.rb
deleted file mode 100644
index 0657bed7b28b69cf986b6288952694e47ac17655..0000000000000000000000000000000000000000
--- a/spec/lib/grafana/time_window_spec.rb
+++ /dev/null
@@ -1,115 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Grafana::TimeWindow do
- let(:from) { '1552799400000' }
- let(:to) { '1552828200000' }
-
- around do |example|
- travel_to(Time.utc(2019, 3, 17, 13, 10)) { example.run }
- end
-
- describe '#formatted' do
- subject { described_class.new(from, to).formatted }
-
- it { is_expected.to eq(start: "2019-03-17T05:10:00Z", end: "2019-03-17T13:10:00Z") }
- end
-
- describe '#in_milliseconds' do
- subject { described_class.new(from, to).in_milliseconds }
-
- it { is_expected.to eq(from: 1552799400000, to: 1552828200000) }
-
- context 'when non-unix parameters are provided' do
- let(:to) { Time.now.to_s }
-
- let(:default_from) { 8.hours.ago.to_i * 1000 }
- let(:default_to) { Time.now.to_i * 1000 }
-
- it { is_expected.to eq(from: default_from, to: default_to) }
- end
- end
-end
-
-RSpec.describe Grafana::RangeWithDefaults do
- let(:from) { Grafana::Timestamp.from_ms_since_epoch('1552799400000') }
- let(:to) { Grafana::Timestamp.from_ms_since_epoch('1552828200000') }
-
- around do |example|
- travel_to(Time.utc(2019, 3, 17, 13, 10)) { example.run }
- end
-
- describe '#to_hash' do
- subject { described_class.new(from: from, to: to).to_hash }
-
- it { is_expected.to eq(from: from, to: to) }
-
- context 'when only "to" is provided' do
- let(:from) { nil }
-
- it 'has the expected properties' do
- expect(subject[:to]).to eq(to)
- expect(subject[:from].time).to eq(to.time - 8.hours)
- end
- end
-
- context 'when only "from" is provided' do
- let(:to) { nil }
-
- it 'has the expected properties' do
- expect(subject[:to].time).to eq(from.time + 8.hours)
- expect(subject[:from]).to eq(from)
- end
- end
-
- context 'when no parameters are provided' do
- let(:to) { nil }
- let(:from) { nil }
-
- let(:default_from) { 8.hours.ago }
- let(:default_to) { Time.now }
-
- it 'has the expected properties' do
- expect(subject[:to].time).to eq(default_to)
- expect(subject[:from].time).to eq(default_from)
- end
- end
- end
-end
-
-RSpec.describe Grafana::Timestamp do
- let(:timestamp) { Time.at(1552799400) }
-
- around do |example|
- travel_to(Time.utc(2019, 3, 17, 13, 10)) { example.run }
- end
-
- describe '#formatted' do
- subject { described_class.new(timestamp).formatted }
-
- it { is_expected.to eq "2019-03-17T05:10:00Z" }
- end
-
- describe '#to_ms' do
- subject { described_class.new(timestamp).to_ms }
-
- it { is_expected.to eq 1552799400000 }
- end
-
- describe '.from_ms_since_epoch' do
- let(:timestamp) { '1552799400000' }
-
- subject { described_class.from_ms_since_epoch(timestamp) }
-
- it { is_expected.to be_a described_class }
-
- context 'when the input is not a unix-ish timestamp' do
- let(:timestamp) { Time.now.to_s }
-
- it 'raises an error' do
- expect { subject }.to raise_error(Grafana::Timestamp::Error)
- end
- end
- end
-end
diff --git a/spec/lib/grafana/validator_spec.rb b/spec/lib/grafana/validator_spec.rb
deleted file mode 100644
index b45749ffc95cd3edbcee6208b21306ae449f496b..0000000000000000000000000000000000000000
--- a/spec/lib/grafana/validator_spec.rb
+++ /dev/null
@@ -1,119 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe Grafana::Validator do
- let(:grafana_dashboard) { Gitlab::Json.parse(fixture_file('grafana/simplified_dashboard_response.json'), symbolize_names: true) }
- let(:datasource) { Gitlab::Json.parse(fixture_file('grafana/datasource_response.json'), symbolize_names: true) }
- let(:panel) { grafana_dashboard[:dashboard][:panels].first }
-
- let(:query_params) do
- {
- from: '1570397739557',
- to: '1570484139557',
- panelId: '8',
- 'var-instance': 'localhost:9121'
- }
- end
-
- describe 'validate!' do
- shared_examples_for 'processing error' do |message|
- it 'raises a processing error' do
- expect { subject }
- .to raise_error(::Grafana::Validator::Error, message)
- end
- end
-
- subject { described_class.new(grafana_dashboard, datasource, panel, query_params).validate! }
-
- it 'does not raise an error' do
- expect { subject }.not_to raise_error
- end
-
- context 'when query param "from" is not specified' do
- before do
- query_params.delete(:from)
- end
-
- it_behaves_like 'processing error', 'Grafana query parameters must include from and to.'
- end
-
- context 'when query param "to" is not specified' do
- before do
- query_params.delete(:to)
- end
-
- it_behaves_like 'processing error', 'Grafana query parameters must include from and to.'
- end
-
- context 'when the panel is not provided' do
- let(:panel) { nil }
-
- it_behaves_like 'processing error', 'Panel type must be a line graph.'
- end
-
- context 'when the panel is not a graph' do
- before do
- panel[:type] = 'singlestat'
- end
-
- it_behaves_like 'processing error', 'Panel type must be a line graph.'
- end
-
- context 'when the panel is not a line graph' do
- before do
- panel[:lines] = false
- end
-
- it_behaves_like 'processing error', 'Panel type must be a line graph.'
- end
-
- context 'when the query dashboard includes undefined variables' do
- before do
- query_params.delete(:'var-instance')
- end
-
- it_behaves_like 'processing error', 'All Grafana variables must be defined in the query parameters.'
- end
-
- context 'when the expression contains unsupported global variables' do
- before do
- grafana_dashboard[:dashboard][:panels][0][:targets][0][:expr] = 'sum(important_metric[$__interval_ms])'
- end
-
- it_behaves_like 'processing error', "Prometheus must not include #{described_class::UNSUPPORTED_GRAFANA_GLOBAL_VARS}"
- end
-
- context 'when the datasource is not proxyable' do
- before do
- datasource[:access] = 'not-proxy'
- end
-
- it_behaves_like 'processing error', 'Only Prometheus datasources with proxy access in Grafana are supported.'
- end
-
- # Skipping datasource validation allows for checks to be
- # run without a secondary call to Grafana API
- context 'when the datasource is not provided' do
- let(:datasource) { nil }
-
- it 'does not raise an error' do
- expect { subject }.not_to raise_error
- end
- end
- end
-
- describe 'valid?' do
- subject { described_class.new(grafana_dashboard, datasource, panel, query_params).valid? }
-
- context 'with valid arguments' do
- it { is_expected.to be true }
- end
-
- context 'with invalid arguments' do
- let(:query_params) { {} }
-
- it { is_expected.to be false }
- end
- end
-end
diff --git a/spec/migrations/20250725071156_remove_grafana_integrations_fk_project_id_spec.rb b/spec/migrations/20250725071156_remove_grafana_integrations_fk_project_id_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..109aeb2747990c93f068576345fe69b250c5f03c
--- /dev/null
+++ b/spec/migrations/20250725071156_remove_grafana_integrations_fk_project_id_spec.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe RemoveGrafanaIntegrationsFkProjectId, feature_category: :observability do
+ include Database::TableSchemaHelpers
+
+ let(:table_name) { :grafana_integrations }
+
+ it 'drops the projects foreign key constraint' do
+ reversible_migration do |migration|
+ migration.before -> {
+ expect_foreign_key_to_exist(table_name, described_class::CONSTRAINT_NAME)
+ }
+
+ migration.after -> {
+ expect_foreign_key_not_to_exist(table_name, described_class::CONSTRAINT_NAME)
+ }
+ end
+ end
+end
diff --git a/spec/migrations/20250725071302_remove_grafana_integrations_spec.rb b/spec/migrations/20250725071302_remove_grafana_integrations_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..3f043b7d0f0dbc17cc7a3689786fea36daae2e55
--- /dev/null
+++ b/spec/migrations/20250725071302_remove_grafana_integrations_spec.rb
@@ -0,0 +1,37 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe RemoveGrafanaIntegrations, feature_category: :observability do
+ include Database::TableSchemaHelpers
+
+ let(:table_name) { :grafana_integrations }
+ let(:column_attributes) do
+ [
+ { name: 'id', sql_type: 'bigint', null: false, default: nil },
+ { name: 'project_id', sql_type: 'bigint', null: false, default: nil },
+ { name: 'created_at', sql_type: 'timestamp with time zone', null: false, default: nil },
+ { name: 'updated_at', sql_type: 'timestamp with time zone', null: false, default: nil },
+ { name: 'encrypted_token', sql_type: 'character varying(255)', null: false, default: nil },
+ { name: 'encrypted_token_iv', sql_type: 'character varying(255)', null: false, default: nil },
+ { name: 'grafana_url', sql_type: 'character varying(1024)', null: false, default: nil },
+ { name: 'enabled', sql_type: 'boolean', null: false, default: 'false' }
+ ]
+ end
+
+ it 'drops the grafana_integrations table' do
+ reversible_migration do |migration|
+ migration.before -> {
+ expect_table_columns_to_match(column_attributes, table_name)
+ expect_primary_keys_after_tables([table_name])
+ expect_index_to_exist('index_grafana_integrations_on_enabled')
+ expect_index_to_exist('index_grafana_integrations_on_project_id')
+ }
+
+ migration.after -> {
+ expect(connection.table_exists?(table_name)).to be(false)
+ }
+ end
+ end
+end
diff --git a/spec/models/grafana_integration_spec.rb b/spec/models/grafana_integration_spec.rb
deleted file mode 100644
index 0c7edab699860b666e234ab51d9b0151442c8290..0000000000000000000000000000000000000000
--- a/spec/models/grafana_integration_spec.rb
+++ /dev/null
@@ -1,123 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe GrafanaIntegration do
- describe 'associations' do
- it { is_expected.to belong_to(:project) }
- end
-
- describe 'validations' do
- it { is_expected.to validate_presence_of(:project) }
- it { is_expected.to validate_presence_of(:encrypted_token) }
-
- it 'disallows invalid urls for grafana_url' do
- unsafe_url = %{https://replaceme.com/'>}
- non_ascii_url = 'http://gitlab.com/api/0/projects/project1/something€'
- blank_url = ''
- excessively_long_url = 'https://grafan' + ('a' * 1024) + '.com'
-
- is_expected.not_to allow_values(
- unsafe_url,
- non_ascii_url,
- blank_url,
- excessively_long_url
- ).for(:grafana_url)
- end
-
- it 'allows valid urls for grafana_url' do
- external_url = 'http://grafana.com/'
- internal_url = 'http://192.168.1.1'
-
- is_expected.to allow_value(
- external_url,
- internal_url
- ).for(:grafana_url)
- end
-
- it 'disallows non-booleans in enabled column' do
- is_expected.not_to allow_value(
- nil
- ).for(:enabled)
- end
-
- it 'allows booleans in enabled column' do
- is_expected.to allow_value(
- true,
- false
- ).for(:enabled)
- end
- end
-
- describe '.client' do
- subject(:grafana_integration) { create(:grafana_integration) }
-
- context 'with grafana integration disabled' do
- it 'returns a grafana client' do
- expect(grafana_integration.client).to be_an_instance_of(::Grafana::Client)
- end
- end
-
- context 'with grafana integration enabled' do
- it 'returns nil' do
- grafana_integration.update!(enabled: false)
-
- expect(grafana_integration.client).to be_nil
- end
- end
- end
-
- describe 'attribute encryption' do
- subject(:grafana_integration) { create(:grafana_integration, token: 'super-secret') }
-
- context 'token' do
- it 'encrypts original value into encrypted_token attribute' do
- expect(grafana_integration.encrypted_token).not_to be_nil
- end
-
- it 'locks access to raw value in private method', :aggregate_failures do
- expect { grafana_integration.token }.to raise_error(NoMethodError, /private method .token. called/)
- expect(grafana_integration.send(:token)).to eql('super-secret')
- end
-
- it 'prevents overriding token value with its encrypted or masked version', :aggregate_failures do
- expect { grafana_integration.update!(token: grafana_integration.encrypted_token) }.not_to change { grafana_integration.reload.send(:token) }
- expect { grafana_integration.update!(token: grafana_integration.masked_token) }.not_to change { grafana_integration.reload.send(:token) }
- end
- end
- end
-
- describe 'Callbacks' do
- describe 'before_validation :reset_token' do
- context 'when a token was previously set' do
- subject(:grafana_integration) { create(:grafana_integration) }
-
- it 'resets token if url changed' do
- grafana_integration.grafana_url = 'http://gitlab1.com'
-
- expect(grafana_integration).not_to be_valid
- expect(grafana_integration.send(:token)).to be_nil
- end
-
- it "does not reset token if new url is set together with the same token" do
- grafana_integration.grafana_url = 'http://gitlab_edited.com'
- current_token = grafana_integration.send(:token)
- grafana_integration.token = current_token
-
- expect(grafana_integration).to be_valid
- expect(grafana_integration.send(:token)).to eq(current_token)
- expect(grafana_integration.grafana_url).to eq('http://gitlab_edited.com')
- end
-
- it 'does not reset token if new url is set together with a new token' do
- grafana_integration.grafana_url = 'http://gitlab_edited.com'
- grafana_integration.token = 'token'
-
- expect(grafana_integration).to be_valid
- expect(grafana_integration.send(:token)).to eq('token')
- expect(grafana_integration.grafana_url).to eq('http://gitlab_edited.com')
- end
- end
- end
- end
-end
diff --git a/spec/policies/project_policy_spec.rb b/spec/policies/project_policy_spec.rb
index 048e77d15df6cae6756a9ca5897fae6882e57e4f..c9bde43cd5f08a85926e93816f1950cc330ac3c3 100644
--- a/spec/policies/project_policy_spec.rb
+++ b/spec/policies/project_policy_spec.rb
@@ -1016,38 +1016,6 @@ def set_access_level(access_level)
end
end
- describe 'read_grafana', feature_category: :observability do
- using RSpec::Parameterized::TableSyntax
-
- let(:policy) { :read_grafana }
-
- where(:project_visibility, :role, :allowed) do
- :public | :anonymous | false
- :public | :guest | false
- :public | :planner | false
- :public | :reporter | true
- :internal | :anonymous | false
- :internal | :guest | true
- :internal | :planner | true
- :internal | :reporter | true
- :private | :anonymous | false
- :private | :guest | true
- :private | :planner | true
- :private | :reporter | true
- end
-
- with_them do
- let(:current_user) { public_send(role) }
- let(:project) { public_send("#{project_visibility}_project") }
-
- if params[:allowed]
- it { is_expected.to be_allowed(policy) }
- else
- it { is_expected.not_to be_allowed(policy) }
- end
- end
- end
-
describe 'read_prometheus', feature_category: :observability do
using RSpec::Parameterized::TableSyntax
diff --git a/spec/requests/api/graphql/project/grafana_integration_spec.rb b/spec/requests/api/graphql/project/grafana_integration_spec.rb
index eefebd5515b080e16f80690b9d0741c7e7b237bd..e01eafb47c8504c8189b6ddcedb8e93070d34798 100644
--- a/spec/requests/api/graphql/project/grafana_integration_spec.rb
+++ b/spec/requests/api/graphql/project/grafana_integration_spec.rb
@@ -6,7 +6,6 @@
let_it_be(:project) { create(:project, :repository) }
let_it_be(:current_user) { project.first_owner }
- let_it_be(:grafana_integration) { create(:grafana_integration, project: project) }
let(:fields) do
<<~QUERY
@@ -22,42 +21,11 @@
)
end
- context 'with grafana integration data' do
- let(:integration_data) { graphql_data['project']['grafanaIntegration'] }
-
- context 'without project admin permissions' do
- let(:user) { create(:user) }
-
- before do
- project.add_developer(user)
- post_graphql(query, current_user: user)
- end
-
- it_behaves_like 'a working graphql query'
-
- specify { expect(integration_data).to be_nil }
- end
-
- context 'with project admin permissions' do
- before do
- post_graphql(query, current_user: current_user)
- end
-
- it_behaves_like 'a working graphql query'
-
- specify { expect(integration_data['grafanaUrl']).to eql grafana_integration.grafana_url }
+ before do
+ post_graphql(query, current_user: current_user)
+ end
- specify do
- expect(
- integration_data['createdAt']
- ).to eql grafana_integration.created_at.strftime('%Y-%m-%dT%H:%M:%SZ')
- end
+ it_behaves_like 'a working graphql query'
- specify do
- expect(
- integration_data['updatedAt']
- ).to eql grafana_integration.updated_at.strftime('%Y-%m-%dT%H:%M:%SZ')
- end
- end
- end
+ specify { expect(graphql_data['project']['grafanaIntegration']).to be_nil }
end
diff --git a/spec/support/helpers/grafana_api_helpers.rb b/spec/support/helpers/grafana_api_helpers.rb
deleted file mode 100644
index 7a7b6fec5b4107c7111cadd22904270ac619235e..0000000000000000000000000000000000000000
--- a/spec/support/helpers/grafana_api_helpers.rb
+++ /dev/null
@@ -1,41 +0,0 @@
-# frozen_string_literal: true
-
-module GrafanaApiHelpers
- def valid_grafana_dashboard_link(base_url)
- base_url +
- '/d/XDaNK6amz/gitlab-omnibus-redis' \
- '?from=1570397739557&to=1570484139557' \
- '&var-instance=localhost:9121&panelId=8'
- end
-
- def stub_dashboard_request(base_url, path: '/api/dashboards/uid/XDaNK6amz', body: nil)
- body ||= fixture_file('grafana/dashboard_response.json')
-
- stub_request(:get, "#{base_url}#{path}")
- .to_return(
- status: 200,
- body: body,
- headers: { 'Content-Type' => 'application/json' }
- )
- end
-
- def stub_datasource_request(base_url, path: '/api/datasources/name/GitLab%20Omnibus', body: nil)
- body ||= fixture_file('grafana/datasource_response.json')
-
- stub_request(:get, "#{base_url}#{path}")
- .to_return(
- status: 200,
- body: body,
- headers: { 'Content-Type' => 'application/json' }
- )
- end
-
- def stub_all_grafana_proxy_requests(base_url)
- stub_request(:any, %r{#{base_url}/api/datasources/proxy})
- .to_return(
- status: 200,
- body: fixture_file('grafana/proxy_response.json'),
- headers: { 'Content-Type' => 'application/json' }
- )
- end
-end
diff --git a/spec/support/rspec_order_todo.yml b/spec/support/rspec_order_todo.yml
index b98dd75e7e0a6c4597cefc1bf53849e92fc98f1e..d755d11f791ff177a21cfc3af88eb897bbda68be 100644
--- a/spec/support/rspec_order_todo.yml
+++ b/spec/support/rspec_order_todo.yml
@@ -3672,7 +3672,6 @@
- './spec/graphql/resolvers/project_packages_resolver_spec.rb'
- './spec/graphql/resolvers/project_resolver_spec.rb'
- './spec/graphql/resolvers/projects/fork_targets_resolver_spec.rb'
-- './spec/graphql/resolvers/projects/grafana_integration_resolver_spec.rb'
- './spec/graphql/resolvers/projects/jira_projects_resolver_spec.rb'
- './spec/graphql/resolvers/projects_resolver_spec.rb'
- './spec/graphql/resolvers/projects/services_resolver_spec.rb'
@@ -5591,9 +5590,6 @@
- './spec/lib/gitlab/zoom_link_extractor_spec.rb'
- './spec/lib/google_api/auth_spec.rb'
- './spec/lib/google_api/cloud_platform/client_spec.rb'
-- './spec/lib/grafana/client_spec.rb'
-- './spec/lib/grafana/time_window_spec.rb'
-- './spec/lib/grafana/validator_spec.rb'
- './spec/lib/initializer_connections_spec.rb'
- './spec/lib/json_web_token/hmac_token_spec.rb'
- './spec/lib/json_web_token/rsa_token_spec.rb'
@@ -5957,7 +5953,6 @@
- './spec/models/generic_commit_status_spec.rb'
- './spec/models/gpg_key_spec.rb'
- './spec/models/gpg_key_subkey_spec.rb'
-- './spec/models/grafana_integration_spec.rb'
- './spec/models/group/crm_settings_spec.rb'
- './spec/models/group_custom_attribute_spec.rb'
- './spec/models/group_deploy_keys_group_spec.rb'