Commit daa3f990 authored by James Fargher's avatar James Fargher

Operator can see all projects using an instance level cluster

Moved logic from groups to apply universally
parent 11ca79e3
...@@ -12,3 +12,5 @@ module Clusters ...@@ -12,3 +12,5 @@ module Clusters
end end
end end
end end
Clusters::InstancePolicy.prepend_if_ee('EE::Clusters::InstancePolicy')
...@@ -145,6 +145,7 @@ Rails.application.routes.draw do ...@@ -145,6 +145,7 @@ Rails.application.routes.draw do
get :metrics, format: :json get :metrics, format: :json
get :metrics_dashboard get :metrics_dashboard
get :'/prometheus/api/v1/*proxy_path', to: 'clusters#prometheus_proxy', as: :prometheus_api get :'/prometheus/api/v1/*proxy_path', to: 'clusters#prometheus_proxy', as: :prometheus_api
get :environments, format: :json
end end
scope :applications do scope :applications do
......
...@@ -7,6 +7,7 @@ module EE ...@@ -7,6 +7,7 @@ module EE
extend ActiveSupport::Concern extend ActiveSupport::Concern
prepended do prepended do
before_action :expire_etag_cache, only: [:show]
before_action :authorize_read_prometheus!, only: :prometheus_proxy before_action :authorize_read_prometheus!, only: :prometheus_proxy
end end
...@@ -51,8 +52,40 @@ module EE ...@@ -51,8 +52,40 @@ module EE
end end
end end
def environments
respond_to do |format|
format.json do
::Gitlab::PollingInterval.set_header(response, interval: 5_000)
environments = ::Clusters::EnvironmentsFinder.new(cluster, current_user).execute
render json: serialize_environments(
environments.preload_for_cluster_environment_entity,
request,
response
)
end
end
end
private private
def expire_etag_cache
return if request.format.json? || !clusterable.environments_cluster_path(cluster)
# this forces to reload json content
::Gitlab::EtagCaching::Store.new.tap do |store|
store.touch(clusterable.environments_cluster_path(cluster))
end
end
def serialize_environments(environments, request, response)
::Clusters::EnvironmentSerializer
.new(cluster: cluster, current_user: current_user)
.with_pagination(request, response)
.represent(environments)
end
def prometheus_adapter def prometheus_adapter
return unless cluster&.application_prometheus_available? return unless cluster&.application_prometheus_available?
......
...@@ -5,44 +5,6 @@ module EE ...@@ -5,44 +5,6 @@ module EE
module ClustersController module ClustersController
extend ActiveSupport::Concern extend ActiveSupport::Concern
prepended do
before_action :expire_etag_cache, only: [:show]
end
def environments
respond_to do |format|
format.json do
::Gitlab::PollingInterval.set_header(response, interval: 5_000)
environments = ::Clusters::EnvironmentsFinder.new(cluster, current_user).execute
render json: serialize_environments(
environments.preload_for_cluster_environment_entity,
request,
response
)
end
end
end
private
def expire_etag_cache
return if request.format.json?
# this forces to reload json content
::Gitlab::EtagCaching::Store.new.tap do |store|
store.touch(environments_group_cluster_path(group, cluster))
end
end
def serialize_environments(environments, request, response)
::Clusters::EnvironmentSerializer
.new(cluster: cluster, current_user: current_user)
.with_pagination(request, response)
.represent(environments)
end
def metrics_dashboard_params def metrics_dashboard_params
{ {
cluster: cluster, cluster: cluster,
......
...@@ -57,6 +57,8 @@ module EE ...@@ -57,6 +57,8 @@ module EE
if cluster&.group_type? if cluster&.group_type?
::Gitlab::Routing.url_helpers.environments_group_cluster_path(cluster.group, cluster) ::Gitlab::Routing.url_helpers.environments_group_cluster_path(cluster.group, cluster)
elsif cluster&.instance_type?
::Gitlab::Routing.url_helpers.environments_admin_cluster_path(cluster)
end end
end end
end end
......
# frozen_string_literal: true
module EE
module Clusters
module InstancePolicy
extend ActiveSupport::Concern
prepended do
condition(:cluster_deployments_available) do
License.feature_available?(:cluster_deployments)
end
rule { can?(:read_cluster) & cluster_deployments_available }
.enable :read_cluster_environments
end
end
end
end
...@@ -9,9 +9,22 @@ module EE ...@@ -9,9 +9,22 @@ module EE
metrics_admin_cluster_path(cluster, params) metrics_admin_cluster_path(cluster, params)
end end
override :environments_cluster_path
def environments_cluster_path(cluster)
return super unless can_read_cluster_environments?
environments_admin_cluster_path(cluster)
end
override :metrics_dashboard_path override :metrics_dashboard_path
def metrics_dashboard_path(cluster) def metrics_dashboard_path(cluster)
metrics_dashboard_admin_cluster_path(cluster) metrics_dashboard_admin_cluster_path(cluster)
end end
private
def can_read_cluster_environments?
can?(current_user, :read_cluster_environments, clusterable)
end
end end
end end
- is_configure_active = !params[:tab] || params[:tab] == 'configure' - is_configure_active = !params[:tab] || params[:tab] == 'configure'
- is_group_type = @cluster.cluster_type.in? 'group_type' - is_project_type = @cluster.cluster_type.in? 'project_type'
- is_creating = @cluster.status_name.in? %i/scheduled creating/ - is_creating = @cluster.status_name.in? %i/scheduled creating/
- if is_group_type && !is_creating - if !is_project_type && !is_creating
.js-toggle-container .js-toggle-container
%ul.nav-links.mobile-separator.nav.nav-tabs{ role: 'tablist' } %ul.nav-links.mobile-separator.nav.nav-tabs{ role: 'tablist' }
%li.nav-item{ role: 'presentation' } %li.nav-item{ role: 'presentation' }
......
---
title: Operator can see all projects using an instance level cluster
merge_request: 18173
author:
type: added
...@@ -31,12 +31,6 @@ constraints(::Constraints::GroupUrlConstrainer.new) do ...@@ -31,12 +31,6 @@ constraints(::Constraints::GroupUrlConstrainer.new) do
end end
end end
resources :clusters, only: [] do
member do
get :environments, format: :json
end
end
resource :ldap, only: [] do resource :ldap, only: [] do
member do member do
put :sync put :sync
......
...@@ -3,8 +3,15 @@ ...@@ -3,8 +3,15 @@
require 'spec_helper' require 'spec_helper'
describe Admin::ClustersController do describe Admin::ClustersController do
include AccessMatchersForController
let(:user) { create(:admin) }
before do
sign_in(user)
end
it_behaves_like 'cluster metrics' do it_behaves_like 'cluster metrics' do
let(:user) { create(:admin) }
let(:clusterable) { Clusters::Instance.new } let(:clusterable) { Clusters::Instance.new }
let(:cluster) do let(:cluster) do
...@@ -50,13 +57,55 @@ describe Admin::ClustersController do ...@@ -50,13 +57,55 @@ describe Admin::ClustersController do
end end
describe 'GET #metrics_dashboard' do describe 'GET #metrics_dashboard' do
let(:user) { create(:admin) } it_behaves_like 'the default dashboard'
end
end
describe 'GET environments' do
let(:cluster) { create(:cluster, :instance, :provided_by_gcp) }
before do
create(:deployment, :success, cluster: cluster)
end
def get_cluster_environments
get :environments,
params: { id: cluster },
format: :json
end
describe 'functionality' do
it 'responds successfully' do
get_cluster_environments
before do expect(response).to have_gitlab_http_status(:ok)
sign_in(user) expect(response.headers['Poll-Interval']).to eq("5000")
end end
end
it_behaves_like 'the default dashboard' describe 'security' do
it { expect { get_cluster_environments }.to be_allowed_for(:admin) }
it { expect { get_cluster_environments }.to be_denied_for(:user) }
it { expect { get_cluster_environments }.to be_denied_for(:external) }
end
end
describe 'GET show' do
let(:cluster) { create(:cluster, :instance, :provided_by_gcp) }
def get_cluster
get :show, params: { id: cluster }
end
it 'expires etag cache to force reload environments list' do
stub_licensed_features(cluster_deployments: true)
expect_next_instance_of(Gitlab::EtagCaching::Store) do |store|
expect(store).to receive(:touch)
.with(environments_admin_cluster_path(cluster))
.and_call_original
end
get_cluster
end end
end end
......
...@@ -151,6 +151,7 @@ describe Groups::ClustersController do ...@@ -151,6 +151,7 @@ describe Groups::ClustersController do
end end
it 'expires etag cache to force reload environments list' do it 'expires etag cache to force reload environments list' do
stub_licensed_features(cluster_deployments: true)
expect_next_instance_of(Gitlab::EtagCaching::Store) do |store| expect_next_instance_of(Gitlab::EtagCaching::Store) do |store|
expect(store).to receive(:touch) expect(store).to receive(:touch)
.with(environments_group_cluster_path(cluster.group, cluster)) .with(environments_group_cluster_path(cluster.group, cluster))
......
...@@ -185,6 +185,28 @@ describe Environment, :use_clean_rails_memory_store_caching do ...@@ -185,6 +185,28 @@ describe Environment, :use_clean_rails_memory_store_caching do
subject subject
end end
end end
context 'with an instance cluster' do
let(:cluster) { create(:cluster, :instance) }
before do
create(:deployment, :success, environment: environment, cluster: cluster)
end
it 'expires the environments path for the group cluster' do
expect_next_instance_of(Gitlab::EtagCaching::Store) do |store|
expect(store).to receive(:touch)
.with(::Gitlab::Routing.url_helpers.project_environments_path(project, format: :json))
.and_call_original
expect(store).to receive(:touch)
.with(::Gitlab::Routing.url_helpers.environments_admin_cluster_path(cluster))
.and_call_original
end
subject
end
end
end end
describe '#rollout_status' do describe '#rollout_status' do
......
...@@ -4,25 +4,21 @@ require 'spec_helper' ...@@ -4,25 +4,21 @@ require 'spec_helper'
describe Clusters::InstancePolicy do describe Clusters::InstancePolicy do
let(:user) { create(:admin) } let(:user) { create(:admin) }
let(:policy) { described_class.new(user, Clusters::Instance.new) } subject { described_class.new(user, Clusters::Instance.new) }
describe 'rules' do context 'when cluster deployments is available' do
context 'when admin' do before do
it { expect(policy).to be_allowed :read_cluster } stub_licensed_features(cluster_deployments: true)
it { expect(policy).to be_allowed :add_cluster }
it { expect(policy).to be_allowed :create_cluster }
it { expect(policy).to be_allowed :update_cluster }
it { expect(policy).to be_allowed :admin_cluster }
end end
context 'when not admin' do it { is_expected.to be_allowed(:read_cluster_environments) }
let(:user) { create(:user) } end
it { expect(policy).to be_disallowed :read_cluster } context 'when cluster deployments is not available' do
it { expect(policy).to be_disallowed :add_cluster } before do
it { expect(policy).to be_disallowed :create_cluster } stub_licensed_features(cluster_deployments: false)
it { expect(policy).to be_disallowed :update_cluster }
it { expect(policy).to be_disallowed :admin_cluster }
end end
it { is_expected.not_to be_allowed(:read_cluster_environments) }
end end
end end
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