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
Jérome Perrin
gitlab-ce
Commits
6b7889f7
Commit
6b7889f7
authored
Oct 03, 2017
by
Shinya Maeda
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Implement Policy. Use show instead of edit. Chnage db column. fix comments. dry up workers
parent
fd677621
Changes
16
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
173 additions
and
204 deletions
+173
-204
app/controllers/projects/clusters_controller.rb
app/controllers/projects/clusters_controller.rb
+19
-9
app/models/gcp/cluster.rb
app/models/gcp/cluster.rb
+3
-6
app/policies/gcp/cluster_policy.rb
app/policies/gcp/cluster_policy.rb
+16
-0
app/policies/project_policy.rb
app/policies/project_policy.rb
+2
-1
app/services/ci/create_cluster_service.rb
app/services/ci/create_cluster_service.rb
+4
-4
app/services/ci/create_gke_cluster_service.rb
app/services/ci/create_gke_cluster_service.rb
+37
-0
app/services/ci/fetch_gcp_operation_service.rb
app/services/ci/fetch_gcp_operation_service.rb
+17
-0
app/services/ci/finalize_cluster_creation_service.rb
app/services/ci/finalize_cluster_creation_service.rb
+33
-0
app/views/projects/clusters/_form.html.haml
app/views/projects/clusters/_form.html.haml
+9
-9
app/views/projects/clusters/show.html.haml
app/views/projects/clusters/show.html.haml
+2
-2
app/workers/cluster_creation_worker.rb
app/workers/cluster_creation_worker.rb
+2
-38
app/workers/wait_for_cluster_creation_worker.rb
app/workers/wait_for_cluster_creation_worker.rb
+14
-59
config/routes/project.rb
config/routes/project.rb
+1
-1
db/migrate/20170924094327_create_gcp_clusters.rb
db/migrate/20170924094327_create_gcp_clusters.rb
+4
-7
db/schema.rb
db/schema.rb
+4
-42
lib/google_api/cloud_platform/client.rb
lib/google_api/cloud_platform/client.rb
+6
-26
No files found.
app/controllers/projects/clusters_controller.rb
View file @
6b7889f7
class
Projects::ClustersController
<
Projects
::
ApplicationController
class
Projects::ClustersController
<
Projects
::
ApplicationController
before_action
:cluster
,
except:
[
:login
,
:index
,
:new
,
:create
]
before_action
:cluster
,
except:
[
:login
,
:index
,
:new
,
:create
]
before_action
:authorize_admin_cluster!
before_action
:authorize_read_cluster!
before_action
:authorize_google_api
,
except:
[
:login
]
before_action
:authorize_create_cluster!
,
only:
[
:new
,
:create
]
before_action
:authorize_google_api
,
only:
[
:new
,
:create
]
before_action
:authorize_update_cluster!
,
only:
[
:update
]
before_action
:authorize_admin_cluster!
,
only:
[
:destroy
]
def
login
def
login
begin
begin
...
@@ -16,7 +19,7 @@ class Projects::ClustersController < Projects::ApplicationController
...
@@ -16,7 +19,7 @@ class Projects::ClustersController < Projects::ApplicationController
def
index
def
index
if
project
.
cluster
if
project
.
cluster
redirect_to
edit_
project_cluster_path
(
project
,
project
.
cluster
)
redirect_to
project_cluster_path
(
project
,
project
.
cluster
)
else
else
redirect_to
new_project_cluster_path
(
project
)
redirect_to
new_project_cluster_path
(
project
)
end
end
...
@@ -32,7 +35,6 @@ class Projects::ClustersController < Projects::ApplicationController
...
@@ -32,7 +35,6 @@ class Projects::ClustersController < Projects::ApplicationController
.
execute
(
token_in_session
)
.
execute
(
token_in_session
)
if
@cluster
.
persisted?
if
@cluster
.
persisted?
ClusterCreationWorker
.
perform_async
(
@cluster
.
id
)
redirect_to
project_clusters_path
(
project
)
redirect_to
project_clusters_path
(
project
)
else
else
render
:new
render
:new
...
@@ -52,7 +54,7 @@ class Projects::ClustersController < Projects::ApplicationController
...
@@ -52,7 +54,7 @@ class Projects::ClustersController < Projects::ApplicationController
end
end
end
end
def
edit
def
show
end
end
def
update
def
update
...
@@ -60,14 +62,14 @@ class Projects::ClustersController < Projects::ApplicationController
...
@@ -60,14 +62,14 @@ class Projects::ClustersController < Projects::ApplicationController
.
new
(
project
,
current_user
,
cluster_params
)
.
new
(
project
,
current_user
,
cluster_params
)
.
execute
(
cluster
)
.
execute
(
cluster
)
render
:
edit
render
:
show
end
end
def
destroy
def
destroy
if
cluster
.
destroy
if
cluster
.
destroy
redirect_to
project_clusters_path
(
project
),
status:
302
redirect_to
project_clusters_path
(
project
),
status:
302
else
else
render
:
edit
render
:
show
end
end
end
end
...
@@ -79,8 +81,8 @@ class Projects::ClustersController < Projects::ApplicationController
...
@@ -79,8 +81,8 @@ class Projects::ClustersController < Projects::ApplicationController
def
cluster_params
def
cluster_params
params
.
require
(
:cluster
)
params
.
require
(
:cluster
)
.
permit
(
:gcp_project_id
,
:
cluster_zone
,
:cluster_name
,
:
cluster_size
,
.
permit
(
:gcp_project_id
,
:
gcp_cluster_zone
,
:gcp_cluster_name
,
:gcp_
cluster_size
,
:machine_type
,
:project_namespace
,
:enabled
)
:
gcp_
machine_type
,
:project_namespace
,
:enabled
)
end
end
def
authorize_google_api
def
authorize_google_api
...
@@ -99,4 +101,12 @@ class Projects::ClustersController < Projects::ApplicationController
...
@@ -99,4 +101,12 @@ class Projects::ClustersController < Projects::ApplicationController
@expires_at_in_session
||=
@expires_at_in_session
||=
session
[
GoogleApi
::
CloudPlatform
::
Client
.
session_key_for_expires_at
]
session
[
GoogleApi
::
CloudPlatform
::
Client
.
session_key_for_expires_at
]
end
end
def
authorize_update_cluster!
return
access_denied!
unless
can?
(
current_user
,
:update_cluster
,
cluster
)
end
def
authorize_admin_cluster!
return
access_denied!
unless
can?
(
current_user
,
:admin_cluster
,
cluster
)
end
end
end
app/models/gcp/cluster.rb
View file @
6b7889f7
...
@@ -8,19 +8,16 @@ module Gcp
...
@@ -8,19 +8,16 @@ module Gcp
attr_encrypted
:password
,
attr_encrypted
:password
,
mode: :per_attribute_iv
,
mode: :per_attribute_iv
,
insecure_mode:
true
,
key:
Gitlab
::
Application
.
secrets
.
db_key_base
,
key:
Gitlab
::
Application
.
secrets
.
db_key_base
,
algorithm:
'aes-256-cbc'
algorithm:
'aes-256-cbc'
attr_encrypted
:kubernetes_token
,
attr_encrypted
:kubernetes_token
,
mode: :per_attribute_iv
,
mode: :per_attribute_iv
,
insecure_mode:
true
,
key:
Gitlab
::
Application
.
secrets
.
db_key_base
,
key:
Gitlab
::
Application
.
secrets
.
db_key_base
,
algorithm:
'aes-256-cbc'
algorithm:
'aes-256-cbc'
attr_encrypted
:gcp_token
,
attr_encrypted
:gcp_token
,
mode: :per_attribute_iv
,
mode: :per_attribute_iv
,
insecure_mode:
true
,
key:
Gitlab
::
Application
.
secrets
.
db_key_base
,
key:
Gitlab
::
Application
.
secrets
.
db_key_base
,
algorithm:
'aes-256-cbc'
algorithm:
'aes-256-cbc'
...
@@ -33,9 +30,9 @@ module Gcp
...
@@ -33,9 +30,9 @@ module Gcp
}
}
validates
:gcp_project_id
,
presence:
true
validates
:gcp_project_id
,
presence:
true
validates
:cluster_zone
,
presence:
true
validates
:
gcp_
cluster_zone
,
presence:
true
validates
:cluster_name
,
presence:
true
validates
:
gcp_
cluster_name
,
presence:
true
validates
:cluster_size
,
presence:
true
,
validates
:
gcp_
cluster_size
,
presence:
true
,
numericality:
{
only_integer:
true
,
greater_than:
0
}
numericality:
{
only_integer:
true
,
greater_than:
0
}
validate
:restrict_modification
,
on: :update
validate
:restrict_modification
,
on: :update
...
...
app/policies/gcp/cluster_policy.rb
0 → 100644
View file @
6b7889f7
module
Gcp
class
ClusterPolicy
<
BasePolicy
alias_method
:cluster
,
:subject
delegate
{
@subject
.
project
}
condition
(
:safe_to_change
)
do
can?
(
:master_access
)
&&
!
cluster
.
on_creation?
end
rule
{
safe_to_change
}.
policy
do
enable
:update_cluster
enable
:admin_cluster
end
end
end
app/policies/project_policy.rb
View file @
6b7889f7
...
@@ -164,6 +164,7 @@ class ProjectPolicy < BasePolicy
...
@@ -164,6 +164,7 @@ class ProjectPolicy < BasePolicy
enable
:create_pipeline
enable
:create_pipeline
enable
:update_pipeline
enable
:update_pipeline
enable
:create_pipeline_schedule
enable
:create_pipeline_schedule
enable
:read_cluster
enable
:create_merge_request
enable
:create_merge_request
enable
:create_wiki
enable
:create_wiki
enable
:push_code
enable
:push_code
...
@@ -188,7 +189,7 @@ class ProjectPolicy < BasePolicy
...
@@ -188,7 +189,7 @@ class ProjectPolicy < BasePolicy
enable
:admin_build
enable
:admin_build
enable
:admin_container_image
enable
:admin_container_image
enable
:admin_pipeline
enable
:admin_pipeline
enable
:
admin
_cluster
enable
:
create
_cluster
enable
:admin_environment
enable
:admin_environment
enable
:admin_deployment
enable
:admin_deployment
enable
:admin_pages
enable
:admin_pages
...
...
app/services/ci/create_cluster_service.rb
View file @
6b7889f7
module
Ci
module
Ci
class
CreateClusterService
<
BaseService
class
CreateClusterService
<
BaseService
def
execute
(
access_token
)
def
execute
(
access_token
)
if
params
[
'machine_type'
].
blank?
params
[
'gcp_machine_type'
]
||=
GoogleApi
::
CloudPlatform
::
Client
::
DEFAULT_MACHINE_TYPE
params
[
'machine_type'
]
=
GoogleApi
::
CloudPlatform
::
Client
::
DEFAULT_MACHINE_TYPE
end
project
.
create_cluster
(
project
.
create_cluster
(
params
.
merge
(
user:
current_user
,
params
.
merge
(
user:
current_user
,
status:
Gcp
::
Cluster
.
statuses
[
:scheduled
],
status:
Gcp
::
Cluster
.
statuses
[
:scheduled
],
gcp_token:
access_token
))
gcp_token:
access_token
)).
tap
do
|
cluster
|
ClusterCreationWorker
.
perform_async
(
cluster
.
id
)
if
cluster
.
persisted?
end
end
end
end
end
end
end
app/services/ci/create_gke_cluster_service.rb
0 → 100644
View file @
6b7889f7
module
Ci
class
CreateGkeClusterService
def
execute
(
cluster
)
api_client
=
GoogleApi
::
CloudPlatform
::
Client
.
new
(
cluster
.
gcp_token
,
nil
)
begin
operation
=
api_client
.
projects_zones_clusters_create
(
cluster
.
gcp_project_id
,
cluster
.
gcp_cluster_zone
,
cluster
.
gcp_cluster_name
,
cluster
.
gcp_cluster_size
,
machine_type:
cluster
.
gcp_machine_type
)
rescue
Google
::
Apis
::
ServerError
,
Google
::
Apis
::
ClientError
,
Google
::
Apis
::
AuthorizationError
=>
e
return
cluster
.
errored!
(
"Failed to request to CloudPlatform;
#{
e
.
message
}
"
)
end
unless
operation
.
status
==
'RUNNING'
||
operation
.
status
==
'PENDING'
return
cluster
.
errored!
(
"Operation status is unexpected;
#{
operation
.
status_message
}
"
)
end
operation_id
=
api_client
.
parse_operation_id
(
operation
.
self_link
)
unless
operation_id
return
cluster
.
errored!
(
'Can not find operation_id from self_link'
)
end
if
cluster
.
creating!
(
operation_id
)
WaitForClusterCreationWorker
.
perform_in
(
WaitForClusterCreationWorker
::
INITIAL_INTERVAL
,
cluster
.
id
)
else
return
cluster
.
errored!
(
"Failed to update cluster record;
#{
cluster
.
errors
}
"
)
end
end
end
end
app/services/ci/fetch_gcp_operation_service.rb
0 → 100644
View file @
6b7889f7
module
Ci
class
FetchGcpOperationService
def
execute
(
cluster
)
api_client
=
GoogleApi
::
CloudPlatform
::
Client
.
new
(
cluster
.
gcp_token
,
nil
)
operation
=
api_client
.
projects_zones_operations
(
cluster
.
gcp_project_id
,
cluster
.
gcp_cluster_zone
,
cluster
.
gcp_operation_id
)
yield
(
operation
)
if
block_given?
rescue
Google
::
Apis
::
ServerError
,
Google
::
Apis
::
ClientError
,
Google
::
Apis
::
AuthorizationError
=>
e
return
cluster
.
errored!
(
"Failed to request to CloudPlatform;
#{
e
.
message
}
"
)
end
end
end
app/services/ci/finalize_cluster_creation_service.rb
0 → 100644
View file @
6b7889f7
module
Ci
class
FinalizeClusterCreationService
def
execute
(
cluster
)
api_client
=
GoogleApi
::
CloudPlatform
::
Client
.
new
(
cluster
.
gcp_token
,
nil
)
begin
gke_cluster
=
api_client
.
projects_zones_clusters_get
(
cluster
.
gcp_project_id
,
cluster
.
gcp_cluster_zone
,
cluster
.
gcp_cluster_name
)
rescue
Google
::
Apis
::
ServerError
,
Google
::
Apis
::
ClientError
,
Google
::
Apis
::
AuthorizationError
=>
e
return
cluster
.
errored!
(
"Failed to request to CloudPlatform;
#{
e
.
message
}
"
)
end
endpoint
=
gke_cluster
.
endpoint
api_url
=
'https://'
+
endpoint
ca_cert
=
Base64
.
decode64
(
gke_cluster
.
master_auth
.
cluster_ca_certificate
)
username
=
gke_cluster
.
master_auth
.
username
password
=
gke_cluster
.
master_auth
.
password
kubernetes_token
=
Ci
::
FetchKubernetesTokenService
.
new
(
api_url
,
ca_cert
,
username
,
password
).
execute
unless
kubernetes_token
return
cluster
.
errored!
(
'Failed to get a default token of kubernetes'
)
end
Ci
::
IntegrateClusterService
.
new
.
execute
(
cluster
,
endpoint
,
ca_cert
,
kubernetes_token
,
username
,
password
)
end
end
end
app/views/projects/clusters/_form.html.haml
View file @
6b7889f7
...
@@ -7,8 +7,8 @@
...
@@ -7,8 +7,8 @@
=
form_for
[
@project
.
namespace
.
becomes
(
Namespace
),
@project
,
@cluster
]
do
|
field
|
=
form_for
[
@project
.
namespace
.
becomes
(
Namespace
),
@project
,
@cluster
]
do
|
field
|
=
form_errors
(
@cluster
)
=
form_errors
(
@cluster
)
.form-group
.form-group
=
field
.
label
:cluster_name
=
field
.
label
:
gcp_
cluster_name
=
field
.
text_field
:cluster_name
,
class:
'form-control'
=
field
.
text_field
:
gcp_
cluster_name
,
class:
'form-control'
.form-group
.form-group
=
field
.
label
:gcp_project_id
=
field
.
label
:gcp_project_id
...
@@ -16,25 +16,25 @@
...
@@ -16,25 +16,25 @@
=
field
.
text_field
:gcp_project_id
,
class:
'form-control'
=
field
.
text_field
:gcp_project_id
,
class:
'form-control'
.form-group
.form-group
=
field
.
label
:cluster_zone
=
field
.
label
:
gcp_
cluster_zone
=
link_to
(
s_
(
'ClusterIntegration|See zones'
),
'https://cloud.google.com/compute/docs/regions-zones/regions-zones'
,
target:
'_blank'
,
rel:
'noopener noreferrer'
)
=
link_to
(
s_
(
'ClusterIntegration|See zones'
),
'https://cloud.google.com/compute/docs/regions-zones/regions-zones'
,
target:
'_blank'
,
rel:
'noopener noreferrer'
)
=
field
.
text_field
:cluster_zone
,
class:
'form-control'
=
field
.
text_field
:
gcp_
cluster_zone
,
class:
'form-control'
.form-group
.form-group
=
field
.
label
:cluster_size
=
field
.
label
:
gcp_
cluster_size
=
field
.
text_field
:cluster_size
,
class:
'form-control'
=
field
.
text_field
:
gcp_
cluster_size
,
class:
'form-control'
.form-group
.form-group
=
field
.
label
:project_namespace
=
field
.
label
:project_namespace
=
field
.
text_field
:project_namespace
,
class:
'form-control'
=
field
.
text_field
:project_namespace
,
class:
'form-control'
.form-group
.form-group
=
field
.
label
:machine_type
=
field
.
label
:
gcp_
machine_type
=
link_to
(
s_
(
'ClusterIntegration|Machine type'
),
'https://cloud.google.com/compute/docs/machine-types'
,
target:
'_blank'
,
rel:
'noopener noreferrer'
)
=
link_to
(
s_
(
'ClusterIntegration|Machine type'
),
'https://cloud.google.com/compute/docs/machine-types'
,
target:
'_blank'
,
rel:
'noopener noreferrer'
)
=
field
.
text_field
:machine_type
,
class:
'form-control'
=
field
.
text_field
:
gcp_
machine_type
,
class:
'form-control'
.form-group
.form-group
=
field
.
submit
s_
(
'ClusterIntegration|Create cluster'
),
class:
'btn btn-save'
=
field
.
submit
s_
(
'ClusterIntegration|Create cluster'
),
class:
'btn btn-save'
-# TODO: Remove before merge
-# TODO: Remove before merge
=
link_to
"Create on Google Container Engine"
,
namespace_project_clusters_path
(
@project
.
namespace
,
@project
,
cluster:
{
cluster_name:
"gke-test-creation
#{
Random
.
rand
(
100
)
}
"
,
gcp_project_id:
'gitlab-internal-153318'
,
cluster_zone:
'us-central1-a'
,
cluster_size:
'1'
,
project_namespace:
'aaa'
,
machine_type:
'n1-standard-1'
}),
method: :post
=
link_to
"Create on Google Container Engine"
,
namespace_project_clusters_path
(
@project
.
namespace
,
@project
,
cluster:
{
gcp_cluster_name:
"gke-test-creation
#{
Random
.
rand
(
100
)
}
"
,
gcp_project_id:
'gitlab-internal-153318'
,
gcp_cluster_zone:
'us-central1-a'
,
gcp_cluster_size:
'1'
,
project_namespace:
'aaa'
,
gcp_
machine_type:
'n1-standard-1'
}),
method: :post
app/views/projects/clusters/
edit
.html.haml
→
app/views/projects/clusters/
show
.html.haml
View file @
6b7889f7
...
@@ -55,9 +55,9 @@
...
@@ -55,9 +55,9 @@
%label
%label
=
s_
(
'ClusterIntegration|Cluster name'
)
=
s_
(
'ClusterIntegration|Cluster name'
)
.input-group
.input-group
%input
.form-control
{
value:
@cluster
.
cluster_name
,
disabled:
true
}
%input
.form-control
{
value:
@cluster
.
gcp_
cluster_name
,
disabled:
true
}
%span
.input-group-addon.clipboard-addon
%span
.input-group-addon.clipboard-addon
=
clipboard_button
(
text:
@cluster
.
cluster_name
,
title:
s_
(
'ClusterIntegration|Copy cluster name'
))
=
clipboard_button
(
text:
@cluster
.
gcp_
cluster_name
,
title:
s_
(
'ClusterIntegration|Copy cluster name'
))
%br
%br
-# - if can?(current_user, :admin_cluster, @cluster)
-# - if can?(current_user, :admin_cluster, @cluster)
...
...
app/workers/cluster_creation_worker.rb
View file @
6b7889f7
...
@@ -3,44 +3,8 @@ class ClusterCreationWorker
...
@@ -3,44 +3,8 @@ class ClusterCreationWorker
include
DedicatedSidekiqQueue
include
DedicatedSidekiqQueue
def
perform
(
cluster_id
)
def
perform
(
cluster_id
)
cluster
=
Gcp
::
Cluster
.
find_by_id
(
cluster_id
)
Gcp
::
Cluster
.
find_by_id
(
cluster_id
).
try
do
|
cluster
|
Ci
::
CreateGkeClusterService
.
new
.
execute
(
cluster
)
unless
cluster
return
Rails
.
logger
.
error
"Cluster object is not found;
#{
cluster_id
}
"
end
api_client
=
GoogleApi
::
CloudPlatform
::
Client
.
new
(
cluster
.
gcp_token
,
nil
)
operation
=
api_client
.
projects_zones_clusters_create
(
cluster
.
gcp_project_id
,
cluster
.
cluster_zone
,
cluster
.
cluster_name
,
cluster
.
cluster_size
,
machine_type:
cluster
.
machine_type
)
if
operation
.
is_a?
(
StandardError
)
return
cluster
.
errored!
(
"Failed to request to CloudPlatform;
#{
operation
.
message
}
"
)
end
unless
operation
.
status
==
'RUNNING'
||
operation
.
status
==
'PENDING'
return
cluster
.
errored!
(
"Operation status is unexpected;
#{
operation
.
status_message
}
"
)
end
operation_id
=
api_client
.
parse_operation_id
(
operation
.
self_link
)
unless
operation_id
return
cluster
.
errored!
(
'Can not find operation_id from self_link'
)
end
if
cluster
.
creating!
(
operation_id
)
WaitForClusterCreationWorker
.
perform_in
(
WaitForClusterCreationWorker
::
INITIAL_INTERVAL
,
cluster
.
id
)
else
return
cluster
.
errored!
(
"Failed to update cluster record;
#{
cluster
.
errors
}
"
)
end
end
end
end
end
end
app/workers/wait_for_cluster_creation_worker.rb
View file @
6b7889f7
...
@@ -7,66 +7,21 @@ class WaitForClusterCreationWorker
...
@@ -7,66 +7,21 @@ class WaitForClusterCreationWorker
TIMEOUT
=
20
.
minutes
TIMEOUT
=
20
.
minutes
def
perform
(
cluster_id
)
def
perform
(
cluster_id
)
cluster
=
Gcp
::
Cluster
.
find_by_id
(
cluster_id
)
Gcp
::
Cluster
.
find_by_id
(
cluster_id
).
try
do
|
cluster
|
Ci
::
FetchGcpOperationService
.
new
.
execute
(
cluster
)
do
|
operation
|
unless
cluster
case
operation
.
status
return
Rails
.
logger
.
error
"Cluster object is not found;
#{
cluster_id
}
"
when
'RUNNING'
end
if
TIMEOUT
<
Time
.
now
-
operation
.
start_time
.
to_time
return
cluster
.
errored!
(
"Cluster creation time exceeds timeout;
#{
TIMEOUT
}
"
)
api_client
=
end
GoogleApi
::
CloudPlatform
::
Client
.
new
(
cluster
.
gcp_token
,
nil
)
WaitForClusterCreationWorker
.
perform_in
(
EAGER_INTERVAL
,
cluster
.
id
)
operation
=
api_client
.
projects_zones_operations
(
when
'DONE'
cluster
.
gcp_project_id
,
Ci
::
FinalizeClusterCreationService
.
new
.
execute
(
cluster
)
cluster
.
cluster_zone
,
else
cluster
.
gcp_operation_id
)
return
cluster
.
errored!
(
"Unexpected operation status;
#{
operation
.
status
}
#{
operation
.
status_message
}
"
)
end
if
operation
.
is_a?
(
StandardError
)
return
cluster
.
errored!
(
"Failed to request to CloudPlatform;
#{
operation
.
message
}
"
)
end
case
operation
.
status
when
'RUNNING'
if
Time
.
now
<
operation
.
start_time
.
to_time
+
TIMEOUT
WaitForClusterCreationWorker
.
perform_in
(
EAGER_INTERVAL
,
cluster
.
id
)
else
return
cluster
.
errored!
(
"Cluster creation time exceeds timeout;
#{
TIMEOUT
}
"
)
end
end
when
'DONE'
integrate
(
cluster
,
api_client
)
else
return
cluster
.
errored!
(
"Unexpected operation status;
#{
operation
.
status
}
#{
operation
.
status_message
}
"
)
end
end
end
end
def
integrate
(
cluster
,
api_client
)
gke_cluster
=
api_client
.
projects_zones_clusters_get
(
cluster
.
gcp_project_id
,
cluster
.
cluster_zone
,
cluster
.
cluster_name
)
if
gke_cluster
.
is_a?
(
StandardError
)
return
cluster
.
errored!
(
"Failed to request to CloudPlatform;
#{
gke_cluster
.
message
}
"
)
end
begin
endpoint
=
gke_cluster
.
endpoint
api_url
=
'https://'
+
endpoint
ca_cert
=
Base64
.
decode64
(
gke_cluster
.
master_auth
.
cluster_ca_certificate
)
username
=
gke_cluster
.
master_auth
.
username
password
=
gke_cluster
.
master_auth
.
password
rescue
Exception
=>
e
return
cluster
.
errored!
(
"Can not extract the expected data;
#{
e
}
"
)
end
kubernetes_token
=
Ci
::
FetchKubernetesTokenService
.
new
(
api_url
,
ca_cert
,
username
,
password
).
execute
unless
kubernetes_token
return
cluster
.
errored!
(
'Failed to get a default token of kubernetes'
)
end
Ci
::
IntegrateClusterService
.
new
.
execute
(
cluster
,
endpoint
,
ca_cert
,
kubernetes_token
,
username
,
password
)
end
end
end
config/routes/project.rb
View file @
6b7889f7
...
@@ -183,7 +183,7 @@ constraints(ProjectUrlConstrainer.new) do
...
@@ -183,7 +183,7 @@ constraints(ProjectUrlConstrainer.new) do
end
end
end
end
resources
:clusters
,
except:
[
:
show
]
do
resources
:clusters
,
except:
[
:
edit
]
do
collection
do
collection
do
get
:login
get
:login
end
end
...
...
db/migrate/20170924094327_create_gcp_clusters.rb
View file @
6b7889f7
...
@@ -19,22 +19,19 @@ class CreateGcpClusters < ActiveRecord::Migration
...
@@ -19,22 +19,19 @@ class CreateGcpClusters < ActiveRecord::Migration
t
.
string
:endpoint
t
.
string
:endpoint
t
.
text
:ca_cert
t
.
text
:ca_cert
t
.
string
:encrypted_kubernetes_token
t
.
string
:encrypted_kubernetes_token
t
.
string
:encrypted_kubernetes_token_salt
t
.
string
:encrypted_kubernetes_token_iv
t
.
string
:encrypted_kubernetes_token_iv
t
.
string
:username
t
.
string
:username
t
.
string
:encrypted_password
t
.
string
:encrypted_password
t
.
string
:encrypted_password_salt
t
.
string
:encrypted_password_iv
t
.
string
:encrypted_password_iv
# GKE
# GKE
t
.
string
:gcp_project_id
,
null:
false
t
.
string
:gcp_project_id
,
null:
false
t
.
string
:cluster_zone
,
null:
false
t
.
string
:
gcp_
cluster_zone
,
null:
false
t
.
string
:cluster_name
,
null:
false
t
.
string
:
gcp_
cluster_name
,
null:
false
t
.
integer
:cluster_size
,
null:
false
t
.
integer
:
gcp_
cluster_size
,
null:
false
t
.
string
:machine_type
t
.
string
:
gcp_
machine_type
t
.
string
:gcp_operation_id
t
.
string
:gcp_operation_id
t
.
string
:encrypted_gcp_token
t
.
string
:encrypted_gcp_token
t
.
string
:encrypted_gcp_token_salt
t
.
string
:encrypted_gcp_token_iv
t
.
string
:encrypted_gcp_token_iv
t
.
datetime_with_timezone
:created_at
,
null:
false
t
.
datetime_with_timezone
:created_at
,
null:
false
...
...
db/schema.rb
View file @
6b7889f7
...
@@ -267,38 +267,6 @@ ActiveRecord::Schema.define(version: 20170928100231) do
...
@@ -267,38 +267,6 @@ ActiveRecord::Schema.define(version: 20170928100231) do
add_index
"ci_builds"
,
[
"updated_at"
],
name:
"index_ci_builds_on_updated_at"
,
using: :btree
add_index
"ci_builds"
,
[
"updated_at"
],
name:
"index_ci_builds_on_updated_at"
,
using: :btree
add_index
"ci_builds"
,
[
"user_id"
],
name:
"index_ci_builds_on_user_id"
,
using: :btree
add_index
"ci_builds"
,
[
"user_id"
],
name:
"index_ci_builds_on_user_id"
,
using: :btree
create_table
"ci_clusters"
,
force: :cascade
do
|
t
|
t
.
integer
"project_id"
,
null:
false
t
.
integer
"user_id"
,
null:
false
t
.
integer
"service_id"
t
.
boolean
"enabled"
,
default:
true
t
.
integer
"status"
t
.
string
"status_reason"
t
.
string
"project_namespace"
t
.
string
"endpoint"
t
.
text
"ca_cert"
t
.
string
"encrypted_kubernetes_token"
t
.
string
"encrypted_kubernetes_token_salt"
t
.
string
"encrypted_kubernetes_token_iv"
t
.
string
"username"
t
.
string
"encrypted_password"
t
.
string
"encrypted_password_salt"
t
.
string
"encrypted_password_iv"
t
.
string
"gcp_project_id"
,
null:
false
t
.
string
"cluster_zone"
,
null:
false
t
.
string
"cluster_name"
,
null:
false
t
.
integer
"cluster_size"
,
null:
false
t
.
string
"machine_type"
t
.
string
"gcp_operation_id"
t
.
string
"encrypted_gcp_token"
t
.
string
"encrypted_gcp_token_salt"
t
.
string
"encrypted_gcp_token_iv"
t
.
datetime
"created_at"
,
null:
false
t
.
datetime
"updated_at"
,
null:
false
end
add_index
"ci_clusters"
,
[
"project_id"
],
name:
"index_ci_clusters_on_project_id"
,
unique:
true
,
using: :btree
create_table
"ci_group_variables"
,
force: :cascade
do
|
t
|
create_table
"ci_group_variables"
,
force: :cascade
do
|
t
|
t
.
string
"key"
,
null:
false
t
.
string
"key"
,
null:
false
t
.
text
"value"
t
.
text
"value"
...
@@ -619,20 +587,17 @@ ActiveRecord::Schema.define(version: 20170928100231) do
...
@@ -619,20 +587,17 @@ ActiveRecord::Schema.define(version: 20170928100231) do
t
.
string
"endpoint"
t
.
string
"endpoint"
t
.
text
"ca_cert"
t
.
text
"ca_cert"
t
.
string
"encrypted_kubernetes_token"
t
.
string
"encrypted_kubernetes_token"
t
.
string
"encrypted_kubernetes_token_salt"
t
.
string
"encrypted_kubernetes_token_iv"
t
.
string
"encrypted_kubernetes_token_iv"
t
.
string
"username"
t
.
string
"username"
t
.
string
"encrypted_password"
t
.
string
"encrypted_password"
t
.
string
"encrypted_password_salt"
t
.
string
"encrypted_password_iv"
t
.
string
"encrypted_password_iv"
t
.
string
"gcp_project_id"
,
null:
false
t
.
string
"gcp_project_id"
,
null:
false
t
.
string
"cluster_zone"
,
null:
false
t
.
string
"
gcp_
cluster_zone"
,
null:
false
t
.
string
"cluster_name"
,
null:
false
t
.
string
"
gcp_
cluster_name"
,
null:
false
t
.
integer
"cluster_size"
,
null:
false
t
.
integer
"
gcp_
cluster_size"
,
null:
false
t
.
string
"machine_type"
t
.
string
"
gcp_
machine_type"
t
.
string
"gcp_operation_id"
t
.
string
"gcp_operation_id"
t
.
string
"encrypted_gcp_token"
t
.
string
"encrypted_gcp_token"
t
.
string
"encrypted_gcp_token_salt"
t
.
string
"encrypted_gcp_token_iv"
t
.
string
"encrypted_gcp_token_iv"
t
.
datetime
"created_at"
,
null:
false
t
.
datetime
"created_at"
,
null:
false
t
.
datetime
"updated_at"
,
null:
false
t
.
datetime
"updated_at"
,
null:
false
...
@@ -1749,9 +1714,6 @@ ActiveRecord::Schema.define(version: 20170928100231) do
...
@@ -1749,9 +1714,6 @@ ActiveRecord::Schema.define(version: 20170928100231) do
add_foreign_key
"ci_builds"
,
"ci_pipelines"
,
column:
"auto_canceled_by_id"
,
name:
"fk_a2141b1522"
,
on_delete: :nullify
add_foreign_key
"ci_builds"
,
"ci_pipelines"
,
column:
"auto_canceled_by_id"
,
name:
"fk_a2141b1522"
,
on_delete: :nullify
add_foreign_key
"ci_builds"
,
"ci_stages"
,
column:
"stage_id"
,
name:
"fk_3a9eaa254d"
,
on_delete: :cascade
add_foreign_key
"ci_builds"
,
"ci_stages"
,
column:
"stage_id"
,
name:
"fk_3a9eaa254d"
,
on_delete: :cascade
add_foreign_key
"ci_builds"
,
"projects"
,
name:
"fk_befce0568a"
,
on_delete: :cascade
add_foreign_key
"ci_builds"
,
"projects"
,
name:
"fk_befce0568a"
,
on_delete: :cascade
add_foreign_key
"ci_clusters"
,
"projects"
,
on_delete: :cascade
add_foreign_key
"ci_clusters"
,
"services"
add_foreign_key
"ci_clusters"
,
"users"
add_foreign_key
"ci_group_variables"
,
"namespaces"
,
column:
"group_id"
,
name:
"fk_33ae4d58d8"
,
on_delete: :cascade
add_foreign_key
"ci_group_variables"
,
"namespaces"
,
column:
"group_id"
,
name:
"fk_33ae4d58d8"
,
on_delete: :cascade
add_foreign_key
"ci_pipeline_schedule_variables"
,
"ci_pipeline_schedules"
,
column:
"pipeline_schedule_id"
,
name:
"fk_41c35fda51"
,
on_delete: :cascade
add_foreign_key
"ci_pipeline_schedule_variables"
,
"ci_pipeline_schedules"
,
column:
"pipeline_schedule_id"
,
name:
"fk_41c35fda51"
,
on_delete: :cascade
add_foreign_key
"ci_pipeline_schedules"
,
"projects"
,
name:
"fk_8ead60fcc4"
,
on_delete: :cascade
add_foreign_key
"ci_pipeline_schedules"
,
"projects"
,
name:
"fk_8ead60fcc4"
,
on_delete: :cascade
...
...
lib/google_api/cloud_platform/client.rb
View file @
6b7889f7
...
@@ -3,7 +3,8 @@ require 'google/apis/container_v1'
...
@@ -3,7 +3,8 @@ require 'google/apis/container_v1'
module
GoogleApi
module
GoogleApi
module
CloudPlatform
module
CloudPlatform
class
Client
<
GoogleApi
::
Auth
class
Client
<
GoogleApi
::
Auth
DEFAULT_MACHINE_TYPE
=
'n1-standard-1'
DEFAULT_MACHINE_TYPE
=
'n1-standard-1'
.
freeze
SCOPE
=
'https://www.googleapis.com/auth/cloud-platform'
.
freeze
class
<<
self
class
<<
self
def
session_key_for_token
def
session_key_for_token
...
@@ -16,7 +17,7 @@ module GoogleApi
...
@@ -16,7 +17,7 @@ module GoogleApi
end
end
def
scope
def
scope
'https://www.googleapis.com/auth/cloud-platform'
SCOPE
end
end
def
validate_token
(
expires_at
)
def
validate_token
(
expires_at
)
...
@@ -35,14 +36,7 @@ module GoogleApi
...
@@ -35,14 +36,7 @@ module GoogleApi
service
=
Google
::
Apis
::
ContainerV1
::
ContainerService
.
new
service
=
Google
::
Apis
::
ContainerV1
::
ContainerService
.
new
service
.
authorization
=
access_token
service
.
authorization
=
access_token
begin
service
.
get_zone_cluster
(
project_id
,
zone
,
cluster_id
)
cluster
=
service
.
get_zone_cluster
(
project_id
,
zone
,
cluster_id
)
rescue
Google
::
Apis
::
ServerError
,
Google
::
Apis
::
ClientError
,
Google
::
Apis
::
AuthorizationError
=>
e
return
e
end
puts
"
#{
self
.
class
.
name
}
-
#{
__callee__
}
: cluster:
#{
cluster
.
inspect
}
"
cluster
end
end
def
projects_zones_clusters_create
(
project_id
,
zone
,
cluster_name
,
cluster_size
,
machine_type
:)
def
projects_zones_clusters_create
(
project_id
,
zone
,
cluster_name
,
cluster_size
,
machine_type
:)
...
@@ -61,28 +55,14 @@ module GoogleApi
...
@@ -61,28 +55,14 @@ module GoogleApi
}
}
)
)
begin
service
.
create_cluster
(
project_id
,
zone
,
request_body
)
operation
=
service
.
create_cluster
(
project_id
,
zone
,
request_body
)
rescue
Google
::
Apis
::
ServerError
,
Google
::
Apis
::
ClientError
,
Google
::
Apis
::
AuthorizationError
=>
e
return
e
end
puts
"
#{
self
.
class
.
name
}
-
#{
__callee__
}
: operation:
#{
operation
.
inspect
}
"
operation
end
end
def
projects_zones_operations
(
project_id
,
zone
,
operation_id
)
def
projects_zones_operations
(
project_id
,
zone
,
operation_id
)
service
=
Google
::
Apis
::
ContainerV1
::
ContainerService
.
new
service
=
Google
::
Apis
::
ContainerV1
::
ContainerService
.
new
service
.
authorization
=
access_token
service
.
authorization
=
access_token
begin
service
.
get_zone_operation
(
project_id
,
zone
,
operation_id
)
operation
=
service
.
get_zone_operation
(
project_id
,
zone
,
operation_id
)
rescue
Google
::
Apis
::
ClientError
,
Google
::
Apis
::
AuthorizationError
=>
e
return
e
end
puts
"
#{
self
.
class
.
name
}
-
#{
__callee__
}
: operation:
#{
operation
.
inspect
}
"
operation
end
end
def
parse_operation_id
(
self_link
)
def
parse_operation_id
(
self_link
)
...
...
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