Commit 518cb413 authored by Adrien Kohlbecker's avatar Adrien Kohlbecker Committed by Natalia Tepluhina

Remove Elastic Stack cluster app feature flag

Enable the app by default
parent 6b832922
...@@ -129,9 +129,6 @@ export default { ...@@ -129,9 +129,6 @@ export default {
crossplaneInstalled() { crossplaneInstalled() {
return this.applications.crossplane.status === APPLICATION_STATUS.INSTALLED; return this.applications.crossplane.status === APPLICATION_STATUS.INSTALLED;
}, },
enableClusterApplicationElasticStack() {
return gon.features && gon.features.enableClusterApplicationElasticStack;
},
ingressModSecurityDescription() { ingressModSecurityDescription() {
const escapedUrl = _.escape(this.ingressModSecurityHelpPath); const escapedUrl = _.escape(this.ingressModSecurityHelpPath);
...@@ -655,7 +652,6 @@ Crossplane runs inside your Kubernetes cluster and supports secure connectivity ...@@ -655,7 +652,6 @@ Crossplane runs inside your Kubernetes cluster and supports secure connectivity
</div> </div>
</application-row> </application-row>
<application-row <application-row
v-if="enableClusterApplicationElasticStack"
id="elastic_stack" id="elastic_stack"
:logo-url="elasticStackLogo" :logo-url="elasticStackLogo"
:title="applications.elastic_stack.title" :title="applications.elastic_stack.title"
......
...@@ -12,9 +12,6 @@ class Clusters::ClustersController < Clusters::BaseController ...@@ -12,9 +12,6 @@ class Clusters::ClustersController < Clusters::BaseController
before_action :authorize_update_cluster!, only: [:update] before_action :authorize_update_cluster!, only: [:update]
before_action :authorize_admin_cluster!, only: [:destroy, :clear_cache] before_action :authorize_admin_cluster!, only: [:destroy, :clear_cache]
before_action :update_applications_status, only: [:cluster_status] before_action :update_applications_status, only: [:cluster_status]
before_action only: [:show] do
push_frontend_feature_flag(:enable_cluster_application_elastic_stack)
end
helper_method :token_in_session helper_method :token_in_session
......
...@@ -58,7 +58,7 @@ module Clusters ...@@ -58,7 +58,7 @@ module Clusters
end end
def instantiate_application def instantiate_application
raise_invalid_application_error if invalid_application? raise_invalid_application_error if unknown_application?
builder || raise(InvalidApplicationError, "invalid application: #{application_name}") builder || raise(InvalidApplicationError, "invalid application: #{application_name}")
end end
...@@ -67,10 +67,6 @@ module Clusters ...@@ -67,10 +67,6 @@ module Clusters
raise(InvalidApplicationError, "invalid application: #{application_name}") raise(InvalidApplicationError, "invalid application: #{application_name}")
end end
def invalid_application?
unknown_application? || (application_name == Applications::ElasticStack.application_name && !Feature.enabled?(:enable_cluster_application_elastic_stack))
end
def unknown_application? def unknown_application?
Clusters::Cluster::APPLICATIONS.keys.exclude?(application_name) Clusters::Cluster::APPLICATIONS.keys.exclude?(application_name)
end end
......
---
title: Add new Elastic Stack cluster application for pod log aggregation
merge_request: 23058
author:
type: added
...@@ -435,18 +435,7 @@ and you will have access to more advanced querying capabilities. ...@@ -435,18 +435,7 @@ and you will have access to more advanced querying capabilities.
Log data is automatically deleted after 15 days using [Curator](https://www.elastic.co/guide/en/elasticsearch/client/curator/5.5/about.html). Log data is automatically deleted after 15 days using [Curator](https://www.elastic.co/guide/en/elasticsearch/client/curator/5.5/about.html).
This is a preliminary release of Elastic Stack as a GitLab-managed application. By default, To enable log shipping, install Elastic Stack into the cluster with the **Install** button.
the ability to install it is disabled.
To allow installation of Elastic Stack as a GitLab-managed application, ask a GitLab
administrator to run following command within a Rails console:
```ruby
Feature.enable(:enable_cluster_application_elastic_stack)
```
Once the feature flag is set, to enable log shipping, install Elastic Stack into the cluster with the
**Install** button.
NOTE: **Note:** NOTE: **Note:**
The [`stable/elastic-stack`](https://github.com/helm/charts/tree/master/stable/elastic-stack) The [`stable/elastic-stack`](https://github.com/helm/charts/tree/master/stable/elastic-stack)
......
...@@ -46,21 +46,20 @@ export default { ...@@ -46,21 +46,20 @@ export default {
showLoader() { showLoader() {
return this.logs.isLoading || !this.logs.isComplete; return this.logs.isLoading || !this.logs.isComplete;
}, },
featureElasticEnabled() {
return gon.features && gon.features.enableClusterApplicationElasticStack;
},
advancedFeaturesEnabled() { advancedFeaturesEnabled() {
const environment = this.environments.options.find( const environment = this.environments.options.find(
({ name }) => name === this.environments.current, ({ name }) => name === this.environments.current,
); );
return this.featureElasticEnabled && environment && environment.enable_advanced_logs_querying; return environment && environment.enable_advanced_logs_querying;
},
disableAdvancedControls() {
return this.environments.isLoading || !this.advancedFeaturesEnabled;
}, },
shouldShowElasticStackCallout() { shouldShowElasticStackCallout() {
return ( return (
!this.isElasticStackCalloutDismissed && !this.isElasticStackCalloutDismissed &&
!this.environments.isLoading &&
!this.logs.isLoading && !this.logs.isLoading &&
!this.advancedFeaturesEnabled !this.disableAdvancedControls
); );
}, },
}, },
...@@ -119,8 +118,7 @@ export default { ...@@ -119,8 +118,7 @@ export default {
:label="s__('Environments|Environment')" :label="s__('Environments|Environment')"
label-size="sm" label-size="sm"
label-for="environments-dropdown" label-for="environments-dropdown"
class="px-1" class="col-3 px-1"
:class="featureElasticEnabled ? 'col-3' : 'col-6'"
> >
<gl-dropdown <gl-dropdown
id="environments-dropdown" id="environments-dropdown"
...@@ -143,8 +141,7 @@ export default { ...@@ -143,8 +141,7 @@ export default {
:label="s__('Environments|Pod logs from')" :label="s__('Environments|Pod logs from')"
label-size="sm" label-size="sm"
label-for="pods-dropdown" label-for="pods-dropdown"
class="px-1" class="col-3 px-1"
:class="featureElasticEnabled ? 'col-3' : 'col-6'"
> >
<gl-dropdown <gl-dropdown
id="pods-dropdown" id="pods-dropdown"
...@@ -162,52 +159,47 @@ export default { ...@@ -162,52 +159,47 @@ export default {
</gl-dropdown-item> </gl-dropdown-item>
</gl-dropdown> </gl-dropdown>
</gl-form-group> </gl-form-group>
<gl-form-group
<template v-if="featureElasticEnabled"> id="dates-fg"
<gl-form-group :label="s__('Environments|Show last')"
id="dates-fg" label-size="sm"
:label="s__('Environments|Show last')" label-for="time-window-dropdown"
label-size="sm" class="col-3 px-1"
label-for="time-window-dropdown" >
class="col-3 px-1" <gl-dropdown
id="time-window-dropdown"
ref="time-window-dropdown"
:disabled="disableAdvancedControls"
:text="timeWindow.options[timeWindow.current].label"
class="d-flex gl-h-32"
toggle-class="dropdown-menu-toggle"
> >
<gl-dropdown <gl-dropdown-item
id="time-window-dropdown" v-for="(option, key) in timeWindow.options"
ref="time-window-dropdown" :key="key"
:disabled="environments.isLoading || !advancedFeaturesEnabled" @click="setTimeWindow(key)"
:text="timeWindow.options[timeWindow.current].label"
class="d-flex gl-h-32"
toggle-class="dropdown-menu-toggle"
> >
<gl-dropdown-item {{ option.label }}
v-for="(option, key) in timeWindow.options" </gl-dropdown-item>
:key="key" </gl-dropdown>
@click="setTimeWindow(key)" </gl-form-group>
> <gl-form-group
{{ option.label }} id="search-fg"
</gl-dropdown-item> :label="s__('Environments|Search')"
</gl-dropdown> label-size="sm"
</gl-form-group> label-for="search"
<gl-form-group class="col-3 px-1"
id="search-fg" >
:label="s__('Environments|Search')" <gl-search-box-by-click
label-size="sm" v-model.trim="searchQuery"
label-for="search" :disabled="disableAdvancedControls"
class="col-3 px-1" :placeholder="s__('Environments|Search')"
> class="js-logs-search"
<gl-search-box-by-click type="search"
v-model.trim="searchQuery" autofocus
:disabled="environments.isLoading || !advancedFeaturesEnabled" @submit="disableAdvancedControls && setSearch(searchQuery)"
:placeholder="s__('Environments|Search')" />
class="js-logs-search" </gl-form-group>
type="search"
autofocus
@submit="
(environments.isLoading || !advancedFeaturesEnabled) && setSearch(searchQuery)
"
/>
</gl-form-group>
</template>
</div> </div>
<log-control-buttons <log-control-buttons
......
...@@ -4,9 +4,6 @@ module Projects ...@@ -4,9 +4,6 @@ module Projects
class LogsController < Projects::ApplicationController class LogsController < Projects::ApplicationController
before_action :authorize_read_pod_logs! before_action :authorize_read_pod_logs!
before_action :environment before_action :environment
before_action do
push_frontend_feature_flag(:enable_cluster_application_elastic_stack)
end
def index def index
if environment.nil? if environment.nil?
......
...@@ -92,7 +92,7 @@ module EE ...@@ -92,7 +92,7 @@ module EE
end end
def elastic_stack_available? def elastic_stack_available?
::Feature.enabled?(:enable_cluster_application_elastic_stack) && !!cluster.application_elastic_stack !!cluster.application_elastic_stack
end end
private private
......
...@@ -114,15 +114,13 @@ describe('EnvironmentLogs', () => { ...@@ -114,15 +114,13 @@ describe('EnvironmentLogs', () => {
expect(findPodsDropdown().is(GlDropdown)).toBe(true); expect(findPodsDropdown().is(GlDropdown)).toBe(true);
expect(findLogControlButtons().exists()).toBe(true); expect(findLogControlButtons().exists()).toBe(true);
expect(findSearchBar().exists()).toBe(false); // behind ff expect(findSearchBar().exists()).toBe(true);
expect(findTimeWindowDropdown().exists()).toBe(false); // behind ff expect(findSearchBar().is(GlSearchBoxByClick)).toBe(true);
expect(findTimeWindowDropdown().exists()).toBe(true);
expect(findTimeWindowDropdown().is(GlDropdown)).toBe(true);
// log trace // log trace
expect(findLogTrace().isEmpty()).toBe(false); expect(findLogTrace().isEmpty()).toBe(false);
// layout
expect(wrapper.find('#environments-dropdown-fg').attributes('class')).toMatch('col-6');
expect(wrapper.find('#pods-dropdown-fg').attributes('class')).toMatch('col-6');
}); });
it('mounted inits data', () => { it('mounted inits data', () => {
...@@ -156,15 +154,24 @@ describe('EnvironmentLogs', () => { ...@@ -156,15 +154,24 @@ describe('EnvironmentLogs', () => {
}); });
it('displays a disabled environments dropdown', () => { it('displays a disabled environments dropdown', () => {
expect(findEnvironmentsDropdown().attributes('disabled')).toEqual('true'); expect(findEnvironmentsDropdown().attributes('disabled')).toBe('true');
expect(findEnvironmentsDropdown().findAll(GlDropdownItem).length).toBe(0); expect(findEnvironmentsDropdown().findAll(GlDropdownItem).length).toBe(0);
}); });
it('displays a disabled pods dropdown', () => { it('displays a disabled pods dropdown', () => {
expect(findPodsDropdown().attributes('disabled')).toEqual('true'); expect(findPodsDropdown().attributes('disabled')).toBe('true');
expect(findPodsDropdown().findAll(GlDropdownItem).length).toBe(0); expect(findPodsDropdown().findAll(GlDropdownItem).length).toBe(0);
}); });
it('displays a disabled search bar', () => {
expect(findSearchBar().exists()).toBe(true);
expect(findSearchBar().attributes('disabled')).toBe('true');
});
it('displays a disabled time window dropdown', () => {
expect(findTimeWindowDropdown().attributes('disabled')).toBe('true');
});
it('does not update buttons state', () => { it('does not update buttons state', () => {
expect(updateControlBtnsMock).not.toHaveBeenCalled(); expect(updateControlBtnsMock).not.toHaveBeenCalled();
}); });
...@@ -179,22 +186,7 @@ describe('EnvironmentLogs', () => { ...@@ -179,22 +186,7 @@ describe('EnvironmentLogs', () => {
}); });
}); });
describe('elastic stack disabled', () => { describe('legacy environment', () => {
beforeEach(() => {
gon.features = gon.features || {};
gon.features.enableClusterApplicationElasticStack = false;
initWrapper();
});
it("doesn't display the search bar", () => {
expect(findSearchBar().exists()).toEqual(false);
expect(wrapper.find('#environments-dropdown-fg').attributes('class')).toEqual('px-1 col-6');
expect(wrapper.find('#pods-dropdown-fg').attributes('class')).toEqual('px-1 col-6');
});
});
describe('ES enabled and legacy environment', () => {
beforeEach(() => { beforeEach(() => {
state.pods.options = []; state.pods.options = [];
...@@ -209,15 +201,13 @@ describe('EnvironmentLogs', () => { ...@@ -209,15 +201,13 @@ describe('EnvironmentLogs', () => {
isLoading: false, isLoading: false,
}; };
gon.features = gon.features || {};
gon.features.enableClusterApplicationElasticStack = true;
initWrapper(); initWrapper();
}); });
it('displays a disabled search bar', () => { it('displays a disabled search bar and time window dropdown', () => {
expect(findSearchBar().exists()).toEqual(true); expect(findSearchBar().exists()).toBe(true);
expect(findSearchBar().attributes('disabled')).toEqual('true'); expect(findSearchBar().attributes('disabled')).toBe('true');
expect(findTimeWindowDropdown().attributes('disabled')).toBe('true');
}); });
}); });
...@@ -227,9 +217,6 @@ describe('EnvironmentLogs', () => { ...@@ -227,9 +217,6 @@ describe('EnvironmentLogs', () => {
actionMocks.showPodLogs.mockImplementation(mockShowPodLogs); actionMocks.showPodLogs.mockImplementation(mockShowPodLogs);
actionMocks.fetchEnvironments.mockImplementation(mockFetchEnvs); actionMocks.fetchEnvironments.mockImplementation(mockFetchEnvs);
gon.features = gon.features || {};
gon.features.enableClusterApplicationElasticStack = true;
initWrapper(); initWrapper();
}); });
...@@ -242,6 +229,14 @@ describe('EnvironmentLogs', () => { ...@@ -242,6 +229,14 @@ describe('EnvironmentLogs', () => {
actionMocks.fetchEnvironments.mockReset(); actionMocks.fetchEnvironments.mockReset();
}); });
it('displays an enabled search bar', () => {
expect(findSearchBar().attributes('disabled')).toBeFalsy();
});
it('displays an enabled time window dropdown', () => {
expect(findTimeWindowDropdown().attributes('disabled')).toBeFalsy();
});
it('populates environments dropdown', () => { it('populates environments dropdown', () => {
const items = findEnvironmentsDropdown().findAll(GlDropdownItem); const items = findEnvironmentsDropdown().findAll(GlDropdownItem);
expect(findEnvironmentsDropdown().props('text')).toBe(mockEnvName); expect(findEnvironmentsDropdown().props('text')).toBe(mockEnvName);
...@@ -312,103 +307,4 @@ describe('EnvironmentLogs', () => { ...@@ -312,103 +307,4 @@ describe('EnvironmentLogs', () => {
}); });
}); });
}); });
describe('when feature flag enable_cluster_application_elastic_stack is enabled', () => {
let originalGon;
beforeEach(() => {
originalGon = window.gon;
window.gon = { features: { enableClusterApplicationElasticStack: true } };
});
afterEach(() => {
window.gon = originalGon;
});
it('displays UI elements', () => {
initWrapper();
// elements
expect(findSearchBar().exists()).toBe(true);
expect(findSearchBar().is(GlSearchBoxByClick)).toBe(true);
expect(findTimeWindowDropdown().exists()).toBe(true);
expect(findTimeWindowDropdown().is(GlDropdown)).toBe(true);
// layout
expect(wrapper.find('#environments-dropdown-fg').attributes('class')).toMatch('col-3');
expect(wrapper.find('#pods-dropdown-fg').attributes('class')).toMatch('col-3');
expect(wrapper.find('#dates-fg').attributes('class')).toMatch('col-3');
expect(wrapper.find('#search-fg').attributes('class')).toMatch('col-3');
});
describe('loading state', () => {
beforeEach(() => {
state.pods.options = [];
state.logs = {
lines: [],
isLoading: true,
};
state.environments = {
options: [],
isLoading: true,
};
initWrapper();
});
it('displays a disabled search bar', () => {
expect(findSearchBar().exists()).toEqual(true);
expect(findSearchBar().attributes('disabled')).toEqual('true');
});
it('displays a disabled time window dropdown', () => {
expect(findTimeWindowDropdown().attributes('disabled')).toEqual('true');
});
});
describe('when advanced querying is disabled', () => {
beforeEach(() => {
state.pods.options = [];
state.logs = {
lines: [],
isLoading: false,
};
state.environments = {
options: [],
isLoading: false,
};
state.enableAdvancedQuerying = false;
initWrapper();
});
it('search bar and time window dropdown are disabled', () => {
expect(findSearchBar().attributes('disabled')).toEqual('true');
expect(findTimeWindowDropdown().attributes('disabled')).toEqual('true');
});
});
describe('state with data', () => {
beforeEach(() => {
actionMocks.setInitData.mockImplementation(mockSetInitData);
actionMocks.showPodLogs.mockImplementation(mockShowPodLogs);
actionMocks.fetchEnvironments.mockImplementation(mockFetchEnvs);
initWrapper();
});
it('displays an enabled search bar', () => {
expect(findSearchBar().attributes('disabled')).toBeFalsy();
});
it('displays an enabled time window dropdown', () => {
expect(findTimeWindowDropdown().attributes('disabled')).toBeFalsy();
});
});
});
}); });
...@@ -179,7 +179,6 @@ describe Clusters::Platforms::Kubernetes do ...@@ -179,7 +179,6 @@ describe Clusters::Platforms::Kubernetes do
before do before do
expect_any_instance_of(::Clusters::Applications::ElasticStack).to receive(:elasticsearch_client).at_least(:once).and_return(Elasticsearch::Transport::Client.new) expect_any_instance_of(::Clusters::Applications::ElasticStack).to receive(:elasticsearch_client).at_least(:once).and_return(Elasticsearch::Transport::Client.new)
expect_any_instance_of(::Gitlab::Elasticsearch::Logs).to receive(:pod_logs).and_return(expected_logs) expect_any_instance_of(::Gitlab::Elasticsearch::Logs).to receive(:pod_logs).and_return(expected_logs)
stub_feature_flags(enable_cluster_application_elastic_stack: true)
end end
include_examples 'successful log request' include_examples 'successful log request'
......
...@@ -14,9 +14,6 @@ describe('Applications', () => { ...@@ -14,9 +14,6 @@ describe('Applications', () => {
beforeEach(() => { beforeEach(() => {
Applications = Vue.extend(applications); Applications = Vue.extend(applications);
gon.features = gon.features || {};
gon.features.enableClusterApplicationElasticStack = true;
}); });
afterEach(() => { afterEach(() => {
......
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