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
0
Merge Requests
0
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
Boxiang Sun
gitlab-ce
Commits
ccf09824
Commit
ccf09824
authored
Nov 01, 2017
by
Kamil Trzcinski
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Slim down Platforms::Kubernetes, and instead make it instrument KubernetesService
parent
0c417ef0
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
43 additions
and
128 deletions
+43
-128
app/models/clusters/cluster.rb
app/models/clusters/cluster.rb
+5
-2
app/models/clusters/platforms/kubernetes.rb
app/models/clusters/platforms/kubernetes.rb
+33
-108
app/services/clusters/create_service.rb
app/services/clusters/create_service.rb
+3
-16
db/schema.rb
db/schema.rb
+2
-2
No files found.
app/models/clusters/cluster.rb
View file @
ccf09824
...
@@ -9,8 +9,11 @@ module Clusters
...
@@ -9,8 +9,11 @@ module Clusters
has_many
:cluster_projects
,
class_name:
'Clusters::Project'
has_many
:cluster_projects
,
class_name:
'Clusters::Project'
has_many
:projects
,
through: :cluster_projects
,
class_name:
'::Project'
has_many
:projects
,
through: :cluster_projects
,
class_name:
'::Project'
has_one
:provider_gcp
,
class_name:
'Clusters::Providers::Gcp'
# we force autosave to happen when we save `Cluster` model
has_one
:platform_kubernetes
,
class_name:
'Clusters::Platforms::Kubernetes'
has_one
:provider_gcp
,
class_name:
'Clusters::Providers::Gcp'
,
autosave:
true
# 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
accepts_nested_attributes_for
:provider_gcp
,
update_only:
true
accepts_nested_attributes_for
:provider_gcp
,
update_only:
true
accepts_nested_attributes_for
:platform_kubernetes
,
update_only:
true
accepts_nested_attributes_for
:platform_kubernetes
,
update_only:
true
...
...
app/models/clusters/platforms/kubernetes.rb
View file @
ccf09824
...
@@ -2,11 +2,8 @@ module Clusters
...
@@ -2,11 +2,8 @@ module Clusters
module
Platforms
module
Platforms
class
Kubernetes
<
ActiveRecord
::
Base
class
Kubernetes
<
ActiveRecord
::
Base
include
Gitlab
::
CurrentSettings
include
Gitlab
::
CurrentSettings
include
Gitlab
::
Kubernetes
include
ReactiveCaching
self
.
table_name
=
'cluster_platforms_kubernetes'
self
.
table_name
=
'cluster_platforms_kubernetes'
self
.
reactive_cache_key
=
->
(
kubernetes
)
{
[
kubernetes
.
class
.
model_name
.
singular
,
kubernetes
.
cluster_id
]
}
belongs_to
:cluster
,
inverse_of: :platform_kubernetes
,
class_name:
'Clusters::Cluster'
belongs_to
:cluster
,
inverse_of: :platform_kubernetes
,
class_name:
'Clusters::Cluster'
...
@@ -30,17 +27,24 @@ module Clusters
...
@@ -30,17 +27,24 @@ module Clusters
message:
Gitlab
::
Regex
.
kubernetes_namespace_regex_message
message:
Gitlab
::
Regex
.
kubernetes_namespace_regex_message
}
}
validates
:api_url
,
url:
true
,
presence:
true
# We expect to be `active?` only when enabled and cluster is created (the api_url is assigned)
validates
:token
,
presence:
true
with_options
presence:
true
,
if: :active?
do
validates
:api_url
,
url:
true
,
presence:
true
validates
:token
,
presence:
true
end
after_save
:clear_reactive_cache!
# TODO: Glue code till we migrate Kubernetes Integration into Platforms::Kubernetes
after_save
:update_kubernetes_integration!
after_destroy
:destroy_kubernetes_integration!
alias_attribute
:ca_pem
,
:ca_cert
alias_attribute
:ca_pem
,
:ca_cert
delegate
:project
,
to: :cluster
,
allow_nil:
true
delegate
:project
,
to: :cluster
,
allow_nil:
true
delegate
:enabled?
,
to: :cluster
,
allow_nil:
true
delegate
:enabled?
,
to: :cluster
,
allow_nil:
true
alias_method
:active?
,
:enabled?
def
active?
enabled?
&&
api_url
.
present?
end
class
<<
self
class
<<
self
def
namespace_for_project
(
project
)
def
namespace_for_project
(
project
)
...
@@ -60,122 +64,43 @@ module Clusters
...
@@ -60,122 +64,43 @@ module Clusters
self
.
class
.
namespace_for_project
(
project
)
if
project
self
.
class
.
namespace_for_project
(
project
)
if
project
end
end
def
predefined_variables
private
config
=
YAML
.
dump
(
kubeconfig
)
variables
=
[
{
key:
'KUBE_URL'
,
value:
api_url
,
public:
true
},
{
key:
'KUBE_TOKEN'
,
value:
token
,
public:
false
},
{
key:
'KUBE_NAMESPACE'
,
value:
actual_namespace
,
public:
true
},
{
key:
'KUBECONFIG'
,
value:
config
,
public:
false
,
file:
true
}
]
if
ca_pem
.
present?
variables
<<
{
key:
'KUBE_CA_PEM'
,
value:
ca_pem
,
public:
true
}
variables
<<
{
key:
'KUBE_CA_PEM_FILE'
,
value:
ca_pem
,
public:
true
,
file:
true
}
end
variables
end
# Constructs a list of terminals from the reactive cache
#
# Returns nil if the cache is empty, in which case you should try again a
# short time later
def
terminals
(
environment
)
with_reactive_cache
do
|
data
|
pods
=
filter_by_label
(
data
[
:pods
],
app:
environment
.
slug
)
terminals
=
pods
.
flat_map
{
|
pod
|
terminals_for_pod
(
api_url
,
actual_namespace
,
pod
)
}
terminals
.
each
{
|
terminal
|
add_terminal_auth
(
terminal
,
terminal_auth
)
}
end
end
# Caches resources in the namespace so other calls don't need to block on
# network access
def
calculate_reactive_cache
return
unless
active?
&&
project
&&
!
project
.
pending_delete?
# We may want to cache extra things in the future
{
pods:
read_pods
}
end
def
kubeconfig
to_kubeconfig
(
url:
api_url
,
namespace:
actual_namespace
,
token:
token
,
ca_pem:
ca_pem
)
end
def
read_secrets
kubeclient
=
build_kubeclient!
kubeclient
.
get_secrets
.
as_json
def
enforce_namespace_to_lower_case
self
.
namespace
=
self
.
namespace
&
.
downcase
end
end
#
Returns a hash of all pods in the namespace
#
TODO: glue code till we migrate Kubernetes Service into Platforms::Kubernetes class
def
read_pods
def
manages_kubernetes_service?
kubeclient
=
build_kubeclient!
return
true
unless
kubernetes_service
&
.
active?
kubeclient
.
get_pods
(
namespace:
actual_namespace
).
as_json
kubernetes_service
.
api_url
==
api_url
rescue
KubeException
=>
err
raise
err
unless
err
.
error_code
==
404
[]
end
end
def
kubeclient_ssl_options
def
destroy_kubernetes_integration!
opts
=
{
verify_ssl:
OpenSSL
::
SSL
::
VERIFY_PEER
}
return
unless
manages_kubernetes_service?
if
ca_pem
.
present?
opts
[
:cert_store
]
=
OpenSSL
::
X509
::
Store
.
new
opts
[
:cert_store
].
add_cert
(
OpenSSL
::
X509
::
Certificate
.
new
(
ca_pem
))
end
opts
kubernetes_service
.
destroy!
end
end
private
def
update_kubernetes_integration!
return
raise
'Kubernetes service already configured'
unless
manages_kubernetes_service?
def
build_kubeclient!
(
api_path:
'api'
,
api_version:
'v1'
)
raise
"Incomplete settings"
unless
api_url
&&
actual_namespace
unless
(
username
&&
password
)
||
token
ensure_kubernetes_service
.
update!
(
raise
"Either username/password or token is required to access API"
active:
active?
,
end
api_url:
api_url
,
namespace:
namespace
,
::
Kubeclient
::
Client
.
new
(
token:
token
,
join_api_url
(
api_path
),
ca_pem:
ca_cert
,
api_version
,
auth_options:
kubeclient_auth_options
,
ssl_options:
kubeclient_ssl_options
,
http_proxy_uri:
ENV
[
'http_proxy'
]
)
)
end
end
def
kubeclient_auth_options
def
kubernetes_service
return
{
username:
username
,
password:
password
}
if
username
&&
password
@kubernetes_service
||=
project
.
kubernetes_service
||
project
.
build_kubernetes_service
return
{
bearer_token:
token
}
if
token
end
def
join_api_url
(
api_path
)
url
=
URI
.
parse
(
api_url
)
prefix
=
url
.
path
.
sub
(
%r{/+
\z
}
,
''
)
url
.
path
=
[
prefix
,
api_path
].
join
(
"/"
)
url
.
to_s
end
end
def
terminal_auth
def
ensure_kubernetes_service
{
@kubernetes_service
||=
kubernetes_service
||
project
.
build_kubernetes_service
token:
token
,
ca_pem:
ca_pem
,
max_session_time:
current_application_settings
.
terminal_max_session_time
}
end
def
enforce_namespace_to_lower_case
self
.
namespace
=
self
.
namespace
&
.
downcase
end
end
end
end
end
end
...
...
app/services/clusters/create_service.rb
View file @
ccf09824
...
@@ -2,9 +2,6 @@ module Clusters
...
@@ -2,9 +2,6 @@ module Clusters
class
CreateService
<
BaseService
class
CreateService
<
BaseService
attr_reader
:access_token
attr_reader
:access_token
TEMPOLARY_API_URL
=
'http://tempolary_api_url'
.
freeze
TEMPOLARY_TOKEN
=
'tempolary_token'
.
freeze
def
execute
(
access_token
)
def
execute
(
access_token
)
@access_token
=
access_token
@access_token
=
access_token
...
@@ -16,14 +13,9 @@ module Clusters
...
@@ -16,14 +13,9 @@ module Clusters
private
private
def
create_cluster
def
create_cluster
cluster
=
nil
Clusters
::
Cluster
.
create!
(
cluster_params
.
merge
(
ActiveRecord
::
Base
.
transaction
do
projects:
[
project
]))
cluster
=
Clusters
::
Cluster
.
create!
(
cluster_params
)
cluster
.
projects
<<
project
end
cluster
rescue
ActiveRecord
::
RecordInvalid
=>
e
rescue
ActiveRecord
::
RecordInvalid
=>
e
e
.
record
e
.
record
end
end
...
@@ -33,11 +25,6 @@ module Clusters
...
@@ -33,11 +25,6 @@ module Clusters
params
[
:provider_gcp_attributes
].
try
do
|
provider
|
params
[
:provider_gcp_attributes
].
try
do
|
provider
|
provider
[
:access_token
]
=
access_token
provider
[
:access_token
]
=
access_token
params
[
:platform_kubernetes_attributes
].
try
do
|
platform
|
platform
[
:api_url
]
=
TEMPOLARY_API_URL
platform
[
:token
]
=
TEMPOLARY_TOKEN
end
end
end
@cluster_params
=
params
.
merge
(
user:
current_user
)
@cluster_params
=
params
.
merge
(
user:
current_user
)
...
...
db/schema.rb
View file @
ccf09824
...
@@ -481,8 +481,8 @@ ActiveRecord::Schema.define(version: 20171017145932) do
...
@@ -481,8 +481,8 @@ ActiveRecord::Schema.define(version: 20171017145932) do
create_table
"cluster_projects"
,
force: :cascade
do
|
t
|
create_table
"cluster_projects"
,
force: :cascade
do
|
t
|
t
.
integer
"project_id"
,
null:
false
t
.
integer
"project_id"
,
null:
false
t
.
integer
"cluster_id"
,
null:
false
t
.
integer
"cluster_id"
,
null:
false
t
.
datetime
"created_at"
,
null:
false
t
.
datetime
_with_timezone
"created_at"
,
null:
false
t
.
datetime
"updated_at"
,
null:
false
t
.
datetime
_with_timezone
"updated_at"
,
null:
false
end
end
add_index
"cluster_projects"
,
[
"cluster_id"
],
name:
"index_cluster_projects_on_cluster_id"
,
using: :btree
add_index
"cluster_projects"
,
[
"cluster_id"
],
name:
"index_cluster_projects_on_cluster_id"
,
using: :btree
...
...
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