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
ff0feee5
Commit
ff0feee5
authored
Oct 14, 2019
by
rpereira2
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Use Stepable in PodLogsService
- This will simplify the service and make it easier to modify in the future.
parent
a7c66cac
Changes
8
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
143 additions
and
81 deletions
+143
-81
app/models/concerns/stepable.rb
app/models/concerns/stepable.rb
+4
-4
ee/app/controllers/ee/projects/environments_controller.rb
ee/app/controllers/ee/projects/environments_controller.rb
+1
-1
ee/app/services/pod_logs_service.rb
ee/app/services/pod_logs_service.rb
+51
-14
ee/spec/controllers/projects/environments_controller_spec.rb
ee/spec/controllers/projects/environments_controller_spec.rb
+2
-2
ee/spec/services/pod_logs_service_spec.rb
ee/spec/services/pod_logs_service_spec.rb
+15
-3
lib/gitlab/database_importers/self_monitoring/project/create_service.rb
...abase_importers/self_monitoring/project/create_service.rb
+45
-42
locale/gitlab.pot
locale/gitlab.pot
+6
-0
spec/models/concerns/stepable_spec.rb
spec/models/concerns/stepable_spec.rb
+19
-15
No files found.
app/models/concerns/stepable.rb
View file @
ff0feee5
...
@@ -11,15 +11,15 @@ module Stepable
...
@@ -11,15 +11,15 @@ module Stepable
initial_result
=
{}
initial_result
=
{}
steps
.
inject
(
initial_result
)
do
|
previous_result
,
callback
|
steps
.
inject
(
initial_result
)
do
|
previous_result
,
callback
|
result
=
method
(
callback
).
call
result
=
method
(
callback
).
call
(
previous_result
)
if
result
[
:status
]
==
:error
if
result
[
:status
]
!=
:success
result
[
:
failed
_step
]
=
callback
result
[
:
last
_step
]
=
callback
break
result
break
result
end
end
previous_result
.
merge
(
result
)
result
end
end
end
end
...
...
ee/app/controllers/ee/projects/environments_controller.rb
View file @
ff0feee5
...
@@ -20,7 +20,7 @@ module EE
...
@@ -20,7 +20,7 @@ module EE
result
=
PodLogsService
.
new
(
environment
,
params:
params
.
permit!
).
execute
result
=
PodLogsService
.
new
(
environment
,
params:
params
.
permit!
).
execute
if
result
.
nil?
if
result
[
:status
]
==
:processing
head
:accepted
head
:accepted
elsif
result
[
:status
]
==
:success
elsif
result
[
:status
]
==
:success
render
json:
{
render
json:
{
...
...
ee/app/services/pod_logs_service.rb
View file @
ff0feee5
# frozen_string_literal: true
# frozen_string_literal: true
class
PodLogsService
<
::
BaseService
class
PodLogsService
<
::
BaseService
include
Stepable
attr_reader
:environment
attr_reader
:environment
K8S_NAME_MAX_LENGTH
=
253
K8S_NAME_MAX_LENGTH
=
253
PARAMS
=
%w(pod_name container_name)
.
freeze
PARAMS
=
%w(pod_name container_name)
.
freeze
SUCCESS_RETURN_KEYS
=
[
:status
,
:logs
].
freeze
steps
:check_param_lengths
,
:check_deployment_platform
,
:check_pod_name
,
:pod_logs
,
:split_logs
,
:filter_return_keys
def
initialize
(
environment
,
params:
{})
def
initialize
(
environment
,
params:
{})
@environment
=
environment
@environment
=
environment
@params
=
filter_params
(
params
.
dup
).
to_hash
@params
=
filter_params
(
params
.
dup
).
to_hash
end
end
def
execute
def
execute
execute_steps
end
private
def
check_param_lengths
(
_result
)
pod_name
=
params
[
'pod_name'
].
presence
pod_name
=
params
[
'pod_name'
].
presence
container_name
=
params
[
'container_name'
].
presence
container_name
=
params
[
'container_name'
].
presence
...
@@ -24,34 +41,54 @@ class PodLogsService < ::BaseService
...
@@ -24,34 +41,54 @@ class PodLogsService < ::BaseService
' %{max_length} chars'
%
{
max_length:
K8S_NAME_MAX_LENGTH
}))
' %{max_length} chars'
%
{
max_length:
K8S_NAME_MAX_LENGTH
}))
end
end
success
(
pod_name:
pod_name
,
container_name:
container_name
)
end
def
check_deployment_platform
(
result
)
unless
environment
.
deployment_platform
unless
environment
.
deployment_platform
return
error
(
'No deployment platform'
)
return
error
(
_
(
'No deployment platform available'
)
)
end
end
success
(
result
)
end
def
check_pod_name
(
result
)
# If pod_name is not received as parameter, get the pod logs of the first
# If pod_name is not received as parameter, get the pod logs of the first
# pod of this environment.
# pod of this environment.
pod_name
||=
environment
.
pod_names
&
.
first
result
[
:pod_name
]
||=
environment
.
pod_names
&
.
first
pod_logs
(
pod_name
,
container_name
)
unless
result
[
:pod_name
]
return
error
(
_
(
'No pods available'
))
end
end
private
success
(
result
)
end
def
pod_logs
(
pod_name
,
container_name
)
def
pod_logs
(
result
)
res
ult
=
environment
.
deployment_platform
.
read_pod_logs
(
res
ponse
=
environment
.
deployment_platform
.
read_pod_logs
(
pod_name
,
result
[
:pod_name
]
,
namespace
,
namespace
,
container:
container_name
container:
result
[
:container_name
]
)
)
return
unless
result
return
{
status: :processing
}
unless
response
result
[
:logs
]
=
response
[
:logs
]
if
res
ult
[
:status
]
==
:error
if
res
ponse
[
:status
]
==
:error
error
(
res
ult
[
:error
])
error
(
res
ponse
[
:error
])
else
else
success
(
result
)
end
end
def
split_logs
(
result
)
logs
=
split_by_newline
(
result
[
:logs
])
logs
=
split_by_newline
(
result
[
:logs
])
success
(
logs:
logs
)
success
(
logs:
logs
)
end
end
def
filter_return_keys
(
result
)
result
.
slice
(
*
SUCCESS_RETURN_KEYS
)
end
end
def
filter_params
(
params
)
def
filter_params
(
params
)
...
...
ee/spec/controllers/projects/environments_controller_spec.rb
View file @
ff0feee5
...
@@ -170,8 +170,8 @@ describe Projects::EnvironmentsController do
...
@@ -170,8 +170,8 @@ describe Projects::EnvironmentsController do
it_behaves_like
'resource not found'
,
'Pod not found'
it_behaves_like
'resource not found'
,
'Pod not found'
end
end
context
'when service returns
nil
'
do
context
'when service returns
status processing
'
do
let
(
:service_result
)
{
nil
}
let
(
:service_result
)
{
{
status: :processing
}
}
it
'renders accepted'
do
it
'renders accepted'
do
get
:logs
,
params:
environment_params
(
pod_name:
pod_name
,
format: :json
)
get
:logs
,
params:
environment_params
(
pod_name:
pod_name
,
format: :json
)
...
...
ee/spec/services/pod_logs_service_spec.rb
View file @
ff0feee5
...
@@ -79,7 +79,7 @@ describe PodLogsService do
...
@@ -79,7 +79,7 @@ describe PodLogsService do
end
end
context
'without deployment platform'
do
context
'without deployment platform'
do
it_behaves_like
'error'
,
'No deployment platform'
it_behaves_like
'error'
,
'No deployment platform
available
'
end
end
context
'with deployment platform'
do
context
'with deployment platform'
do
...
@@ -137,6 +137,18 @@ describe PodLogsService do
...
@@ -137,6 +137,18 @@ describe PodLogsService do
subject
.
execute
subject
.
execute
end
end
context
'when there are no pods'
do
before
do
allow_any_instance_of
(
Gitlab
::
Kubernetes
::
RolloutStatus
).
to
receive
(
:instances
)
.
and_return
([])
end
it
'returns error'
do
expect
(
result
[
:status
]).
to
eq
(
:error
)
expect
(
result
[
:message
]).
to
eq
(
'No pods available'
)
end
end
end
end
context
'when error is returned'
do
context
'when error is returned'
do
...
@@ -152,8 +164,8 @@ describe PodLogsService do
...
@@ -152,8 +164,8 @@ describe PodLogsService do
.
and_return
(
nil
)
.
and_return
(
nil
)
end
end
it
'returns
nil
'
do
it
'returns
processing
'
do
expect
(
result
).
to
eq
(
nil
)
expect
(
result
).
to
eq
(
status: :processing
,
last_step: :pod_logs
)
end
end
end
end
end
end
...
...
lib/gitlab/database_importers/self_monitoring/project/create_service.rb
View file @
ff0feee5
...
@@ -33,7 +33,7 @@ module Gitlab
...
@@ -33,7 +33,7 @@ module Gitlab
if
result
[
:status
]
==
:success
if
result
[
:status
]
==
:success
result
result
elsif
STEPS_ALLOWED_TO_FAIL
.
include?
(
result
[
:
failed
_step
])
elsif
STEPS_ALLOWED_TO_FAIL
.
include?
(
result
[
:
last
_step
])
success
success
else
else
raise
StandardError
,
result
[
:message
]
raise
StandardError
,
result
[
:message
]
...
@@ -42,121 +42,124 @@ module Gitlab
...
@@ -42,121 +42,124 @@ module Gitlab
private
private
def
validate_application_settings
def
validate_application_settings
(
_result
)
return
success
if
application_settings
return
success
if
application_settings
log_error
(
'No application_settings found'
)
log_error
(
'No application_settings found'
)
error
(
_
(
'No application_settings found'
))
error
(
_
(
'No application_settings found'
))
end
end
def
validate_project_created
def
validate_project_created
(
result
)
return
success
unless
project_created?
return
success
(
result
)
unless
project_created?
log_error
(
'Project already created'
)
log_error
(
'Project already created'
)
error
(
_
(
'Project already created'
))
error
(
_
(
'Project already created'
))
end
end
def
validate_admins
def
validate_admins
(
result
)
unless
instance_admins
.
any?
unless
instance_admins
.
any?
log_error
(
'No active admin user found'
)
log_error
(
'No active admin user found'
)
return
error
(
_
(
'No active admin user found'
))
return
error
(
_
(
'No active admin user found'
))
end
end
success
success
(
result
)
end
end
def
create_group
def
create_group
(
result
)
if
project_created?
if
project_created?
log_info
(
_
(
'Instance administrators group already exists'
))
log_info
(
_
(
'Instance administrators group already exists'
))
@group
=
application_settings
.
instance_administration_project
.
owner
result
[
:group
]
=
application_settings
.
instance_administration_project
.
owner
return
success
(
group:
@group
)
return
success
(
result
)
end
end
@group
=
::
Groups
::
CreateService
.
new
(
group_owner
,
create_group_params
).
execute
result
[
:group
]
=
::
Groups
::
CreateService
.
new
(
group_owner
,
create_group_params
).
execute
if
@group
.
persisted?
if
result
[
:group
]
.
persisted?
success
(
group:
@group
)
success
(
result
)
else
else
error
(
_
(
'Could not create group'
))
error
(
_
(
'Could not create group'
))
end
end
end
end
def
create_project
def
create_project
(
result
)
if
project_created?
if
project_created?
log_info
(
'Instance administration project already exists'
)
log_info
(
'Instance administration project already exists'
)
@project
=
application_settings
.
instance_administration_project
result
[
:project
]
=
application_settings
.
instance_administration_project
return
success
(
project:
projec
t
)
return
success
(
resul
t
)
end
end
@project
=
::
Projects
::
CreateService
.
new
(
group_owner
,
create_project_params
).
execute
result
[
:project
]
=
::
Projects
::
CreateService
.
new
(
group_owner
,
create_project_params
(
result
[
:group
])
).
execute
if
project
.
persisted?
if
result
[
:project
]
.
persisted?
success
(
project:
projec
t
)
success
(
resul
t
)
else
else
log_error
(
"Could not create instance administration project. Errors: %{errors}"
%
{
errors:
project
.
errors
.
full_messages
})
log_error
(
"Could not create instance administration project. Errors: %{errors}"
%
{
errors:
result
[
:project
]
.
errors
.
full_messages
})
error
(
_
(
'Could not create project'
))
error
(
_
(
'Could not create project'
))
end
end
end
end
def
save_project_id
def
save_project_id
(
result
)
return
success
if
project_created?
return
success
if
project_created?
result
=
application_settings
.
update
(
instance_administration_project_id:
@project
.
id
)
response
=
application_settings
.
update
(
instance_administration_project_id:
result
[
:project
].
id
)
if
res
ult
if
res
ponse
success
success
(
result
)
else
else
log_error
(
"Could not save instance administration project ID, errors: %{errors}"
%
{
errors:
application_settings
.
errors
.
full_messages
})
log_error
(
"Could not save instance administration project ID, errors: %{errors}"
%
{
errors:
application_settings
.
errors
.
full_messages
})
error
(
_
(
'Could not save project ID'
))
error
(
_
(
'Could not save project ID'
))
end
end
end
end
def
add_group_members
def
add_group_members
(
result
)
members
=
@group
.
add_users
(
members_to_add
,
Gitlab
::
Access
::
MAINTAINER
)
group
=
result
[
:group
]
members
=
group
.
add_users
(
members_to_add
(
group
),
Gitlab
::
Access
::
MAINTAINER
)
errors
=
members
.
flat_map
{
|
member
|
member
.
errors
.
full_messages
}
errors
=
members
.
flat_map
{
|
member
|
member
.
errors
.
full_messages
}
if
errors
.
any?
if
errors
.
any?
log_error
(
'Could not add admins as members to self-monitoring project. Errors: %{errors}'
%
{
errors:
errors
})
log_error
(
'Could not add admins as members to self-monitoring project. Errors: %{errors}'
%
{
errors:
errors
})
error
(
_
(
'Could not add admins as members'
))
error
(
_
(
'Could not add admins as members'
))
else
else
success
success
(
result
)
end
end
end
end
def
add_to_whitelist
def
add_to_whitelist
(
result
)
return
success
unless
prometheus_enabled?
return
success
(
result
)
unless
prometheus_enabled?
return
success
unless
prometheus_listen_address
.
present?
return
success
(
result
)
unless
prometheus_listen_address
.
present?
uri
=
parse_url
(
internal_prometheus_listen_address_uri
)
uri
=
parse_url
(
internal_prometheus_listen_address_uri
)
return
error
(
_
(
'Prometheus listen_address in config/gitlab.yml is not a valid URI'
))
unless
uri
return
error
(
_
(
'Prometheus listen_address in config/gitlab.yml is not a valid URI'
))
unless
uri
application_settings
.
add_to_outbound_local_requests_whitelist
([
uri
.
normalized_host
])
application_settings
.
add_to_outbound_local_requests_whitelist
([
uri
.
normalized_host
])
res
ult
=
application_settings
.
save
res
ponse
=
application_settings
.
save
if
res
ult
if
res
ponse
# Expire the Gitlab::CurrentSettings cache after updating the whitelist.
# Expire the Gitlab::CurrentSettings cache after updating the whitelist.
# This happens automatically in an after_commit hook, but in migrations,
# This happens automatically in an after_commit hook, but in migrations,
# the after_commit hook only runs at the end of the migration.
# the after_commit hook only runs at the end of the migration.
Gitlab
::
CurrentSettings
.
expire_current_application_settings
Gitlab
::
CurrentSettings
.
expire_current_application_settings
success
success
(
result
)
else
else
log_error
(
"Could not add prometheus URL to whitelist, errors: %{errors}"
%
{
errors:
application_settings
.
errors
.
full_messages
})
log_error
(
"Could not add prometheus URL to whitelist, errors: %{errors}"
%
{
errors:
application_settings
.
errors
.
full_messages
})
error
(
_
(
'Could not add prometheus URL to whitelist'
))
error
(
_
(
'Could not add prometheus URL to whitelist'
))
end
end
end
end
def
add_prometheus_manual_configuration
def
add_prometheus_manual_configuration
(
result
)
return
success
unless
prometheus_enabled?
return
success
(
result
)
unless
prometheus_enabled?
return
success
unless
prometheus_listen_address
.
present?
return
success
(
result
)
unless
prometheus_listen_address
.
present?
service
=
project
.
find_or_initialize_service
(
'prometheus'
)
service
=
result
[
:project
]
.
find_or_initialize_service
(
'prometheus'
)
unless
service
.
update
(
prometheus_service_attributes
)
unless
service
.
update
(
prometheus_service_attributes
)
log_error
(
'Could not save prometheus manual configuration for self-monitoring project. Errors: %{errors}'
%
{
errors:
service
.
errors
.
full_messages
})
log_error
(
'Could not save prometheus manual configuration for self-monitoring project. Errors: %{errors}'
%
{
errors:
service
.
errors
.
full_messages
})
return
error
(
_
(
'Could not save prometheus manual configuration'
))
return
error
(
_
(
'Could not save prometheus manual configuration'
))
end
end
success
success
(
result
)
end
end
def
application_settings
def
application_settings
...
@@ -196,11 +199,11 @@ module Gitlab
...
@@ -196,11 +199,11 @@ module Gitlab
instance_admins
.
first
instance_admins
.
first
end
end
def
members_to_add
def
members_to_add
(
group
)
# Exclude admins who are already members of group because
# Exclude admins who are already members of group because
# `
@
group.add_users(users)` returns an error if the users parameter contains
# `group.add_users(users)` returns an error if the users parameter contains
# users who are already members of the group.
# users who are already members of the group.
instance_admins
-
@
group
.
members
.
collect
(
&
:user
)
instance_admins
-
group
.
members
.
collect
(
&
:user
)
end
end
def
create_group_params
def
create_group_params
...
@@ -217,13 +220,13 @@ module Gitlab
...
@@ -217,13 +220,13 @@ module Gitlab
)
)
end
end
def
create_project_params
def
create_project_params
(
group
)
{
{
initialize_with_readme:
true
,
initialize_with_readme:
true
,
visibility_level:
VISIBILITY_LEVEL
,
visibility_level:
VISIBILITY_LEVEL
,
name:
PROJECT_NAME
,
name:
PROJECT_NAME
,
description:
"This project is automatically generated and will be used to help monitor this GitLab instance. [More information](
#{
docs_path
}
)"
,
description:
"This project is automatically generated and will be used to help monitor this GitLab instance. [More information](
#{
docs_path
}
)"
,
namespace_id:
@
group
.
id
namespace_id:
group
.
id
}
}
end
end
...
...
locale/gitlab.pot
View file @
ff0feee5
...
@@ -10896,6 +10896,9 @@ msgstr ""
...
@@ -10896,6 +10896,9 @@ msgstr ""
msgid "No data to display"
msgid "No data to display"
msgstr ""
msgstr ""
msgid "No deployment platform available"
msgstr ""
msgid "No deployments found"
msgid "No deployments found"
msgstr ""
msgstr ""
...
@@ -10962,6 +10965,9 @@ msgstr ""
...
@@ -10962,6 +10965,9 @@ msgstr ""
msgid "No parent group"
msgid "No parent group"
msgstr ""
msgstr ""
msgid "No pods available"
msgstr ""
msgid "No preview for this file type"
msgid "No preview for this file type"
msgstr ""
msgstr ""
...
...
spec/models/concerns/stepable_spec.rb
View file @
ff0feee5
...
@@ -7,6 +7,8 @@ describe Stepable do
...
@@ -7,6 +7,8 @@ describe Stepable do
Class
.
new
do
Class
.
new
do
include
Stepable
include
Stepable
attr_writer
:return_non_success
steps
:method1
,
:method2
,
:method3
steps
:method1
,
:method2
,
:method3
def
execute
def
execute
...
@@ -15,18 +17,18 @@ describe Stepable do
...
@@ -15,18 +17,18 @@ describe Stepable do
private
private
def
method1
def
method1
(
_result
)
{
status: :success
}
{
status: :success
}
end
end
def
method2
def
method2
(
result
)
return
{
status: :
error
}
unless
@pa
ss
return
{
status: :
not_a_success
}
if
@return_non_succe
ss
{
status: :success
,
variable1:
'var1'
}
result
.
merge
({
status: :success
,
variable1:
'var1'
,
excluded_variable:
'a'
})
end
end
def
method3
def
method3
(
result
)
{
status: :success
,
variable2:
'var2'
}
result
.
except
(
:excluded_variable
).
merge
({
status: :success
,
variable2:
'var2'
})
end
end
end
end
end
end
...
@@ -41,8 +43,8 @@ describe Stepable do
...
@@ -41,8 +43,8 @@ describe Stepable do
private
private
def
appended_method1
def
appended_method1
(
previous_result
)
{
status: :success
}
previous_result
.
merge
({
status: :success
})
end
end
end
end
end
end
...
@@ -51,21 +53,19 @@ describe Stepable do
...
@@ -51,21 +53,19 @@ describe Stepable do
described_class
.
prepend
(
prepended_module
)
described_class
.
prepend
(
prepended_module
)
end
end
it
'stops after the first error'
do
it
'stops after the first non success status'
do
subject
.
return_non_success
=
true
expect
(
subject
).
not_to
receive
(
:method3
)
expect
(
subject
).
not_to
receive
(
:method3
)
expect
(
subject
).
not_to
receive
(
:appended_method1
)
expect
(
subject
).
not_to
receive
(
:appended_method1
)
expect
(
subject
.
execute
).
to
eq
(
expect
(
subject
.
execute
).
to
eq
(
status: :
error
,
status: :
not_a_success
,
failed
_step: :method2
last
_step: :method2
)
)
end
end
context
'when all methods return success'
do
context
'when all methods return success'
do
before
do
subject
.
instance_variable_set
(
:@pass
,
true
)
end
it
'calls all methods in order'
do
it
'calls all methods in order'
do
expect
(
subject
).
to
receive
(
:method1
).
and_call_original
.
ordered
expect
(
subject
).
to
receive
(
:method1
).
and_call_original
.
ordered
expect
(
subject
).
to
receive
(
:method2
).
and_call_original
.
ordered
expect
(
subject
).
to
receive
(
:method2
).
and_call_original
.
ordered
...
@@ -82,6 +82,10 @@ describe Stepable do
...
@@ -82,6 +82,10 @@ describe Stepable do
variable2:
'var2'
variable2:
'var2'
)
)
end
end
it
'can modify results of previous steps'
do
expect
(
subject
.
execute
).
not_to
include
(
excluded_variable:
'a'
)
end
end
end
context
'with multiple stepable classes'
do
context
'with multiple stepable classes'
do
...
...
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