Commit f8d01f16 authored by Robert Speicher's avatar Robert Speicher

Merge branch '207031-json-index-controller' into 'master'

Added json index action to cluster controller

Closes #207031

See merge request gitlab-org/gitlab!30635
parents a30e482f 5542c66c
...@@ -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