Commit 78f85f3f authored by Matija Čupić's avatar Matija Čupić

Add check step for creating GCP clusters

parent 1de0261d
class Projects::Clusters::GcpController < Projects::ApplicationController class Projects::Clusters::GcpController < Projects::ApplicationController
before_action :authorize_read_cluster! before_action :authorize_read_cluster!
before_action :authorize_google_api, except: [:login] before_action :authorize_google_api, except: [:login]
before_action :authorize_google_project_billing, only: [:check]
before_action :authorize_create_cluster!, only: [:new, :create] before_action :authorize_create_cluster!, only: [:new, :create]
STATUS_POLLING_INTERVAL = 10_000
def login def login
begin begin
state = generate_session_key_redirect(gcp_new_namespace_project_clusters_path.to_s) state = generate_session_key_redirect(gcp_check_namespace_project_clusters_path.to_s)
@authorize_url = GoogleApi::CloudPlatform::Client.new( @authorize_url = GoogleApi::CloudPlatform::Client.new(
nil, callback_google_api_auth_url, nil, callback_google_api_auth_url,
...@@ -15,6 +18,18 @@ class Projects::Clusters::GcpController < Projects::ApplicationController ...@@ -15,6 +18,18 @@ class Projects::Clusters::GcpController < Projects::ApplicationController
end end
end end
def check
respond_to do |format|
format.json do
Gitlab::PollingInterval.set_header(response, interval: STATUS_POLLING_INTERVAL)
Gitlab::Redis::SharedState.with do |redis|
render json: { billing: redis.get(CheckGcpProjectBillingWorker.redis_shared_state_key_for(token_in_session)) }
end
end
end
end
def new def new
@cluster = ::Clusters::Cluster.new.tap do |cluster| @cluster = ::Clusters::Cluster.new.tap do |cluster|
cluster.build_provider_gcp cluster.build_provider_gcp
...@@ -57,6 +72,14 @@ class Projects::Clusters::GcpController < Projects::ApplicationController ...@@ -57,6 +72,14 @@ class Projects::Clusters::GcpController < Projects::ApplicationController
end end
end end
def authorize_google_project_billing
Gitlab::Redis::SharedState.with do |redis|
unless redis.get(CheckGcpProjectBillingWorker.redis_shared_state_key_for(token_in_session)) == 'true'
CheckGcpProjectBillingWorker.perform_async(token_in_session)
end
end
end
def token_in_session def token_in_session
@token_in_session ||= @token_in_session ||=
session[GoogleApi::CloudPlatform::Client.session_key_for_token] session[GoogleApi::CloudPlatform::Client.session_key_for_token]
......
...@@ -8,6 +8,6 @@ ...@@ -8,6 +8,6 @@
%h4.prepend-top-0= s_('ClusterIntegration|Choose how to set up cluster integration') %h4.prepend-top-0= s_('ClusterIntegration|Choose how to set up cluster integration')
%p= s_('ClusterIntegration|Create a new cluster on Google Kubernetes Engine right from GitLab') %p= s_('ClusterIntegration|Create a new cluster on Google Kubernetes Engine right from GitLab')
= link_to s_('ClusterIntegration|Create on GKE'), gcp_new_namespace_project_clusters_path(@project.namespace, @project), class: 'btn append-bottom-20' = link_to s_('ClusterIntegration|Create on GKE'), gcp_check_namespace_project_clusters_path(@project.namespace, @project), class: 'btn append-bottom-20'
%p= s_('ClusterIntegration|Enter the details for an existing Kubernetes cluster') %p= s_('ClusterIntegration|Enter the details for an existing Kubernetes cluster')
= link_to s_('ClusterIntegration|Add an existing cluster'), user_new_namespace_project_clusters_path(@project.namespace, @project), class: 'btn append-bottom-20' = link_to s_('ClusterIntegration|Add an existing cluster'), user_new_namespace_project_clusters_path(@project.namespace, @project), class: 'btn append-bottom-20'
...@@ -189,6 +189,7 @@ constraints(ProjectUrlConstrainer.new) do ...@@ -189,6 +189,7 @@ constraints(ProjectUrlConstrainer.new) do
get '/user/new', to: 'clusters/user#new' get '/user/new', to: 'clusters/user#new'
post '/user', to: 'clusters/user#create' post '/user', to: 'clusters/user#create'
get '/gcp/check', to: 'clusters/gcp#check'
get '/gcp/new', to: 'clusters/gcp#new' get '/gcp/new', to: 'clusters/gcp#new'
get '/gcp/login', to: 'clusters/gcp#login' get '/gcp/login', to: 'clusters/gcp#login'
post '/gcp', to: 'clusters/gcp#create' post '/gcp', to: 'clusters/gcp#create'
......
...@@ -30,7 +30,7 @@ describe Projects::Clusters::GcpController do ...@@ -30,7 +30,7 @@ describe Projects::Clusters::GcpController do
go go
expect(assigns(:authorize_url)).to include(key) expect(assigns(:authorize_url)).to include(key)
expect(session[session_key_for_redirect_uri]).to eq(gcp_new_project_clusters_path(project)) expect(session[session_key_for_redirect_uri]).to eq(gcp_check_project_clusters_path(project))
end end
end end
...@@ -63,6 +63,75 @@ describe Projects::Clusters::GcpController do ...@@ -63,6 +63,75 @@ describe Projects::Clusters::GcpController do
end end
end end
describe 'GET check' do
let(:user) { create(:user) }
before do
project.add_master(user)
sign_in(user)
end
describe 'functionality' do
context 'when redis has wanted billing status' do
let(:token) { 'bogustoken' }
before do
redis_double = double
allow(Gitlab::Redis::SharedState).to receive(:with).and_yield(redis_double)
allow(redis_double).to receive(:get).and_return('true')
end
it 'should render json with billing status' do
go
expect(response).to have_http_status(:ok)
expect(response.body).to include_json(billing: 'true')
end
it 'should not start worker' do
expect(CheckGcpProjectBillingWorker).not_to receive(:perform_async)
go
end
end
context 'when redis does not have billing status' do
before do
redis_double = double
allow(Gitlab::Redis::SharedState).to receive(:with).and_yield(redis_double)
allow(redis_double).to receive(:get).and_return(nil)
end
it 'should render json with null billing status' do
go
expect(response).to have_http_status(:ok)
expect(response.body).to include_json(billing: nil)
end
it 'should start worker' do
expect(CheckGcpProjectBillingWorker).to receive(:perform_async)
go
end
end
end
describe 'security' do
it { expect { go }.to be_allowed_for(:admin) }
it { expect { go }.to be_allowed_for(:owner).of(project) }
it { expect { go }.to be_allowed_for(:master).of(project) }
it { expect { go }.to be_denied_for(:developer).of(project) }
it { expect { go }.to be_denied_for(:reporter).of(project) }
it { expect { go }.to be_denied_for(:guest).of(project) }
it { expect { go }.to be_denied_for(:user) }
it { expect { go }.to be_denied_for(:external) }
end
def go
get :check, namespace_id: project.namespace, project_id: project, format: :json
end
end
describe 'GET new' do describe 'GET new' do
describe 'functionality' do describe 'functionality' do
let(:user) { create(:user) } let(:user) { create(:user) }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment