Commit 5542c66c authored by Emily Ring's avatar Emily Ring

Added json cluster controller

Add new json response to cluster index action
Add new serializer fields to display json content
Added tests for new controller
parent 1468db1d
...@@ -18,20 +18,19 @@ class Clusters::ClustersController < Clusters::BaseController ...@@ -18,20 +18,19 @@ class Clusters::ClustersController < Clusters::BaseController
STATUS_POLLING_INTERVAL = 10_000 STATUS_POLLING_INTERVAL = 10_000
def index def index
finder = ClusterAncestorsFinder.new(clusterable.subject, current_user) @clusters = cluster_list
clusters = finder.execute
# Note: We are paginating through an array here but this should OK as: respond_to do |format|
# format.html
# In CE, we can have a maximum group nesting depth of 21, so including format.json do
# project cluster, we can have max 22 clusters for a group hierarchy. serializer = ClusterSerializer.new(current_user: current_user)
# In EE (Premium) we can have any number, as multiple clusters are
# supported, but the number of clusters are fairly low currently.
#
# See https://gitlab.com/gitlab-org/gitlab-foss/issues/55260 also.
@clusters = Kaminari.paginate_array(clusters).page(params[:page]).per(20)
@has_ancestor_clusters = finder.has_ancestor_clusters? render json: {
clusters: serializer.with_pagination(request, response).represent_list(@clusters),
has_ancestor_clusters: @has_ancestor_clusters
}
end
end
end end
def new def new
...@@ -158,6 +157,23 @@ class Clusters::ClustersController < Clusters::BaseController ...@@ -158,6 +157,23 @@ class Clusters::ClustersController < Clusters::BaseController
private private
def cluster_list
finder = ClusterAncestorsFinder.new(clusterable.subject, current_user)
clusters = finder.execute
@has_ancestor_clusters = finder.has_ancestor_clusters?
# Note: We are paginating through an array here but this should OK as:
#
# In CE, we can have a maximum group nesting depth of 21, so including
# project cluster, we can have max 22 clusters for a group hierarchy.
# In EE (Premium) we can have any number, as multiple clusters are
# supported, but the number of clusters are fairly low currently.
#
# See https://gitlab.com/gitlab-org/gitlab-foss/issues/55260 also.
Kaminari.paginate_array(clusters).page(params[:page]).per(20)
end
def destroy_params def destroy_params
params.permit(:cleanup) params.permit(:cleanup)
end end
......
...@@ -3,7 +3,16 @@ ...@@ -3,7 +3,16 @@
class ClusterEntity < Grape::Entity class ClusterEntity < Grape::Entity
include RequestAwareEntity include RequestAwareEntity
expose :cluster_type
expose :enabled
expose :environment_scope
expose :name
expose :status_name, as: :status expose :status_name, as: :status
expose :status_reason expose :status_reason
expose :path do |cluster|
Clusters::ClusterPresenter.new(cluster).show_path # rubocop: disable CodeReuse/Presenter
end
expose :applications, using: ClusterApplicationEntity expose :applications, using: ClusterApplicationEntity
end end
# frozen_string_literal: true # frozen_string_literal: true
class ClusterSerializer < BaseSerializer class ClusterSerializer < BaseSerializer
include WithPagination
entity ClusterEntity entity ClusterEntity
def represent_list(resource)
represent(resource, {
only: [
:cluster_type,
:enabled,
:environment_scope,
:name,
:path,
:status
]
})
end
def represent_status(resource) def represent_status(resource)
represent(resource, { only: [:status, :status_reason, :applications] }) represent(resource, { only: [:status, :status_reason, :applications] })
end end
......
...@@ -27,7 +27,7 @@ describe Admin::ClustersController do ...@@ -27,7 +27,7 @@ describe Admin::ClustersController do
create(:cluster, :disabled, :provided_by_gcp, :production_environment, :instance) create(:cluster, :disabled, :provided_by_gcp, :production_environment, :instance)
end end
it 'lists available clusters' do it 'lists available clusters and displays html' do
get_index get_index
expect(response).to have_gitlab_http_status(:ok) expect(response).to have_gitlab_http_status(:ok)
...@@ -35,20 +35,39 @@ describe Admin::ClustersController do ...@@ -35,20 +35,39 @@ describe Admin::ClustersController do
expect(assigns(:clusters)).to match_array([enabled_cluster, disabled_cluster]) expect(assigns(:clusters)).to match_array([enabled_cluster, disabled_cluster])
end end
it 'lists available clusters and renders json serializer' do
get_index(format: :json)
expect(response).to have_gitlab_http_status(:ok)
expect(response).to match_response_schema('cluster_list')
end
context 'when page is specified' do context 'when page is specified' do
let(:last_page) { Clusters::Cluster.instance_type.page.total_pages } let(:last_page) { Clusters::Cluster.instance_type.page.total_pages }
let(:total_count) { Clusters::Cluster.instance_type.page.total_count }
before do before do
allow(Clusters::Cluster).to receive(:paginates_per).and_return(1) create_list(:cluster, 30, :provided_by_gcp, :production_environment, :instance)
create_list(:cluster, 2, :provided_by_gcp, :production_environment, :instance)
end end
it 'redirects to the page' do it 'redirects to the page' do
expect(last_page).to be > 1
get_index(page: last_page) get_index(page: last_page)
expect(response).to have_gitlab_http_status(:ok) expect(response).to have_gitlab_http_status(:ok)
expect(assigns(:clusters).current_page).to eq(last_page) expect(assigns(:clusters).current_page).to eq(last_page)
end end
it 'displays cluster list for associated page' do
expect(last_page).to be > 1
get_index(page: last_page, format: :json)
expect(response).to have_gitlab_http_status(:ok)
expect(response.headers['X-Page'].to_i).to eq(last_page)
expect(response.headers['X-Total'].to_i).to eq(total_count)
end
end end
end end
......
...@@ -32,7 +32,7 @@ describe Groups::ClustersController do ...@@ -32,7 +32,7 @@ describe Groups::ClustersController do
create(:cluster, :disabled, :provided_by_gcp, :production_environment, cluster_type: :group_type, groups: [group]) create(:cluster, :disabled, :provided_by_gcp, :production_environment, cluster_type: :group_type, groups: [group])
end end
it 'lists available clusters' do it 'lists available clusters and renders html' do
go go
expect(response).to have_gitlab_http_status(:ok) expect(response).to have_gitlab_http_status(:ok)
...@@ -40,20 +40,39 @@ describe Groups::ClustersController do ...@@ -40,20 +40,39 @@ describe Groups::ClustersController do
expect(assigns(:clusters)).to match_array([enabled_cluster, disabled_cluster]) expect(assigns(:clusters)).to match_array([enabled_cluster, disabled_cluster])
end end
it 'lists available clusters with json serializer' do
go(format: :json)
expect(response).to have_gitlab_http_status(:ok)
expect(response).to match_response_schema('cluster_list')
end
context 'when page is specified' do context 'when page is specified' do
let(:last_page) { group.clusters.page.total_pages } let(:last_page) { group.clusters.page.total_pages }
let(:total_count) { group.clusters.page.total_count }
before do before do
allow(Clusters::Cluster).to receive(:paginates_per).and_return(1) create_list(:cluster, 30, :provided_by_gcp, :production_environment, cluster_type: :group_type, groups: [group])
create_list(:cluster, 2, :provided_by_gcp, :production_environment, cluster_type: :group_type, groups: [group])
end end
it 'redirects to the page' do it 'redirects to the page' do
expect(last_page).to be > 1
go(page: last_page) go(page: last_page)
expect(response).to have_gitlab_http_status(:ok) expect(response).to have_gitlab_http_status(:ok)
expect(assigns(:clusters).current_page).to eq(last_page) expect(assigns(:clusters).current_page).to eq(last_page)
end end
it 'displays cluster list for associated page' do
expect(last_page).to be > 1
go(page: last_page, format: :json)
expect(response).to have_gitlab_http_status(:ok)
expect(response.headers['X-Page'].to_i).to eq(last_page)
expect(response.headers['X-Total'].to_i).to eq(total_count)
end
end end
end end
......
...@@ -26,7 +26,7 @@ describe Projects::ClustersController do ...@@ -26,7 +26,7 @@ describe Projects::ClustersController do
let!(:enabled_cluster) { create(:cluster, :provided_by_gcp, projects: [project]) } let!(:enabled_cluster) { create(:cluster, :provided_by_gcp, projects: [project]) }
let!(:disabled_cluster) { create(:cluster, :disabled, :provided_by_gcp, :production_environment, projects: [project]) } let!(:disabled_cluster) { create(:cluster, :disabled, :provided_by_gcp, :production_environment, projects: [project]) }
it 'lists available clusters' do it 'lists available clusters and renders html' do
go go
expect(response).to have_gitlab_http_status(:ok) expect(response).to have_gitlab_http_status(:ok)
...@@ -34,20 +34,39 @@ describe Projects::ClustersController do ...@@ -34,20 +34,39 @@ describe Projects::ClustersController do
expect(assigns(:clusters)).to match_array([enabled_cluster, disabled_cluster]) expect(assigns(:clusters)).to match_array([enabled_cluster, disabled_cluster])
end end
it 'lists available clusters with json serializer' do
go(format: :json)
expect(response).to have_gitlab_http_status(:ok)
expect(response).to match_response_schema('cluster_list')
end
context 'when page is specified' do context 'when page is specified' do
let(:last_page) { project.clusters.page.total_pages } let(:last_page) { project.clusters.page.total_pages }
let(:total_count) { project.clusters.page.total_count }
before do before do
allow(Clusters::Cluster).to receive(:paginates_per).and_return(1) create_list(:cluster, 30, :provided_by_gcp, :production_environment, projects: [project])
create_list(:cluster, 2, :provided_by_gcp, :production_environment, projects: [project])
end end
it 'redirects to the page' do it 'redirects to the page' do
expect(last_page).to be > 1
go(page: last_page) go(page: last_page)
expect(response).to have_gitlab_http_status(:ok) expect(response).to have_gitlab_http_status(:ok)
expect(assigns(:clusters).current_page).to eq(last_page) expect(assigns(:clusters).current_page).to eq(last_page)
end end
it 'displays cluster list for associated page' do
expect(last_page).to be > 1
go(page: last_page, format: :json)
expect(response).to have_gitlab_http_status(:ok)
expect(response.headers['X-Page'].to_i).to eq(last_page)
expect(response.headers['X-Total'].to_i).to eq(total_count)
end
end end
end end
...@@ -68,9 +87,11 @@ describe Projects::ClustersController do ...@@ -68,9 +87,11 @@ describe Projects::ClustersController do
it 'is allowed for admin when admin mode enabled', :enable_admin_mode do it 'is allowed for admin when admin mode enabled', :enable_admin_mode do
expect { go }.to be_allowed_for(:admin) expect { go }.to be_allowed_for(:admin)
end end
it 'is disabled for admin when admin mode disabled' do it 'is disabled for admin when admin mode disabled' do
expect { go }.to be_denied_for(:admin) expect { go }.to be_denied_for(:admin)
end end
it { expect { go }.to be_allowed_for(:owner).of(project) } it { expect { go }.to be_allowed_for(:owner).of(project) }
it { expect { go }.to be_allowed_for(:maintainer).of(project) } it { expect { go }.to be_allowed_for(:maintainer).of(project) }
it { expect { go }.to be_denied_for(:developer).of(project) } it { expect { go }.to be_denied_for(:developer).of(project) }
......
{
"clusters": {
"type": "array",
"items": {
"cluster_type": "string",
"enabled": "boolean",
"environment_scope": "string",
"name": "string",
"path": "string",
"status": "string"
}
},
"has_ancestor_clusters": { "type": ["boolean", "false"] }
}
...@@ -7,7 +7,7 @@ describe ClusterEntity do ...@@ -7,7 +7,7 @@ describe ClusterEntity do
subject { described_class.new(cluster).as_json } subject { described_class.new(cluster).as_json }
context 'when provider type is gcp' do context 'when provider type is gcp' do
let(:cluster) { create(:cluster, provider_type: :gcp, provider_gcp: provider) } let(:cluster) { create(:cluster, :instance, provider_type: :gcp, provider_gcp: provider) }
context 'when status is creating' do context 'when status is creating' do
let(:provider) { create(:cluster_provider_gcp, :creating) } let(:provider) { create(:cluster_provider_gcp, :creating) }
...@@ -29,7 +29,7 @@ describe ClusterEntity do ...@@ -29,7 +29,7 @@ describe ClusterEntity do
end end
context 'when provider type is user' do context 'when provider type is user' do
let(:cluster) { create(:cluster, provider_type: :user) } let(:cluster) { create(:cluster, :instance, provider_type: :user) }
it 'has corresponded data' do it 'has corresponded data' do
expect(subject[:status]).to eq(:created) expect(subject[:status]).to eq(:created)
...@@ -38,7 +38,7 @@ describe ClusterEntity do ...@@ -38,7 +38,7 @@ describe ClusterEntity do
end end
context 'when no application has been installed' do context 'when no application has been installed' do
let(:cluster) { create(:cluster) } let(:cluster) { create(:cluster, :instance) }
subject { described_class.new(cluster).as_json[:applications]} subject { described_class.new(cluster).as_json[:applications]}
......
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