Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
heptapod
heptapod
Commits
f837aaaf7fac
Commit
f837aaaf
authored
Nov 02, 2017
by
Kamil Trzcinski
Browse files
Improve backend structure of data
parent
d05bf53d5eb6
Changes
22
Hide whitespace changes
Inline
Side-by-side
app/controllers/projects/clusters/applications_controller.rb
0 → 100644
View file @
f837aaaf
class
Projects::Clusters::ApplicationsController
<
Projects
::
ApplicationController
before_action
:cluster
before_action
:application_class
,
only:
[
:create
]
before_action
:authorize_read_cluster!
before_action
:authorize_create_cluster!
,
only:
[
:create
]
def
new
end
def
create
return
render_404
if
application
new_application
=
application_class
.
create
(
cluster:
cluster
)
respond_to
do
|
format
|
format
.
json
do
if
new_application
.
persisted?
head
:ok
else
head
:bad_request
end
end
end
end
private
def
cluster
@cluster
||=
project
.
clusters
.
find_by
(
cluster_id:
params
[
:cluster_id
]).
present
(
current_user:
current_user
)
end
def
application_class
Clusters
::
Cluster
::
Applications
.
find
(
params
[
:application
])
end
def
application
application_class
.
find_by
(
cluster:
cluster
)
end
end
app/models/clusters/applications/helm.rb
0 → 100644
View file @
f837aaaf
module
Clusters
module
Applications
class
Helm
<
ActiveRecord
::
Base
self
.
table_name
=
'clusters_applications_helm'
NAME
=
'helm'
.
freeze
include
::
Clusters
::
Concerns
::
AppStatus
belongs_to
:cluser
,
class_name:
'Clusters::Cluster'
,
foreign_key: :cluster_id
default_value_for
:version
,
Gitlab
::
Clusters
::
Helm
::
HELM_VERSION
def
name
NAME
end
end
end
end
app/models/clusters/cluster.rb
View file @
f837aaaf
...
...
@@ -4,6 +4,10 @@
self
.
table_name
=
'clusters'
APPLICATIONS
=
{
Clusters
::
Applications
::
Helm
::
NAME
=>
Clusters
::
Applications
::
Helm
}
belongs_to
:user
has_many
:cluster_projects
,
class_name:
'Clusters::Project'
...
...
@@ -15,9 +19,11 @@
# We have to ":destroy" it today to ensure that we clean also the Kubernetes Integration
has_one
:platform_kubernetes
,
class_name:
'Clusters::Platforms::Kubernetes'
,
autosave:
true
,
dependent: :destroy
# rubocop:disable Cop/ActiveRecordDependent
has_one
:application_helm
,
class_name:
'Clusters::Applications::Helm'
accepts_nested_attributes_for
:provider_gcp
,
update_only:
true
accepts_nested_attributes_for
:platform_kubernetes
,
update_only:
true
validates
:name
,
cluster_name:
true
validate
:restrict_modification
,
on: :update
...
...
@@ -18,10 +24,9 @@
accepts_nested_attributes_for
:provider_gcp
,
update_only:
true
accepts_nested_attributes_for
:platform_kubernetes
,
update_only:
true
validates
:name
,
cluster_name:
true
validate
:restrict_modification
,
on: :update
delegate
:status
,
to: :provider
,
allow_nil:
true
delegate
:status_reason
,
to: :provider
,
allow_nil:
true
delegate
:status_name
,
to: :provider
,
allow_nil:
true
delegate
:on_creation?
,
to: :provider
,
allow_nil:
true
...
...
@@ -38,6 +43,14 @@
scope
:enabled
,
->
{
where
(
enabled:
true
)
}
scope
:disabled
,
->
{
where
(
enabled:
false
)
}
def
status_name
if
provider
provider
.
status_name
else
:created
end
end
def
provider
return
provider_gcp
if
gcp?
end
...
...
@@ -53,6 +66,10 @@
end
alias_method
:project
,
:first_project
def
kubeclient
platform_kubernetes
.
kubeclient
if
kubernetes?
end
private
def
restrict_modification
...
...
app/models/clusters/kubernetes.rb
deleted
100644 → 0
View file @
d05bf53d
module
Clusters
module
Kubernetes
def
self
.
table_name_prefix
'clusters_kubernetes_'
end
def
self
.
app
(
app_name
)
case
app_name
when
HelmApp
::
NAME
HelmApp
else
raise
ArgumentError
,
"Unknown app
#{
app_name
}
"
end
end
end
end
app/models/clusters/kubernetes/helm_app.rb
deleted
100644 → 0
View file @
d05bf53d
module
Clusters
module
Kubernetes
class
HelmApp
<
ActiveRecord
::
Base
NAME
=
'helm'
.
freeze
include
::
Clusters
::
Concerns
::
AppStatus
belongs_to
:kubernetes_service
,
class_name:
'KubernetesService'
,
foreign_key: :service_id
default_value_for
:version
,
Gitlab
::
Clusters
::
Helm
::
HELM_VERSION
alias_method
:cluster
,
:kubernetes_service
def
name
NAME
end
end
end
end
app/models/clusters/platforms/kubernetes.rb
View file @
f837aaaf
...
...
@@ -60,6 +60,10 @@
self
.
class
.
namespace_for_project
(
project
)
if
project
end
def
kubeclient
@kubeclient
||=
kubernetes_service
.
kubeclient
if
manages_kubernetes_service?
end
private
def
enforce_namespace_to_lower_case
...
...
app/models/project.rb
View file @
f837aaaf
...
...
@@ -189,6 +189,7 @@
has_one
:cluster_project
,
class_name:
'Clusters::Project'
has_one
:cluster
,
through: :cluster_project
,
class_name:
'Clusters::Cluster'
has_many
:clusters
,
through: :cluster_project
,
class_name:
'Clusters::Cluster'
# Container repositories need to remove data from the container registry,
# which is not managed by the DB. Hence we're still using dependent: :destroy
...
...
app/models/project_services/kubernetes_service.rb
View file @
f837aaaf
...
...
@@ -3,8 +3,6 @@
include
Gitlab
::
Kubernetes
include
ReactiveCaching
has_one
:helm_app
,
class_name:
'Clusters::Kubernetes::HelmApp'
,
foreign_key: :service_id
self
.
reactive_cache_key
=
->
(
service
)
{
[
service
.
class
.
model_name
.
singular
,
service
.
project_id
]
}
# Namespace defaults to the project path, but can be overridden in case that
...
...
@@ -138,8 +136,8 @@
{
pods:
read_pods
}
end
def
helm
Gitlab
::
Clusters
::
Helm
.
new
(
build_kubeclient!
)
def
kubeclient
@kubeclient
||=
build_kubeclient!
end
TEMPLATE_PLACEHOLDER
=
'Kubernetes namespace'
.
freeze
...
...
app/presenters/clusters/cluster_presenter.rb
View file @
f837aaaf
...
...
@@ -5,5 +5,11 @@
def
gke_cluster_url
"https://console.cloud.google.com/kubernetes/clusters/details/
#{
provider
.
zone
}
/
#{
name
}
"
if
gcp?
end
def
applications
Clusters
::
Cluster
::
APPLICATIONS
.
map
do
|
key
,
value
|
value
.
find_by
(
cluster_id:
id
)
end
.
compact
end
end
end
app/serializers/cluster_app_entity.rb
0 → 100644
View file @
f837aaaf
class
ClusterAppEntity
<
Grape
::
Entity
expose
:name
expose
:status_name
,
as: :status
expose
:status_reason
end
app/serializers/cluster_entity.rb
View file @
f837aaaf
...
...
@@ -3,16 +3,5 @@
expose
:status_name
,
as: :status
expose
:status_reason
expose
:applications
do
|
cluster
,
options
|
if
cluster
.
created?
{
helm:
{
status:
'installed'
},
ingress:
{
status:
'error'
,
status_reason:
'Missing namespace'
},
runner:
{
status:
'installing'
},
prometheus:
{
status:
'installable'
}
}
else
{}
end
end
expose
:applications
,
using:
ClusterAppEntity
end
app/services/clusters/base_helm_service.rb
View file @
f837aaaf
...
...
@@ -8,6 +8,7 @@
protected
def
helm
return
@helm
if
defined?
(
@helm
)
def
cluster
app
.
cluster
end
...
...
@@ -13,5 +14,10 @@
@helm
=
@app
.
cluster
.
helm
def
kubeclient
cluster
.
kubeclient
end
def
helm_api
@helm
||=
Gitlab
::
Clusters
::
Helm
.
new
(
kubeclient
)
end
end
end
app/services/clusters/fetch_app_installation_status_service.rb
View file @
f837aaaf
...
...
@@ -3,8 +3,8 @@
def
execute
return
unless
app
.
installing?
phase
=
helm
.
installation_status
(
app
)
log
=
helm
.
installation_log
(
app
)
if
phase
==
'Failed'
phase
=
helm
_api
.
installation_status
(
app
)
log
=
helm
_api
.
installation_log
(
app
)
if
phase
==
'Failed'
yield
(
phase
,
log
)
if
block_given?
rescue
KubeException
=>
ke
app
.
make_errored!
(
"Kubernetes error:
#{
ke
.
message
}
"
)
unless
app
.
errored?
...
...
app/services/clusters/finalize_app_installation_service.rb
View file @
f837aaaf
module
Clusters
class
FinalizeAppInstallationService
<
BaseHelmService
def
execute
helm
.
delete_installation_pod!
(
app
)
helm
_api
.
delete_installation_pod!
(
app
)
app
.
make_errored!
(
'Installation aborted'
)
if
aborted?
end
...
...
app/services/clusters/install_app_service.rb
View file @
f837aaaf
...
...
@@ -4,10 +4,11 @@
return
unless
app
.
scheduled?
begin
helm
.
install
(
app
)
helm_api
.
install
(
app
)
if
app
.
make_installing
ClusterWaitForAppInstallationWorker
.
perform_in
(
ClusterWaitForAppInstallationWorker
::
INITIAL_INTERVAL
,
app
.
name
,
app
.
id
)
else
app
.
make_errored!
(
"Failed to update app record;
#{
app
.
errors
}
"
)
end
...
...
@@ -8,10 +9,9 @@
if
app
.
make_installing
ClusterWaitForAppInstallationWorker
.
perform_in
(
ClusterWaitForAppInstallationWorker
::
INITIAL_INTERVAL
,
app
.
name
,
app
.
id
)
else
app
.
make_errored!
(
"Failed to update app record;
#{
app
.
errors
}
"
)
end
rescue
KubeException
=>
ke
app
.
make_errored!
(
"Kubernetes error:
#{
ke
.
message
}
"
)
rescue
StandardError
=>
e
...
...
app/workers/concerns/cluster_app.rb
View file @
f837aaaf
...
...
@@ -3,8 +3,9 @@
included
do
def
find_app
(
app_name
,
id
)
app
=
Clusters
::
Kubernetes
.
app
(
app_name
).
find
(
id
)
yield
(
app
)
if
block_given?
Clusters
::
Applications
.
const_get
(
app_name
.
classify
).
find
(
id
).
try
do
|
app
|
yield
(
app
)
if
block_given?
end
end
end
end
config/routes/project.rb
View file @
f837aaaf
...
...
@@ -190,6 +190,10 @@
member
do
get
:status
,
format: :json
scope
'*application'
do
resource
:applications
,
only:
[
:create
]
end
end
end
...
...
db/migrate/20171031100710_create_clusters_kubernetes_helm_apps.rb
View file @
f837aaaf
class
CreateClustersKubernetesHelmApps
<
ActiveRecord
::
Migration
def
change
create_table
:clusters_
kubernete
s_helm
_apps
do
|
t
|
t
.
integer
:status
,
null:
false
create_table
:clusters_
application
s_helm
do
|
t
|
t
.
references
:cluster
,
null:
false
,
unique:
true
,
foreign_key:
{
on_delete: :cascade
}
t
.
datetime_with_timezone
:created_at
,
null:
false
t
.
datetime_with_timezone
:updated_at
,
null:
false
...
...
@@ -5,8 +5,8 @@
t
.
datetime_with_timezone
:created_at
,
null:
false
t
.
datetime_with_timezone
:updated_at
,
null:
false
t
.
references
:service
,
index:
true
,
null:
false
,
foreign_key:
{
on_delete: :cascade
}
t
.
integer
:status
,
null:
false
t
.
string
:version
,
null:
false
t
.
text
:status_reason
end
...
...
db/schema.rb
View file @
f837aaaf
...
...
@@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord
::
Schema
.
define
(
version:
201710
17145932
)
do
ActiveRecord
::
Schema
.
define
(
version:
201710
31100710
)
do
# These are extensions that must be enabled in order to support this database
enable_extension
"plpgsql"
...
...
@@ -464,9 +464,7 @@
create_table
"cluster_platforms_kubernetes"
,
force: :cascade
do
|
t
|
t
.
integer
"cluster_id"
,
null:
false
t
.
datetime
"created_at"
,
null:
false
t
.
datetime
"updated_at"
,
null:
false
t
.
text
"api_url"
t
.
string
"api_url"
t
.
text
"ca_cert"
t
.
string
"namespace"
t
.
string
"username"
...
...
@@ -474,6 +472,8 @@
t
.
string
"encrypted_password_iv"
t
.
text
"encrypted_token"
t
.
string
"encrypted_token_iv"
t
.
datetime_with_timezone
"created_at"
,
null:
false
t
.
datetime_with_timezone
"updated_at"
,
null:
false
end
add_index
"cluster_platforms_kubernetes"
,
[
"cluster_id"
],
name:
"index_cluster_platforms_kubernetes_on_cluster_id"
,
unique:
true
,
using: :btree
...
...
@@ -491,9 +491,6 @@
create_table
"cluster_providers_gcp"
,
force: :cascade
do
|
t
|
t
.
integer
"cluster_id"
,
null:
false
t
.
integer
"status"
t
.
integer
"num_nodes"
,
null:
false
t
.
datetime
"created_at"
,
null:
false
t
.
datetime
"updated_at"
,
null:
false
t
.
text
"status_reason"
t
.
string
"gcp_project_id"
,
null:
false
t
.
string
"zone"
,
null:
false
...
...
@@ -497,8 +494,9 @@
t
.
text
"status_reason"
t
.
string
"gcp_project_id"
,
null:
false
t
.
string
"zone"
,
null:
false
t
.
integer
"num_nodes"
,
null:
false
t
.
string
"machine_type"
t
.
string
"operation_id"
t
.
string
"endpoint"
t
.
text
"encrypted_access_token"
t
.
string
"encrypted_access_token_iv"
...
...
@@ -500,10 +498,12 @@
t
.
string
"machine_type"
t
.
string
"operation_id"
t
.
string
"endpoint"
t
.
text
"encrypted_access_token"
t
.
string
"encrypted_access_token_iv"
t
.
datetime_with_timezone
"created_at"
,
null:
false
t
.
datetime_with_timezone
"updated_at"
,
null:
false
end
add_index
"cluster_providers_gcp"
,
[
"cluster_id"
],
name:
"index_cluster_providers_gcp_on_cluster_id"
,
unique:
true
,
using: :btree
create_table
"clusters"
,
force: :cascade
do
|
t
|
...
...
@@ -505,8 +505,10 @@
end
add_index
"cluster_providers_gcp"
,
[
"cluster_id"
],
name:
"index_cluster_providers_gcp_on_cluster_id"
,
unique:
true
,
using: :btree
create_table
"clusters"
,
force: :cascade
do
|
t
|
t
.
integer
"user_id"
,
null:
false
t
.
integer
"user_id"
t
.
boolean
"enabled"
,
default:
true
t
.
string
"name"
,
null:
false
t
.
integer
"provider_type"
t
.
integer
"platform_type"
...
...
@@ -511,8 +513,6 @@
t
.
integer
"provider_type"
t
.
integer
"platform_type"
t
.
datetime
"created_at"
,
null:
false
t
.
datetime
"updated_at"
,
null:
false
t
.
boolean
"enabled"
,
default:
true
t
.
string
"name"
,
null:
false
t
.
datetime_with_timezone
"created_at"
,
null:
false
t
.
datetime_with_timezone
"updated_at"
,
null:
false
end
...
...
@@ -517,7 +517,13 @@
end
add_index
"clusters"
,
[
"enabled"
],
name:
"index_clusters_on_enabled"
,
using: :btree
add_index
"clusters"
,
[
"user_id"
],
name:
"index_clusters_on_user_id"
,
using: :btree
create_table
"clusters_applications_helm"
,
force: :cascade
do
|
t
|
t
.
integer
"cluster_id"
,
null:
false
t
.
datetime_with_timezone
"created_at"
,
null:
false
t
.
datetime_with_timezone
"updated_at"
,
null:
false
t
.
integer
"status"
,
null:
false
t
.
string
"version"
,
null:
false
t
.
text
"status_reason"
end
create_table
"container_repositories"
,
force: :cascade
do
|
t
|
t
.
integer
"project_id"
,
null:
false
...
...
@@ -1872,6 +1878,7 @@
add_foreign_key
"cluster_projects"
,
"projects"
,
on_delete: :cascade
add_foreign_key
"cluster_providers_gcp"
,
"clusters"
,
on_delete: :cascade
add_foreign_key
"clusters"
,
"users"
,
on_delete: :nullify
add_foreign_key
"clusters_applications_helm"
,
"clusters"
,
on_delete: :cascade
add_foreign_key
"container_repositories"
,
"projects"
add_foreign_key
"deploy_keys_projects"
,
"projects"
,
name:
"fk_58a901ca7e"
,
on_delete: :cascade
add_foreign_key
"deployments"
,
"projects"
,
name:
"fk_b9a3851b82"
,
on_delete: :cascade
...
...
spec/models/clusters/kubernetes/helm_app_spec.rb
View file @
f837aaaf
require
'rails_helper'
require_relative
'../kubernetes_spec'
RSpec
.
describe
Clusters
::
Kubernete
s
::
Helm
App
,
type: :model
do
RSpec
.
describe
Clusters
::
Application
s
::
Helm
,
type: :model
do
it_behaves_like
'a registered kubernetes app'
it
{
is_expected
.
to
belong_to
(
:kubernetes_service
)
}
...
...
Prev
1
2
Next
Write
Preview
Supports
Markdown
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