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
59e62c0a
Commit
59e62c0a
authored
Jul 08, 2019
by
James Lopez
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'clusters-group-cte' into 'master'
Clusters hierarchy CTE See merge request gitlab-org/gitlab-ce!30063
parents
299387e3
3bc76511
Changes
5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
216 additions
and
3 deletions
+216
-3
app/models/clusters/clusters_hierarchy.rb
app/models/clusters/clusters_hierarchy.rb
+104
-0
app/models/concerns/deployment_platform.rb
app/models/concerns/deployment_platform.rb
+17
-2
changelogs/unreleased/clusters-group-cte.yml
changelogs/unreleased/clusters-group-cte.yml
+5
-0
spec/models/clusters/clusters_hierarchy_spec.rb
spec/models/clusters/clusters_hierarchy_spec.rb
+73
-0
spec/models/concerns/deployment_platform_spec.rb
spec/models/concerns/deployment_platform_spec.rb
+17
-1
No files found.
app/models/clusters/clusters_hierarchy.rb
0 → 100644
View file @
59e62c0a
# frozen_string_literal: true
module
Clusters
class
ClustersHierarchy
DEPTH_COLUMN
=
:depth
def
initialize
(
clusterable
)
@clusterable
=
clusterable
end
# Returns clusters in order from deepest to highest group
def
base_and_ancestors
cte
=
recursive_cte
cte_alias
=
cte
.
table
.
alias
(
model
.
table_name
)
model
.
unscoped
.
where
(
'clusters.id IS NOT NULL'
)
.
with
.
recursive
(
cte
.
to_arel
)
.
from
(
cte_alias
)
.
order
(
DEPTH_COLUMN
=>
:asc
)
end
private
attr_reader
:clusterable
def
recursive_cte
cte
=
Gitlab
::
SQL
::
RecursiveCTE
.
new
(
:clusters_cte
)
base_query
=
case
clusterable
when
::
Group
group_clusters_base_query
when
::
Project
project_clusters_base_query
else
raise
ArgumentError
,
"unknown type for
#{
clusterable
}
"
end
cte
<<
base_query
cte
<<
parent_query
(
cte
)
cte
end
def
group_clusters_base_query
group_parent_id_alias
=
alias_as_column
(
groups
[
:parent_id
],
'group_parent_id'
)
join_sources
=
::
Group
.
left_joins
(
:clusters
).
join_sources
model
.
unscoped
.
select
([
clusters_star
,
group_parent_id_alias
,
"1 AS
#{
DEPTH_COLUMN
}
"
])
.
where
(
groups
[
:id
].
eq
(
clusterable
.
id
))
.
from
(
groups
)
.
joins
(
join_sources
)
end
def
project_clusters_base_query
projects
=
::
Project
.
arel_table
project_parent_id_alias
=
alias_as_column
(
projects
[
:namespace_id
],
'group_parent_id'
)
join_sources
=
::
Project
.
left_joins
(
:clusters
).
join_sources
model
.
unscoped
.
select
([
clusters_star
,
project_parent_id_alias
,
"1 AS
#{
DEPTH_COLUMN
}
"
])
.
where
(
projects
[
:id
].
eq
(
clusterable
.
id
))
.
from
(
projects
)
.
joins
(
join_sources
)
end
def
parent_query
(
cte
)
group_parent_id_alias
=
alias_as_column
(
groups
[
:parent_id
],
'group_parent_id'
)
model
.
unscoped
.
select
([
clusters_star
,
group_parent_id_alias
,
cte
.
table
[
DEPTH_COLUMN
]
+
1
])
.
from
([
cte
.
table
,
groups
])
.
joins
(
'LEFT OUTER JOIN cluster_groups ON cluster_groups.group_id = namespaces.id'
)
.
joins
(
'LEFT OUTER JOIN clusters ON cluster_groups.cluster_id = clusters.id'
)
.
where
(
groups
[
:id
].
eq
(
cte
.
table
[
:group_parent_id
]))
end
def
model
Clusters
::
Cluster
end
def
clusters
@clusters
||=
model
.
arel_table
end
def
groups
@groups
||=
::
Group
.
arel_table
end
def
clusters_star
@clusters_star
||=
clusters
[
Arel
.
star
]
end
def
alias_as_column
(
value
,
alias_to
)
Arel
::
Nodes
::
As
.
new
(
value
,
Arel
::
Nodes
::
SqlLiteral
.
new
(
alias_to
))
end
end
end
app/models/concerns/deployment_platform.rb
View file @
59e62c0a
...
...
@@ -12,11 +12,26 @@ module DeploymentPlatform
private
def
find_deployment_platform
(
environment
)
find_cluster_platform_kubernetes
(
environment:
environment
)
||
find_group_cluster_platform_kubernetes
(
environment:
environment
)
||
find_platform_kubernetes
(
environment
)
||
find_instance_cluster_platform_kubernetes
(
environment:
environment
)
end
def
find_platform_kubernetes
(
environment
)
if
Feature
.
enabled?
(
:clusters_cte
)
find_platform_kubernetes_with_cte
(
environment
)
else
find_cluster_platform_kubernetes
(
environment:
environment
)
||
find_group_cluster_platform_kubernetes
(
environment:
environment
)
end
end
# EE would override this and utilize environment argument
def
find_platform_kubernetes_with_cte
(
_environment
)
Clusters
::
ClustersHierarchy
.
new
(
self
).
base_and_ancestors
.
enabled
.
default_environment
.
first
&
.
platform_kubernetes
end
# EE would override this and utilize environment argument
def
find_cluster_platform_kubernetes
(
environment:
nil
)
clusters
.
enabled
.
default_environment
...
...
changelogs/unreleased/clusters-group-cte.yml
0 → 100644
View file @
59e62c0a
---
title
:
Use CTE to fetch clusters hierarchy in single query
merge_request
:
30063
author
:
type
:
performance
spec/models/clusters/clusters_hierarchy_spec.rb
0 → 100644
View file @
59e62c0a
# frozen_string_literal: true
require
'spec_helper'
describe
Clusters
::
ClustersHierarchy
do
describe
'#base_and_ancestors'
do
def
base_and_ancestors
(
clusterable
)
described_class
.
new
(
clusterable
).
base_and_ancestors
end
context
'project in nested group with clusters at every level'
do
let!
(
:cluster
)
{
create
(
:cluster
,
:project
,
projects:
[
project
])
}
let!
(
:child
)
{
create
(
:cluster
,
:group
,
groups:
[
child_group
])
}
let!
(
:parent
)
{
create
(
:cluster
,
:group
,
groups:
[
parent_group
])
}
let!
(
:ancestor
)
{
create
(
:cluster
,
:group
,
groups:
[
ancestor_group
])
}
let
(
:ancestor_group
)
{
create
(
:group
)
}
let
(
:parent_group
)
{
create
(
:group
,
parent:
ancestor_group
)
}
let
(
:child_group
)
{
create
(
:group
,
parent:
parent_group
)
}
let
(
:project
)
{
create
(
:project
,
group:
child_group
)
}
it
'returns clusters for project'
do
expect
(
base_and_ancestors
(
project
)).
to
eq
([
cluster
,
child
,
parent
,
ancestor
])
end
it
'returns clusters for child_group'
do
expect
(
base_and_ancestors
(
child_group
)).
to
eq
([
child
,
parent
,
ancestor
])
end
it
'returns clusters for parent_group'
do
expect
(
base_and_ancestors
(
parent_group
)).
to
eq
([
parent
,
ancestor
])
end
it
'returns clusters for ancestor_group'
do
expect
(
base_and_ancestors
(
ancestor_group
)).
to
eq
([
ancestor
])
end
end
context
'project in a namespace'
do
let!
(
:cluster
)
{
create
(
:cluster
,
:project
)
}
it
'returns clusters for project'
do
expect
(
base_and_ancestors
(
cluster
.
project
)).
to
eq
([
cluster
])
end
end
context
'project in nested group with clusters at some levels'
do
let!
(
:child
)
{
create
(
:cluster
,
:group
,
groups:
[
child_group
])
}
let!
(
:ancestor
)
{
create
(
:cluster
,
:group
,
groups:
[
ancestor_group
])
}
let
(
:ancestor_group
)
{
create
(
:group
)
}
let
(
:parent_group
)
{
create
(
:group
,
parent:
ancestor_group
)
}
let
(
:child_group
)
{
create
(
:group
,
parent:
parent_group
)
}
let
(
:project
)
{
create
(
:project
,
group:
child_group
)
}
it
'returns clusters for project'
do
expect
(
base_and_ancestors
(
project
)).
to
eq
([
child
,
ancestor
])
end
it
'returns clusters for child_group'
do
expect
(
base_and_ancestors
(
child_group
)).
to
eq
([
child
,
ancestor
])
end
it
'returns clusters for parent_group'
do
expect
(
base_and_ancestors
(
parent_group
)).
to
eq
([
ancestor
])
end
it
'returns clusters for ancestor_group'
do
expect
(
base_and_ancestors
(
ancestor_group
)).
to
eq
([
ancestor
])
end
end
end
end
spec/models/concerns/deployment_platform_spec.rb
View file @
59e62c0a
...
...
@@ -5,7 +5,7 @@ require 'rails_helper'
describe
DeploymentPlatform
do
let
(
:project
)
{
create
(
:project
)
}
describe
'#deployment_platform'
do
shared_examples
'#deployment_platform'
do
subject
{
project
.
deployment_platform
}
context
'with no Kubernetes configuration on CI/CD, no Kubernetes Service'
do
...
...
@@ -84,4 +84,20 @@ describe DeploymentPlatform do
end
end
end
context
'legacy implementation'
do
before
do
stub_feature_flags
(
clusters_cte:
false
)
end
include_examples
'#deployment_platform'
end
context
'CTE implementation'
do
before
do
stub_feature_flags
(
clusters_cte:
true
)
end
include_examples
'#deployment_platform'
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