From 6a65e2f5f94781a69f3f7fb329483ead6bc81fd9 Mon Sep 17 00:00:00 2001 From: Shinya Maeda Date: Tue, 31 Oct 2017 17:47:48 +0900 Subject: specs for controller. Improved validation --- .../projects/clusters_controller_spec.rb | 543 ++++++++++++++------- spec/factories/clusters/cluster.rb | 4 +- spec/factories/clusters/platforms/kubernetes.rb | 13 +- spec/models/clusters/cluster_spec.rb | 2 + spec/models/clusters/platforms/kubernetes_spec.rb | 90 ++-- spec/support/google_api/cloud_platform_helpers.rb | 150 ++++++ spec/support/google_api_helpers.rb | 140 ------ spec/support/kubernetes_helpers.rb | 2 +- 8 files changed, 568 insertions(+), 376 deletions(-) create mode 100644 spec/support/google_api/cloud_platform_helpers.rb delete mode 100644 spec/support/google_api_helpers.rb (limited to 'spec') diff --git a/spec/controllers/projects/clusters_controller_spec.rb b/spec/controllers/projects/clusters_controller_spec.rb index 7985028d73b..fd1a68ba7e1 100644 --- a/spec/controllers/projects/clusters_controller_spec.rb +++ b/spec/controllers/projects/clusters_controller_spec.rb @@ -1,68 +1,108 @@ require 'spec_helper' describe Projects::ClustersController do - set(:user) { create(:user) } - set(:project) { create(:project) } - let(:role) { :master } + include AccessMatchersForController + include GoogleApi::CloudPlatformHelpers - before do - project.team << [user, role] + describe 'GET index' do + describe 'functionality' do + let(:user) { create(:user) } - sign_in(user) - end + before do + project.add_master(user) + sign_in(user) + end - describe 'GET index' do - subject do - get :index, namespace_id: project.namespace, - project_id: project - end + context 'when project has a cluster' do + let(:cluster) { create(:cluster, :project, :provided_by_gcp) } + let(:project) { cluster.project } - context 'when cluster is already created' do - let!(:cluster) { create(:gcp_cluster, :created_on_gke, project: project) } + it { expect(go).to redirect_to(project_cluster_path(project, project.cluster)) } + end - it 'redirects to show a cluster' do - subject + context 'when project does not have a cluster' do + let(:project) { create(:project) } - expect(response).to redirect_to(project_cluster_path(project, cluster)) + it { expect(go).to redirect_to(new_project_cluster_path(project)) } end end - context 'when we do not have cluster' do - it 'redirects to create a cluster' do - subject + describe 'security' do + let(:cluster) { create(:cluster, :project, :provided_by_gcp) } + let(:project) { cluster.project } + + 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 - expect(response).to redirect_to(new_project_cluster_path(project)) - end + def go + get :index, namespace_id: project.namespace.to_param, project_id: project end end describe 'GET login' do - render_views + let(:project) { create(:project) } - subject do - get :login, namespace_id: project.namespace, - project_id: project - end + describe 'functionality' do + let(:user) { create(:user) } - context 'when we do have omniauth configured' do - it 'shows login button' do - subject - - expect(response.body).to include('auth_buttons/signin_with_google') + before do + project.add_master(user) + sign_in(user) end - end - context 'when we do not have omniauth configured' do - before do - stub_omniauth_setting(providers: []) + context 'when omniauth has been configured' do + let(:key) { 'secere-key' } + + let(:session_key_for_redirect_uri) do + GoogleApi::CloudPlatform::Client.session_key_for_redirect_uri(key) + end + + before do + allow(SecureRandom).to receive(:hex).and_return(key) + end + + it 'has authorize_url' do + go + + expect(assigns(:authorize_url)).to include(key) + expect(session[session_key_for_redirect_uri]).to eq(namespace_project_clusters_url(project.namespace, project)) + end end - it 'shows notice message' do - subject + context 'when omniauth has not configured' do + before do + stub_omniauth_setting(providers: []) + end - expect(response.body).to include('Ask your GitLab administrator if you want to use this service.') + it 'does not have authorize_url' do + go + + expect(assigns(:authorize_url)).to be_nil + 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 :login, namespace_id: project.namespace, project_id: project + end end shared_examples 'requires to login' do @@ -74,235 +114,406 @@ describe Projects::ClustersController do end describe 'GET new' do - render_views + let(:project) { create(:project) } - subject do - get :new, namespace_id: project.namespace, - project_id: project - end + describe 'functionality' do + let(:user) { create(:user) } - context 'when logged' do before do - make_logged_in + project.add_master(user) + sign_in(user) + end + + context 'when access token is valid' do + before do + stub_google_api_validate_token + end + + it 'has new object' do + go + + expect(assigns(:cluster)).to be_an_instance_of(Clusters::Cluster) + end end - it 'shows a creation form' do - subject + context 'when access token is expired' do + before do + stub_google_api_expired_token + end + + it { expect(go).to redirect_to(login_project_clusters_path(project)) } + end - expect(response.body).to include('Create cluster') + context 'when access token is not stored in session' do + it { expect(go).to redirect_to(login_project_clusters_path(project)) } end end - context 'when not logged' do - it_behaves_like 'requires to login' + 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 :new, namespace_id: project.namespace, project_id: project end end describe 'POST create' do - subject do - post :create, params.merge(namespace_id: project.namespace, - project_id: project) + let(:project) { create(:project) } + + let(:params) do + { + cluster: { + name: 'new-cluster', + platform_type: :kubernetes, + provider_type: :gcp, + provider_gcp_attributes: { + gcp_project_id: '111', + } + } + } end - context 'when not logged' do - let(:params) { {} } - - it_behaves_like 'requires to login' - end + describe 'functionality' do + let(:user) { create(:user) } - context 'when logged in' do before do - make_logged_in + project.add_master(user) + sign_in(user) end - context 'when all required parameters are set' do - let(:params) do - { - cluster: { - gcp_cluster_name: 'new-cluster', - gcp_project_id: '111' - } - } + context 'when access token is valid' do + before do + stub_google_api_validate_token end - before do - expect(ClusterProvisionWorker).to receive(:perform_async) { } + context 'when creates a cluster on gke' do + it 'creates a new cluster' do + expect(ClusterProvisionWorker).to receive(:perform_async) + expect { go }.to change { Clusters::Cluster.count } + expect(response).to redirect_to(project_cluster_path(project, project.cluster)) + end end - it 'creates a new cluster' do - expect { subject }.to change { Gcp::Cluster.count } + context 'when adds a cluster manually' do + let(:params) do + { + cluster: { + name: 'new-cluster', + platform_type: :kubernetes, + provider_type: :user + } + } + end - expect(response).to redirect_to(project_cluster_path(project, project.cluster)) + it 'creates a new cluster' do + expect(ClusterProvisionWorker).to receive(:perform_async) + expect { go }.to change { Clusters::Cluster.count } + expect(response).to redirect_to(project_cluster_path(project, project.cluster)) + end end - end - - context 'when not all required parameters are set' do - render_views - let(:params) do - { - cluster: { - project_namespace: 'some namespace' + context 'when not all required parameters are set' do + let(:params) do + { + cluster: { + name: 'new-cluster' + } } - } + end + + it 'shows an error message' do + expect { go }.not_to change { Clusters::Cluster.count } + expect(assigns(:cluster).errors).not_to be_empty + expect(response).to render_template(:new) + end + end + end + + context 'when access token is expired' do + before do + stub_google_api_expired_token end - it 'shows an error message' do - expect { subject }.not_to change { Gcp::Cluster.count } + it 'redirects to login page' do + expect(go).to redirect_to(login_project_clusters_path(project)) + end + end - expect(response).to render_template(:new) + context 'when access token is not stored in session' do + it 'redirects to login page' do + expect(go).to redirect_to(login_project_clusters_path(project)) 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 + post :create, params.merge(namespace_id: project.namespace, project_id: project) + end end describe 'GET status' do - let(:cluster) { create(:gcp_cluster, :created_on_gke, project: project) } + let(:cluster) { create(:cluster, :project, :providing_by_gcp) } + let(:project) { cluster.project } + + describe 'functionality' do + let(:user) { create(:user) } - subject do + before do + project.add_master(user) + sign_in(user) + end + + it "responds with matching schema" do + go + + expect(response).to have_http_status(:ok) + expect(response).to match_response_schema('cluster_status') + 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 :status, namespace_id: project.namespace, project_id: project, id: cluster, format: :json end - - it "responds with matching schema" do - subject - - expect(response).to have_http_status(:ok) - expect(response).to match_response_schema('cluster_status') - end end describe 'GET show' do - render_views - - let(:cluster) { create(:gcp_cluster, :created_on_gke, project: project) } + let(:cluster) { create(:cluster, :project, :provided_by_gcp) } + let(:project) { cluster.project } - subject do - get :show, namespace_id: project.namespace, - project_id: project, - id: cluster - end + describe 'functionality' do + let(:user) { create(:user) } - context 'when logged as master' do - it "allows to update cluster" do - subject - - expect(response).to have_http_status(:ok) - expect(response.body).to include("Save") + before do + project.add_master(user) + sign_in(user) end - it "allows remove integration" do - subject + it "renders view" do + go expect(response).to have_http_status(:ok) - expect(response.body).to include("Remove integration") + expect(assigns(:cluster)).to eq(cluster) end end - context 'when logged as developer' do - let(:role) { :developer } - - it "does not allow to access page" do - subject + 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 - expect(response).to have_http_status(:not_found) - end + def go + get :show, namespace_id: project.namespace, + project_id: project, + id: cluster end end describe 'PUT update' do - render_views + let(:cluster) { create(:cluster, :project, :provided_by_gcp) } + let(:project) { cluster.project } - let(:service) { project.build_kubernetes_service } - let(:cluster) { create(:gcp_cluster, :created_on_gke, project: project, service: service) } - let(:params) { {} } + describe 'functionality' do + let(:user) { create(:user) } - subject do - put :update, params.merge(namespace_id: project.namespace, - project_id: project, - id: cluster) - end + before do + project.add_master(user) + sign_in(user) + end - context 'when logged as master' do - context 'when valid params are used' do + context 'when update enabled' do let(:params) do { cluster: { enabled: false } } end - it "redirects back to show page" do - subject + it "updates and redirects back to show page" do + go + cluster.reload expect(response).to redirect_to(project_cluster_path(project, project.cluster)) expect(flash[:notice]).to eq('Cluster was successfully updated.') + expect(cluster.enabled).to be_falsey + end + + context 'when cluster is being created' do + let(:cluster) { create(:cluster, :project, :providing_by_gcp) } + + it "rejects changes" do + go + + expect(response).to have_http_status(:ok) + expect(response).to render_template(:show) + expect(cluster.enabled).to be_truthy + end end end - context 'when invalid params are used' do + context 'when update namespace' do + let(:namespace) { 'namespace-123' } + let(:params) do { - cluster: { project_namespace: 'my Namespace 321321321 #' } + cluster: { + platform_kubernetes_attributes: { + namespace: namespace + } + } } end - it "rejects changes" do - subject + it "updates and redirects back to show page" do + go + + cluster.reload + expect(response).to redirect_to(project_cluster_path(project, project.cluster)) + expect(flash[:notice]).to eq('Cluster was successfully updated.') + expect(cluster.platform.namespace).to eq(namespace) + end + + context 'when namespace is invalid' do + let(:namespace) { 'my Namespace 321321321 #' } + + it "rejects changes" do + go - expect(response).to have_http_status(:ok) - expect(response).to render_template(:show) + expect(response).to have_http_status(:ok) + expect(response).to render_template(:show) + expect(cluster.platform.namespace).not_to eq(namespace) + end end end end - context 'when logged as developer' do - let(:role) { :developer } + describe 'security' do + let(:params) do + { + cluster: { enabled: false } + } + end - it "does not allow to update cluster" do - subject + 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 - expect(response).to have_http_status(:not_found) - end + def go + put :update, params.merge(namespace_id: project.namespace, + project_id: project, + id: cluster) end end describe 'delete update' do - let(:cluster) { create(:gcp_cluster, :created_on_gke, project: project) } + let(:cluster) { create(:cluster, :project, :provided_by_gcp) } + let(:project) { cluster.project } - subject do - delete :destroy, namespace_id: project.namespace, - project_id: project, - id: cluster - end + describe 'functionality' do + let(:user) { create(:user) } - context 'when logged as master' do - it "redirects back to clusters list" do - subject + before do + project.add_master(user) + sign_in(user) + end + + it "destroys and redirects back to clusters list" do + expect { go } + .to change { Clusters::Cluster.count }.by(-1) + .and change { Clusters::Platforms::Kubernetes.count }.by(-1) + .and change { Clusters::Providers::Gcp.count }.by(-1) expect(response).to redirect_to(project_clusters_path(project)) expect(flash[:notice]).to eq('Cluster integration was successfully removed.') end - end - context 'when logged as developer' do - let(:role) { :developer } + context 'when cluster is being created' do + let(:cluster) { create(:cluster, :project, :providing_by_gcp) } + + it "destroys and redirects back to clusters list" do + expect { go } + .to change { Clusters::Cluster.count }.by(-1) + .and change { Clusters::Platforms::Kubernetes.count }.by(-1) + .and change { Clusters::Providers::Gcp.count }.by(-1) + + expect(response).to redirect_to(project_clusters_path(project)) + expect(flash[:notice]).to eq('Cluster integration was successfully removed.') + end + end + + context 'when provider is user' do + let(:cluster) { create(:cluster, :project, :provided_by_user) } - it "does not allow to destroy cluster" do - subject + it "destroys and redirects back to clusters list" do + expect { go } + .to change { Clusters::Cluster.count }.by(-1) + .and change { Clusters::Platforms::Kubernetes.count }.by(-1) + .and change { Clusters::Providers::Gcp.count }.by(0) - expect(response).to have_http_status(:not_found) + expect(response).to redirect_to(project_clusters_path(project)) + expect(flash[:notice]).to eq('Cluster integration was successfully removed.') + end end end - end - def make_logged_in - session[GoogleApi::CloudPlatform::Client.session_key_for_token] = '1234' - session[GoogleApi::CloudPlatform::Client.session_key_for_expires_at] = in_hour.to_i.to_s - 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 in_hour - Time.now + 1.hour + def go + delete :destroy, namespace_id: project.namespace, + project_id: project, + id: cluster + end end end diff --git a/spec/factories/clusters/cluster.rb b/spec/factories/clusters/cluster.rb index ad116ecfa16..ef09cfbf5e3 100644 --- a/spec/factories/clusters/cluster.rb +++ b/spec/factories/clusters/cluster.rb @@ -42,7 +42,9 @@ FactoryGirl.define do end after(:create) do |cluster, evaluator| - create(:platform_kubernetes, cluster: cluster) + build(:platform_kubernetes, cluster: cluster).tap do |platform| + platform.save!(validate: false) + end end end end diff --git a/spec/factories/clusters/platforms/kubernetes.rb b/spec/factories/clusters/platforms/kubernetes.rb index 69c2f30f859..86adaddfcb9 100644 --- a/spec/factories/clusters/platforms/kubernetes.rb +++ b/spec/factories/clusters/platforms/kubernetes.rb @@ -3,19 +3,16 @@ FactoryGirl.define do cluster namespace nil - trait :ca_cert do - after(:create) do |platform_kubernetes, evaluator| - pem_file = File.expand_path(Rails.root.join('spec/fixtures/clusters/sample_cert.pem')) - platform_kubernetes.ca_cert = File.read(pem_file) - end - end - trait :configured do api_url 'https://kubernetes.example.com' - ca_cert nil token 'a' * 40 username 'xxxxxx' password 'xxxxxx' + + after(:create) do |platform_kubernetes, evaluator| + pem_file = File.expand_path(Rails.root.join('spec/fixtures/clusters/sample_cert.pem')) + platform_kubernetes.ca_cert = File.read(pem_file) + end end end end diff --git a/spec/models/clusters/cluster_spec.rb b/spec/models/clusters/cluster_spec.rb index e53ce8497f5..997ed865545 100644 --- a/spec/models/clusters/cluster_spec.rb +++ b/spec/models/clusters/cluster_spec.rb @@ -10,6 +10,8 @@ describe Clusters::Cluster do it { is_expected.to delegate_method(:status_name).to(:provider) } it { is_expected.to delegate_method(:on_creation?).to(:provider) } it { is_expected.to respond_to :project } + it { is_expected.to validate_presence_of(:provider_type) } + it { is_expected.to validate_presence_of(:platform_type) } describe '.enabled' do subject { described_class.enabled } diff --git a/spec/models/clusters/platforms/kubernetes_spec.rb b/spec/models/clusters/platforms/kubernetes_spec.rb index ec6ecee6ff2..d11ce690601 100644 --- a/spec/models/clusters/platforms/kubernetes_spec.rb +++ b/spec/models/clusters/platforms/kubernetes_spec.rb @@ -11,7 +11,7 @@ describe Clusters::Platforms::Kubernetes, :use_clean_rails_memory_store_caching describe 'before_validation' do context 'when namespace includes upper case' do - let(:kubernetes) { create(:platform_kubernetes, namespace: namespace) } + let(:kubernetes) { create(:platform_kubernetes, :configured, namespace: namespace) } let(:namespace) { 'ABC' } it 'converts to lower case' do @@ -24,7 +24,7 @@ describe Clusters::Platforms::Kubernetes, :use_clean_rails_memory_store_caching subject { kubernetes.valid? } context 'when validates namespace' do - let(:kubernetes) { build(:platform_kubernetes, namespace: namespace) } + let(:kubernetes) { build(:platform_kubernetes, :configured, namespace: namespace) } context 'when namespace is blank' do let(:namespace) { '' } @@ -52,74 +52,42 @@ describe Clusters::Platforms::Kubernetes, :use_clean_rails_memory_store_caching end context 'when validates api_url' do - context 'when updates a record' do - let(:kubernetes) { create(:platform_kubernetes) } + let(:kubernetes) { build(:platform_kubernetes, :configured) } - before do - kubernetes.api_url = api_url - end - - context 'when api_url is invalid url' do - let(:api_url) { '!!!!!!' } - - it { expect(kubernetes.save).to be_falsey } - end - - context 'when api_url is nil' do - let(:api_url) { nil } - - it { expect(kubernetes.save).to be_falsey } - end + before do + kubernetes.api_url = api_url + end - context 'when api_url is valid url' do - let(:api_url) { 'https://111.111.111.111' } + context 'when api_url is invalid url' do + let(:api_url) { '!!!!!!' } - it { expect(kubernetes.save).to be_truthy } - end + it { expect(kubernetes.save).to be_falsey } end - context 'when creates a record' do - let(:kubernetes) { build(:platform_kubernetes) } + context 'when api_url is nil' do + let(:api_url) { nil } - before do - kubernetes.api_url = api_url - end + it { expect(kubernetes.save).to be_falsey } + end - context 'when api_url is nil' do - let(:api_url) { nil } + context 'when api_url is valid url' do + let(:api_url) { 'https://111.111.111.111' } - it { expect(kubernetes.save).to be_truthy } - end + it { expect(kubernetes.save).to be_truthy } end end context 'when validates token' do - context 'when updates a record' do - let(:kubernetes) { create(:platform_kubernetes) } + let(:kubernetes) { build(:platform_kubernetes, :configured) } - before do - kubernetes.token = token - end - - context 'when token is nil' do - let(:token) { nil } - - it { expect(kubernetes.save).to be_falsey } - end + before do + kubernetes.token = token end - context 'when creates a record' do - let(:kubernetes) { build(:platform_kubernetes) } + context 'when token is nil' do + let(:token) { nil } - before do - kubernetes.token = token - end - - context 'when token is nil' do - let(:token) { nil } - - it { expect(kubernetes.save).to be_truthy } - end + it { expect(kubernetes.save).to be_falsey } end end end @@ -128,7 +96,8 @@ describe Clusters::Platforms::Kubernetes, :use_clean_rails_memory_store_caching subject { kubernetes.actual_namespace } let!(:cluster) { create(:cluster, :project, platform_kubernetes: kubernetes) } - let(:kubernetes) { create(:platform_kubernetes, namespace: namespace) } + let(:project) { cluster.project } + let(:kubernetes) { create(:platform_kubernetes, :configured, namespace: namespace) } context 'when namespace is present' do let(:namespace) { 'namespace-123' } @@ -139,7 +108,7 @@ describe Clusters::Platforms::Kubernetes, :use_clean_rails_memory_store_caching context 'when namespace is not present' do let(:namespace) { nil } - it { is_expected.to eq("#{cluster.project.path}-#{cluster.project.id}") } + it { is_expected.to eq("#{project.path}-#{project.id}") } end end @@ -154,12 +123,13 @@ describe Clusters::Platforms::Kubernetes, :use_clean_rails_memory_store_caching describe '#default_namespace' do subject { kubernetes.default_namespace } - let(:kubernetes) { create(:platform_kubernetes) } + let(:kubernetes) { create(:platform_kubernetes, :configured) } context 'when cluster belongs to a project' do let!(:cluster) { create(:cluster, :project, platform_kubernetes: kubernetes) } + let(:project) { cluster.project } - it { is_expected.to eq("#{cluster.project.path}-#{cluster.project.id}") } + it { is_expected.to eq("#{project.path}-#{project.id}") } end context 'when cluster belongs to nothing' do @@ -229,7 +199,7 @@ describe Clusters::Platforms::Kubernetes, :use_clean_rails_memory_store_caching let!(:cluster) { create(:cluster, :project, platform_kubernetes: service) } let(:project) { cluster.project } - let(:service) { create(:platform_kubernetes) } + let(:service) { create(:platform_kubernetes, :configured) } let(:environment) { build(:environment, project: project, name: "env", slug: "env-000000") } context 'with invalid pods' do @@ -268,7 +238,7 @@ describe Clusters::Platforms::Kubernetes, :use_clean_rails_memory_store_caching subject { service.calculate_reactive_cache } let!(:cluster) { create(:cluster, :project, enabled: enabled, platform_kubernetes: service) } - let(:service) { create(:platform_kubernetes, :ca_cert) } + let(:service) { create(:platform_kubernetes, :configured) } let(:enabled) { true } context 'when cluster is disabled' do diff --git a/spec/support/google_api/cloud_platform_helpers.rb b/spec/support/google_api/cloud_platform_helpers.rb new file mode 100644 index 00000000000..ef73add3991 --- /dev/null +++ b/spec/support/google_api/cloud_platform_helpers.rb @@ -0,0 +1,150 @@ +module GoogleApi + module CloudPlatformHelpers + def stub_google_api_validate_token + request.session[GoogleApi::CloudPlatform::Client.session_key_for_token] = 'token' + request.session[GoogleApi::CloudPlatform::Client.session_key_for_expires_at] = 1.hour.since.to_i.to_s + end + + def stub_google_api_expired_token + request.session[GoogleApi::CloudPlatform::Client.session_key_for_token] = 'token' + request.session[GoogleApi::CloudPlatform::Client.session_key_for_expires_at] = 1.hour.ago.to_i.to_s + end + + def stub_cloud_platform_get_zone_cluster(project_id, zone, cluster_id, **options) + WebMock.stub_request(:get, cloud_platform_get_zone_cluster_url(project_id, zone, cluster_id)) + .to_return(cloud_platform_response(cloud_platform_cluster_body(options))) + end + + def stub_cloud_platform_get_zone_cluster_error(project_id, zone, cluster_id) + WebMock.stub_request(:get, cloud_platform_get_zone_cluster_url(project_id, zone, cluster_id)) + .to_return(status: [500, "Internal Server Error"]) + end + + def stub_cloud_platform_create_cluster(project_id, zone, **options) + WebMock.stub_request(:post, cloud_platform_create_cluster_url(project_id, zone)) + .to_return(cloud_platform_response(cloud_platform_operation_body(options))) + end + + def stub_cloud_platform_create_cluster_error(project_id, zone) + WebMock.stub_request(:post, cloud_platform_create_cluster_url(project_id, zone)) + .to_return(status: [500, "Internal Server Error"]) + end + + def stub_cloud_platform_get_zone_operation(project_id, zone, operation_id, **options) + WebMock.stub_request(:get, cloud_platform_get_zone_operation_url(project_id, zone, operation_id)) + .to_return(cloud_platform_response(cloud_platform_operation_body(options))) + end + + def stub_cloud_platform_get_zone_operation_error(project_id, zone, operation_id) + WebMock.stub_request(:get, cloud_platform_get_zone_operation_url(project_id, zone, operation_id)) + .to_return(status: [500, "Internal Server Error"]) + end + + def cloud_platform_get_zone_cluster_url(project_id, zone, cluster_id) + "https://container.googleapis.com/v1/projects/#{project_id}/zones/#{zone}/clusters/#{cluster_id}" + end + + def cloud_platform_create_cluster_url(project_id, zone) + "https://container.googleapis.com/v1/projects/#{project_id}/zones/#{zone}/clusters" + end + + def cloud_platform_get_zone_operation_url(project_id, zone, operation_id) + "https://container.googleapis.com/v1/projects/#{project_id}/zones/#{zone}/operations/#{operation_id}" + end + + def cloud_platform_response(body) + { status: 200, headers: { 'Content-Type' => 'application/json' }, body: body.to_json } + end + + def load_sample_cert + pem_file = File.expand_path(Rails.root.join('spec/fixtures/clusters/sample_cert.pem')) + Base64.encode64(File.read(pem_file)) + end + + def cloud_platform_cluster_body(**options) + { + "name": options[:name] || 'string', + "description": options[:description] || 'string', + "initialNodeCount": options[:initialNodeCount] || 'number', + # "nodeConfig": {, + # object(NodeConfig), + # },, + "masterAuth": { + "username": options[:username] || 'string', + "password": options[:password] || 'string', + # "clientCertificateConfig": { + # object(ClientCertificateConfig) + # }, + "clusterCaCertificate": options[:clusterCaCertificate] || load_sample_cert, + "clientCertificate": options[:clientCertificate] || 'string', + "clientKey": options[:clientKey] || 'string' + }, + "loggingService": options[:loggingService] || 'string', + "monitoringService": options[:monitoringService] || 'string', + "network": options[:network] || 'string', + "clusterIpv4Cidr": options[:clusterIpv4Cidr] || 'string', + # "addonsConfig": {, + # object(AddonsConfig), + # },, + "subnetwork": options[:subnetwork] || 'string', + # "nodePools": [, + # {, + # object(NodePool), + # }, + # ],, + # "locations": [, + # string, + # ],, + "enableKubernetesAlpha": options[:enableKubernetesAlpha] || 'boolean', + # "resourceLabels": {, + # string: string,, + # ..., + # },, + "labelFingerprint": options[:labelFingerprint] || 'string', + # "legacyAbac": {, + # object(LegacyAbac), + # }, + # "networkPolicy": {, + # object(NetworkPolicy), + # }, + # "ipAllocationPolicy": {, + # object(IPAllocationPolicy), + # }, + # "masterAuthorizedNetworksConfig": {, + # object(MasterAuthorizedNetworksConfig), + # }, + "selfLink": options[:selfLink] || 'string', + "zone": options[:zone] || 'string', + "endpoint": options[:endpoint] || 'string', + "initialClusterVersion": options[:initialClusterVersion] || 'string', + "currentMasterVersion": options[:currentMasterVersion] || 'string', + "currentNodeVersion": options[:currentNodeVersion] || 'string', + "createTime": options[:createTime] || 'string', + "status": options[:status] || 'RUNNING', + "statusMessage": options[:statusMessage] || 'string', + "nodeIpv4CidrSize": options[:nodeIpv4CidrSize] || 'number', + "servicesIpv4Cidr": options[:servicesIpv4Cidr] || 'string', + # "instanceGroupUrls": [, + # string, + # ],, + "currentNodeCount": options[:currentNodeCount] || 'number', + "expireTime": options[:expireTime] || 'string' + } + end + + def cloud_platform_operation_body(**options) + { + "name": options[:name] || 'operation-1234567891234-1234567', + "zone": options[:zone] || 'us-central1-a', + "operationType": options[:operationType] || 'CREATE_CLUSTER', + "status": options[:status] || 'PENDING', + "detail": options[:detail] || 'detail', + "statusMessage": options[:statusMessage] || '', + "selfLink": options[:selfLink] || 'https://container.googleapis.com/v1/projects/123456789101/zones/us-central1-a/operations/operation-1234567891234-1234567', + "targetLink": options[:targetLink] || 'https://container.googleapis.com/v1/projects/123456789101/zones/us-central1-a/clusters/test-cluster', + "startTime": options[:startTime] || '2017-09-13T16:49:13.055601589Z', + "endTime": options[:endTime] || '' + } + end + end +end diff --git a/spec/support/google_api_helpers.rb b/spec/support/google_api_helpers.rb deleted file mode 100644 index f032b028741..00000000000 --- a/spec/support/google_api_helpers.rb +++ /dev/null @@ -1,140 +0,0 @@ -module GoogleApi - module CloudPlatformHelpers - def stub_cloud_platform_get_zone_cluster(project_id, zone, cluster_id, **options) - WebMock.stub_request(:get, cloud_platform_get_zone_cluster_url(project_id, zone, cluster_id)) - .to_return(cloud_platform_response(cloud_platform_cluster_body(options))) - end - - def stub_cloud_platform_get_zone_cluster_error(project_id, zone, cluster_id) - WebMock.stub_request(:get, cloud_platform_get_zone_cluster_url(project_id, zone, cluster_id)) - .to_return(status: [500, "Internal Server Error"]) - end - - def stub_cloud_platform_create_cluster(project_id, zone, **options) - WebMock.stub_request(:post, cloud_platform_create_cluster_url(project_id, zone)) - .to_return(cloud_platform_response(cloud_platform_operation_body(options))) - end - - def stub_cloud_platform_create_cluster_error(project_id, zone) - WebMock.stub_request(:post, cloud_platform_create_cluster_url(project_id, zone)) - .to_return(status: [500, "Internal Server Error"]) - end - - def stub_cloud_platform_get_zone_operation(project_id, zone, operation_id, **options) - WebMock.stub_request(:get, cloud_platform_get_zone_operation_url(project_id, zone, operation_id)) - .to_return(cloud_platform_response(cloud_platform_operation_body(options))) - end - - def stub_cloud_platform_get_zone_operation_error(project_id, zone, operation_id) - WebMock.stub_request(:get, cloud_platform_get_zone_operation_url(project_id, zone, operation_id)) - .to_return(status: [500, "Internal Server Error"]) - end - - def cloud_platform_get_zone_cluster_url(project_id, zone, cluster_id) - "https://container.googleapis.com/v1/projects/#{project_id}/zones/#{zone}/clusters/#{cluster_id}" - end - - def cloud_platform_create_cluster_url(project_id, zone) - "https://container.googleapis.com/v1/projects/#{project_id}/zones/#{zone}/clusters" - end - - def cloud_platform_get_zone_operation_url(project_id, zone, operation_id) - "https://container.googleapis.com/v1/projects/#{project_id}/zones/#{zone}/operations/#{operation_id}" - end - - def cloud_platform_response(body) - { status: 200, headers: { 'Content-Type' => 'application/json' }, body: body.to_json } - end - - def load_sample_cert - pem_file = File.expand_path(Rails.root.join('spec/fixtures/clusters/sample_cert.pem')) - Base64.encode64(File.read(pem_file)) - end - - def cloud_platform_cluster_body(**options) - { - "name": options[:name] || 'string', - "description": options[:description] || 'string', - "initialNodeCount": options[:initialNodeCount] || 'number', - # "nodeConfig": {, - # object(NodeConfig), - # },, - "masterAuth": { - "username": options[:username] || 'string', - "password": options[:password] || 'string', - # "clientCertificateConfig": { - # object(ClientCertificateConfig) - # }, - "clusterCaCertificate": options[:clusterCaCertificate] || load_sample_cert, - "clientCertificate": options[:clientCertificate] || 'string', - "clientKey": options[:clientKey] || 'string' - }, - "loggingService": options[:loggingService] || 'string', - "monitoringService": options[:monitoringService] || 'string', - "network": options[:network] || 'string', - "clusterIpv4Cidr": options[:clusterIpv4Cidr] || 'string', - # "addonsConfig": {, - # object(AddonsConfig), - # },, - "subnetwork": options[:subnetwork] || 'string', - # "nodePools": [, - # {, - # object(NodePool), - # }, - # ],, - # "locations": [, - # string, - # ],, - "enableKubernetesAlpha": options[:enableKubernetesAlpha] || 'boolean', - # "resourceLabels": {, - # string: string,, - # ..., - # },, - "labelFingerprint": options[:labelFingerprint] || 'string', - # "legacyAbac": {, - # object(LegacyAbac), - # }, - # "networkPolicy": {, - # object(NetworkPolicy), - # }, - # "ipAllocationPolicy": {, - # object(IPAllocationPolicy), - # }, - # "masterAuthorizedNetworksConfig": {, - # object(MasterAuthorizedNetworksConfig), - # }, - "selfLink": options[:selfLink] || 'string', - "zone": options[:zone] || 'string', - "endpoint": options[:endpoint] || 'string', - "initialClusterVersion": options[:initialClusterVersion] || 'string', - "currentMasterVersion": options[:currentMasterVersion] || 'string', - "currentNodeVersion": options[:currentNodeVersion] || 'string', - "createTime": options[:createTime] || 'string', - "status": options[:status] || 'RUNNING', - "statusMessage": options[:statusMessage] || 'string', - "nodeIpv4CidrSize": options[:nodeIpv4CidrSize] || 'number', - "servicesIpv4Cidr": options[:servicesIpv4Cidr] || 'string', - # "instanceGroupUrls": [, - # string, - # ],, - "currentNodeCount": options[:currentNodeCount] || 'number', - "expireTime": options[:expireTime] || 'string' - } - end - - def cloud_platform_operation_body(**options) - { - "name": options[:name] || 'operation-1234567891234-1234567', - "zone": options[:zone] || 'us-central1-a', - "operationType": options[:operationType] || 'CREATE_CLUSTER', - "status": options[:status] || 'PENDING', - "detail": options[:detail] || 'detail', - "statusMessage": options[:statusMessage] || '', - "selfLink": options[:selfLink] || 'https://container.googleapis.com/v1/projects/123456789101/zones/us-central1-a/operations/operation-1234567891234-1234567', - "targetLink": options[:targetLink] || 'https://container.googleapis.com/v1/projects/123456789101/zones/us-central1-a/clusters/test-cluster', - "startTime": options[:startTime] || '2017-09-13T16:49:13.055601589Z', - "endTime": options[:endTime] || '' - } - end - end -end diff --git a/spec/support/kubernetes_helpers.rb b/spec/support/kubernetes_helpers.rb index 1916bec05b8..3ae325637f6 100644 --- a/spec/support/kubernetes_helpers.rb +++ b/spec/support/kubernetes_helpers.rb @@ -14,7 +14,7 @@ module KubernetesHelpers end def stub_kubeclient_pods(response = nil) - stub_kubeclient_discover + stub_kubeclient_discover(service.api_url) pods_url = service.api_url + "/api/v1/namespaces/#{service.actual_namespace}/pods" WebMock.stub_request(:get, pods_url).to_return(response || kube_pods_response) -- cgit v1.2.3