Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
39aa9458
Commit
39aa9458
authored
Feb 04, 2019
by
Peter Leitzen
Committed by
Sean McGivern
Feb 04, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Implement alerting setting model
parent
fc3cb7aa
Changes
16
Show whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
394 additions
and
13 deletions
+394
-13
db/schema.rb
db/schema.rb
+6
-0
ee/app/controllers/ee/projects/settings/operations_controller.rb
...controllers/ee/projects/settings/operations_controller.rb
+23
-2
ee/app/models/alerting/project_alerting_setting.rb
ee/app/models/alerting/project_alerting_setting.rb
+28
-0
ee/app/models/ee/project.rb
ee/app/models/ee/project.rb
+2
-0
ee/app/services/ee/projects/operations/update_service.rb
ee/app/services/ee/projects/operations/update_service.rb
+20
-1
ee/app/services/projects/prometheus/alerts/notify_service.rb
ee/app/services/projects/prometheus/alerts/notify_service.rb
+13
-2
ee/changelogs/unreleased/9258-support-alerts-from-external-prometheus-servers-model.yml
...support-alerts-from-external-prometheus-servers-model.yml
+5
-0
ee/config/routes/project.rb
ee/config/routes/project.rb
+8
-0
ee/db/migrate/20190121140658_create_project_alerting_settings.rb
...igrate/20190121140658_create_project_alerting_settings.rb
+15
-0
ee/spec/controllers/projects/settings/operations_controller_spec.rb
...ntrollers/projects/settings/operations_controller_spec.rb
+101
-0
ee/spec/factories/project_alerting_settings.rb
ee/spec/factories/project_alerting_settings.rb
+8
-0
ee/spec/lib/gitlab/import_export/all_models.yml
ee/spec/lib/gitlab/import_export/all_models.yml
+1
-0
ee/spec/models/alerting/project_alerting_setting_spec.rb
ee/spec/models/alerting/project_alerting_setting_spec.rb
+40
-0
ee/spec/models/project_spec.rb
ee/spec/models/project_spec.rb
+1
-0
ee/spec/services/projects/operations/update_service_spec.rb
ee/spec/services/projects/operations/update_service_spec.rb
+93
-3
ee/spec/services/projects/prometheus/alerts/notify_service_spec.rb
...ervices/projects/prometheus/alerts/notify_service_spec.rb
+30
-5
No files found.
db/schema.rb
View file @
39aa9458
...
...
@@ -2166,6 +2166,11 @@ ActiveRecord::Schema.define(version: 20190124200344) do
t
.
index
[
"name"
],
name:
"index_programming_languages_on_name"
,
unique:
true
,
using: :btree
end
create_table
"project_alerting_settings"
,
primary_key:
"project_id"
,
id: :integer
,
force: :cascade
do
|
t
|
t
.
string
"encrypted_token"
,
null:
false
t
.
string
"encrypted_token_iv"
,
null:
false
end
create_table
"project_authorizations"
,
id:
false
,
force: :cascade
do
|
t
|
t
.
integer
"user_id"
,
null:
false
t
.
integer
"project_id"
,
null:
false
...
...
@@ -3462,6 +3467,7 @@ ActiveRecord::Schema.define(version: 20190124200344) do
add_foreign_key
"personal_access_tokens"
,
"users"
add_foreign_key
"pool_repositories"
,
"projects"
,
column:
"source_project_id"
,
on_delete: :nullify
add_foreign_key
"pool_repositories"
,
"shards"
,
on_delete: :restrict
add_foreign_key
"project_alerting_settings"
,
"projects"
,
on_delete: :cascade
add_foreign_key
"project_authorizations"
,
"projects"
,
on_delete: :cascade
add_foreign_key
"project_authorizations"
,
"users"
,
on_delete: :cascade
add_foreign_key
"project_auto_devops"
,
"projects"
,
on_delete: :cascade
...
...
ee/app/controllers/ee/projects/settings/operations_controller.rb
View file @
39aa9458
...
...
@@ -8,13 +8,34 @@ module EE
extend
ActiveSupport
::
Concern
prepended
do
before_action
:authorize_read_prometheus_alerts!
,
only:
[
:reset_alerting_token
]
respond_to
:json
,
only:
[
:reset_alerting_token
]
def
reset_alerting_token
result
=
::
Projects
::
Operations
::
UpdateService
.
new
(
project
,
current_user
,
alerting_params
)
.
execute
if
result
[
:status
]
==
:success
render
json:
{
token:
project
.
alerting_setting
.
token
}
else
render
json:
{},
status: :unprocessable_entity
end
end
helper_method
:tracing_setting
private
def
alerting_params
{
alerting_setting_attributes:
{
regenerate_token:
true
}
}
end
def
tracing_setting
@tracing_setting
||=
project
.
tracing_setting
||
project
.
build_tracing_setting
end
private
:tracing_setting
end
override
:permitted_project_params
...
...
ee/app/models/alerting/project_alerting_setting.rb
0 → 100644
View file @
39aa9458
# frozen_string_literal: true
require
'securerandom'
module
Alerting
class
ProjectAlertingSetting
<
ApplicationRecord
belongs_to
:project
validates
:token
,
presence:
true
attr_encrypted
:token
,
mode: :per_attribute_iv
,
key:
Settings
.
attr_encrypted_db_key_base_truncated
,
algorithm:
'aes-256-gcm'
before_validation
:ensure_token
private
def
ensure_token
self
.
token
||=
generate_token
end
def
generate_token
SecureRandom
.
hex
end
end
end
ee/app/models/ee/project.rb
View file @
39aa9458
...
...
@@ -40,6 +40,7 @@ module EE
has_one
:github_service
has_one
:gitlab_slack_application_service
has_one
:tracing_setting
,
class_name:
'ProjectTracingSetting'
has_one
:alerting_setting
,
inverse_of: :project
,
class_name:
'Alerting::ProjectAlertingSetting'
has_one
:feature_usage
,
class_name:
'ProjectFeatureUsage'
has_many
:reviews
,
inverse_of: :project
...
...
@@ -118,6 +119,7 @@ module EE
delegate
:store_security_reports_available?
,
to: :namespace
accepts_nested_attributes_for
:tracing_setting
,
update_only:
true
,
allow_destroy:
true
accepts_nested_attributes_for
:alerting_setting
,
update_only:
true
end
class_methods
do
...
...
ee/app/services/ee/projects/operations/update_service.rb
View file @
39aa9458
...
...
@@ -9,7 +9,9 @@ module EE
override
:project_update_params
def
project_update_params
super
.
merge
(
tracing_setting_params
)
super
.
merge
(
tracing_setting_params
)
.
merge
(
alerting_setting_params
)
end
private
...
...
@@ -22,6 +24,23 @@ module EE
{
tracing_setting_attributes:
attr
.
merge
(
_destroy:
destroy
)
}
end
def
alerting_setting_params
return
{}
unless
can?
(
current_user
,
:read_prometheus_alerts
,
project
)
attr
=
params
[
:alerting_setting_attributes
]
return
{}
unless
attr
regenerate_token
=
attr
.
delete
(
:regenerate_token
)
if
regenerate_token
attr
[
:token
]
=
nil
else
attr
=
attr
.
except
(
:token
)
# rubocop: disable CodeReuse/ActiveRecord
end
{
alerting_setting_attributes:
attr
}
end
end
end
end
...
...
ee/app/services/projects/prometheus/alerts/notify_service.rb
View file @
39aa9458
...
...
@@ -34,10 +34,21 @@ module Projects
end
def
valid_alert_manager_token?
(
token
)
# We don't support token authorization for manual installations.
valid_for_manual?
(
token
)
||
valid_for_managed?
(
token
)
end
def
valid_for_manual?
(
token
)
prometheus
=
project
.
find_or_initialize_service
(
'prometheus'
)
return
true
if
prometheus
.
manual_configuration?
return
false
unless
prometheus
.
manual_configuration?
if
setting
=
project
.
alerting_setting
compare_token
(
token
,
setting
.
token
)
else
token
.
nil?
end
end
def
valid_for_managed?
(
token
)
prometheus_application
=
available_prometheus_application
(
project
)
return
false
unless
prometheus_application
...
...
ee/changelogs/unreleased/9258-support-alerts-from-external-prometheus-servers-model.yml
0 → 100644
View file @
39aa9458
---
title
:
Support alerts from external Prometheus servers
merge_request
:
9334
author
:
type
:
added
ee/config/routes/project.rb
View file @
39aa9458
...
...
@@ -36,6 +36,14 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do
end
end
end
namespace
:settings
do
resource
:operations
,
only:
[
:show
,
:update
]
do
member
do
post
:reset_alerting_token
end
end
end
end
end
end
...
...
ee/db/migrate/20190121140658_create_project_alerting_settings.rb
0 → 100644
View file @
39aa9458
# frozen_string_literal: true
class
CreateProjectAlertingSettings
<
ActiveRecord
::
Migration
[
5.0
]
include
Gitlab
::
Database
::
MigrationHelpers
DOWNTIME
=
false
def
change
create_table
:project_alerting_settings
,
id: :int
,
primary_key: :project_id
do
|
t
|
t
.
string
:encrypted_token
,
null:
false
t
.
string
:encrypted_token_iv
,
null:
false
t
.
foreign_key
:projects
,
column: :project_id
,
on_delete: :cascade
end
end
end
ee/spec/controllers/projects/settings/operations_controller_spec.rb
View file @
39aa9458
...
...
@@ -232,6 +232,107 @@ describe Projects::Settings::OperationsController do
end
end
describe
'POST reset_alerting_token'
do
let
(
:project
)
{
create
(
:project
)
}
before
do
stub_licensed_features
(
prometheus_alerts:
true
)
project
.
add_maintainer
(
user
)
end
context
'with existing alerting setting'
do
let!
(
:alerting_setting
)
do
create
(
:project_alerting_setting
,
project:
project
)
end
let!
(
:old_token
)
{
alerting_setting
.
token
}
it
'returns newly reset token'
do
reset_alerting_token
expect
(
response
).
to
have_gitlab_http_status
(
:ok
)
expect
(
json_response
[
'token'
]).
to
eq
(
alerting_setting
.
reload
.
token
)
expect
(
old_token
).
not_to
eq
(
alerting_setting
.
token
)
end
end
context
'without existing alerting setting'
do
it
'creates a token'
do
reset_alerting_token
expect
(
response
).
to
have_gitlab_http_status
(
:ok
)
expect
(
project
.
alerting_setting
).
not_to
be_nil
expect
(
json_response
[
'token'
]).
to
eq
(
project
.
alerting_setting
.
token
)
end
end
context
'when update fails'
do
let
(
:operations_update_service
)
{
spy
(
:operations_update_service
)
}
let
(
:alerting_params
)
do
{
alerting_setting_attributes:
{
regenerate_token:
true
}
}
end
before
do
expect
(
::
Projects
::
Operations
::
UpdateService
)
.
to
receive
(
:new
).
with
(
project
,
user
,
alerting_params
)
.
and_return
(
operations_update_service
)
expect
(
operations_update_service
).
to
receive
(
:execute
)
.
and_return
(
status: :error
)
end
it
'returns unprocessable_entity'
do
reset_alerting_token
expect
(
response
).
to
have_gitlab_http_status
(
:unprocessable_entity
)
expect
(
json_response
).
to
be_empty
end
end
context
'with insufficient permissions'
do
before
do
project
.
add_reporter
(
user
)
end
it
'returns 404'
do
reset_alerting_token
expect
(
response
).
to
have_gitlab_http_status
(
:not_found
)
end
end
context
'as an anonymous user'
do
before
do
sign_out
(
user
)
end
it
'returns unauthorized status'
do
reset_alerting_token
expect
(
response
).
to
have_gitlab_http_status
(
:unauthorized
)
end
end
context
'without a license'
do
before
do
stub_licensed_features
(
prometheus_alerts:
false
)
end
it
'returns 404'
do
reset_alerting_token
expect
(
response
).
to
have_gitlab_http_status
(
:not_found
)
end
end
private
def
reset_alerting_token
post
:reset_alerting_token
,
params:
project_params
(
project
),
format: :json
end
end
private
def
project_params
(
project
,
params
=
{})
...
...
ee/spec/factories/project_alerting_settings.rb
0 → 100644
View file @
39aa9458
# frozen_string_literal: true
FactoryBot
.
define
do
factory
:project_alerting_setting
,
class:
Alerting
::
ProjectAlertingSetting
do
project
token
'access_token_123'
end
end
ee/spec/lib/gitlab/import_export/all_models.yml
View file @
39aa9458
...
...
@@ -77,6 +77,7 @@ project:
-
packages
-
package_files
-
tracing_setting
-
alerting_setting
-
webide_pipelines
-
reviews
prometheus_metrics
:
...
...
ee/spec/models/alerting/project_alerting_setting_spec.rb
0 → 100644
View file @
39aa9458
# frozen_string_literal: true
require
'spec_helper'
describe
Alerting
::
ProjectAlertingSetting
do
set
(
:project
)
{
create
(
:project
)
}
subject
{
create
(
:project_alerting_setting
,
project:
project
)
}
describe
'Associations'
do
it
{
is_expected
.
to
belong_to
(
:project
)
}
end
describe
'#token'
do
context
'when set'
do
let
(
:token
)
{
SecureRandom
.
hex
}
subject
do
create
(
:project_alerting_setting
,
project:
project
,
token:
token
)
end
it
'reads the token'
do
expect
(
subject
.
token
).
to
eq
(
token
)
expect
(
subject
.
encrypted_token
).
not_to
be_nil
expect
(
subject
.
encrypted_token_iv
).
not_to
be_nil
end
end
context
'when not set'
do
before
do
subject
.
token
=
nil
end
it
'generates a token before validation'
do
expect
(
subject
).
to
be_valid
expect
(
subject
.
token
).
to
match
(
/\A\h{32}\z/
)
end
end
end
end
ee/spec/models/project_spec.rb
View file @
39aa9458
...
...
@@ -16,6 +16,7 @@ describe Project do
it
{
is_expected
.
to
have_one
(
:import_state
).
class_name
(
'ProjectImportState'
)
}
it
{
is_expected
.
to
have_one
(
:repository_state
).
class_name
(
'ProjectRepositoryState'
).
inverse_of
(
:project
)
}
it
{
is_expected
.
to
have_one
(
:alerting_setting
).
class_name
(
'Alerting::ProjectAlertingSetting'
)
}
it
{
is_expected
.
to
have_many
(
:reviews
).
inverse_of
(
:project
)
}
it
{
is_expected
.
to
have_many
(
:path_locks
)
}
...
...
ee/spec/services/projects/operations/update_service_spec.rb
View file @
39aa9458
...
...
@@ -3,12 +3,12 @@
require
'spec_helper'
describe
Projects
::
Operations
::
UpdateService
do
s
ubject
{
described_class
.
new
(
project
,
user
,
params
)
}
s
et
(
:user
)
{
create
(
:user
)
}
let
(
:project
)
{
create
(
:project
)
}
let
(
:result
)
{
subject
.
execute
}
set
(
:user
)
{
create
(
:user
)
}
set
(
:project
)
{
create
(
:project
)
}
subject
{
described_class
.
new
(
project
,
user
,
params
)
}
describe
'#execute'
do
context
'tracing setting'
do
...
...
@@ -98,5 +98,95 @@ describe Projects::Operations::UpdateService do
end
end
end
context
'alerting setting'
do
before
do
stub_licensed_features
(
prometheus_alerts:
true
)
project
.
add_maintainer
(
user
)
end
shared_examples
'no operation'
do
it
'does nothing'
do
expect
(
result
[
:status
]).
to
eq
(
:success
)
expect
(
project
.
reload
.
alerting_setting
).
to
be_nil
end
end
context
'with valid params'
do
let
(
:params
)
{
{
alerting_setting_attributes:
alerting_params
}
}
shared_examples
'setting creation'
do
it
'creates a setting'
do
expect
(
project
.
alerting_setting
).
to
be_nil
expect
(
result
[
:status
]).
to
eq
(
:success
)
expect
(
project
.
reload
.
alerting_setting
).
not_to
be_nil
end
end
context
'when regenerate_token is not set'
do
let
(
:alerting_params
)
{
{
token:
'some token'
}
}
context
'with an existing setting'
do
let!
(
:alerting_setting
)
do
create
(
:project_alerting_setting
,
project:
project
)
end
it
'ignores provided token'
do
expect
(
result
[
:status
]).
to
eq
(
:success
)
expect
(
project
.
reload
.
alerting_setting
.
token
)
.
to
eq
(
alerting_setting
.
token
)
end
end
context
'without an existing setting'
do
it_behaves_like
'setting creation'
end
end
context
'when regenerate_token is set'
do
let
(
:alerting_params
)
{
{
regenerate_token:
true
}
}
context
'with an existing setting'
do
let
(
:token
)
{
'some token'
}
let!
(
:alerting_setting
)
do
create
(
:project_alerting_setting
,
project:
project
,
token:
token
)
end
it
'regenerates token'
do
expect
(
result
[
:status
]).
to
eq
(
:success
)
expect
(
project
.
reload
.
alerting_setting
.
token
).
not_to
eq
(
token
)
end
end
context
'without an existing setting'
do
it_behaves_like
'setting creation'
context
'without license'
do
before
do
stub_licensed_features
(
prometheus_alerts:
false
)
end
it_behaves_like
'no operation'
end
context
'with insufficient permissions'
do
before
do
project
.
add_reporter
(
user
)
end
it_behaves_like
'no operation'
end
end
end
end
context
'with empty params'
do
let
(
:params
)
{
{}
}
it_behaves_like
'no operation'
end
end
end
end
ee/spec/services/projects/prometheus/alerts/notify_service_spec.rb
View file @
39aa9458
...
...
@@ -70,8 +70,6 @@ describe Projects::Prometheus::Alerts::NotifyService do
end
with_them
do
let
(
:alert_manager_token
)
{
token_input
}
before
do
cluster
=
create
(
:cluster
,
:provided_by_user
,
projects:
[
project
],
...
...
@@ -138,11 +136,38 @@ describe Projects::Prometheus::Alerts::NotifyService do
end
context
'with manual prometheus installation'
do
using
RSpec
::
Parameterized
::
TableSyntax
where
(
:alerting_setting
,
:configured_token
,
:token_input
,
:result
)
do
true
|
token
|
token
|
:success
true
|
token
|
'x'
|
:failure
true
|
token
|
nil
|
:failure
false
|
nil
|
nil
|
:success
false
|
nil
|
token
|
:failure
end
with_them
do
let
(
:alert_manager_token
)
{
token_input
}
before
do
create
(
:prometheus_service
,
project:
project
)
if
alerting_setting
create
(
:project_alerting_setting
,
project:
project
,
token:
configured_token
)
end
end
case
result
=
params
[
:result
]
when
:success
it_behaves_like
'notifies alerts'
when
:failure
it_behaves_like
'no notifications'
else
raise
"invalid result:
#{
result
.
inspect
}
"
end
end
end
end
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment