Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-03-18 06:09:43 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2020-03-18 06:09:43 +0300
commitb4b9b3854eddd2a4829113ebfc1812c3a332a7d9 (patch)
tree6a21e491917e1606d81329af710459b0217eb1a4 /app
parent2e31c85a97183814ffa7ba5cc58f7bbad668fb2b (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
-rw-r--r--app/assets/javascripts/logs/components/environment_logs.vue23
-rw-r--r--app/assets/javascripts/logs/stores/actions.js5
-rw-r--r--app/assets/javascripts/logs/stores/getters.js4
-rw-r--r--app/assets/javascripts/logs/stores/mutation_types.js1
-rw-r--r--app/assets/javascripts/logs/stores/mutations.js10
-rw-r--r--app/assets/javascripts/logs/stores/state.js2
-rw-r--r--app/assets/javascripts/monitoring/components/dashboard.vue3
-rw-r--r--app/assets/javascripts/monitoring/components/embed.vue3
-rw-r--r--app/assets/javascripts/monitoring/constants.js36
-rw-r--r--app/assets/javascripts/vue_shared/components/date_time_picker/date_time_picker.vue6
-rw-r--r--app/assets/javascripts/vue_shared/constants.js56
-rw-r--r--app/services/pod_logs/base_service.rb52
-rw-r--r--app/services/pod_logs/elasticsearch_service.rb5
-rw-r--r--app/services/pod_logs/kubernetes_service.rb48
14 files changed, 148 insertions, 106 deletions
diff --git a/app/assets/javascripts/logs/components/environment_logs.vue b/app/assets/javascripts/logs/components/environment_logs.vue
index b0acd69bae0..03019e4c25e 100644
--- a/app/assets/javascripts/logs/components/environment_logs.vue
+++ b/app/assets/javascripts/logs/components/environment_logs.vue
@@ -5,15 +5,17 @@ import {
GlSprintf,
GlAlert,
GlDropdown,
+ GlDropdownDivider,
GlDropdownItem,
GlFormGroup,
GlSearchBoxByClick,
GlInfiniteScroll,
} from '@gitlab/ui';
+import { s__ } from '~/locale';
import DateTimePicker from '~/vue_shared/components/date_time_picker/date_time_picker.vue';
import LogControlButtons from './log_control_buttons.vue';
-import { timeRanges, defaultTimeRange } from '~/monitoring/constants';
+import { timeRanges, defaultTimeRange } from '~/vue_shared/constants';
import { timeRangeFromUrl } from '~/monitoring/utils';
import { formatDate } from '../utils';
@@ -22,6 +24,7 @@ export default {
GlSprintf,
GlAlert,
GlDropdown,
+ GlDropdownDivider,
GlDropdownItem,
GlFormGroup,
GlSearchBoxByClick,
@@ -90,6 +93,16 @@ export default {
shouldShowElasticStackCallout() {
return !this.isElasticStackCalloutDismissed && this.disableAdvancedControls;
},
+
+ podDropdownText() {
+ if (this.pods.current) {
+ return this.pods.current;
+ } else if (this.advancedFeaturesEnabled) {
+ // "All pods" is a valid option when advanced querying is available
+ return s__('Environments|All pods');
+ }
+ return s__('Environments|No pod selected');
+ },
},
mounted() {
this.setInitData({
@@ -178,11 +191,17 @@ export default {
>
<gl-dropdown
id="pods-dropdown"
- :text="pods.current || s__('Environments|No pods to display')"
+ :text="podDropdownText"
:disabled="environments.isLoading"
class="d-flex gl-h-32 js-pods-dropdown"
toggle-class="dropdown-menu-toggle"
>
+ <template v-if="advancedFeaturesEnabled">
+ <gl-dropdown-item key="all-pods" @click="showPodLogs(null)">
+ {{ s__('Environments|All pods') }}
+ </gl-dropdown-item>
+ <gl-dropdown-divider />
+ </template>
<gl-dropdown-item
v-for="podName in pods.options"
:key="podName"
diff --git a/app/assets/javascripts/logs/stores/actions.js b/app/assets/javascripts/logs/stores/actions.js
index 4544ebdfec1..834462573cc 100644
--- a/app/assets/javascripts/logs/stores/actions.js
+++ b/app/assets/javascripts/logs/stores/actions.js
@@ -82,7 +82,6 @@ export const setTimeRange = ({ dispatch, commit }, timeRange) => {
export const showEnvironment = ({ dispatch, commit }, environmentName) => {
commit(types.SET_PROJECT_ENVIRONMENT, environmentName);
- commit(types.SET_CURRENT_POD_NAME, null);
dispatch('fetchLogs');
};
@@ -107,16 +106,16 @@ export const fetchEnvironments = ({ commit, dispatch }, environmentsPath) => {
};
export const fetchLogs = ({ commit, state }) => {
- commit(types.REQUEST_PODS_DATA);
commit(types.REQUEST_LOGS_DATA);
return requestLogsUntilData(state)
.then(({ data }) => {
const { pod_name, pods, logs, cursor } = data;
+ commit(types.RECEIVE_LOGS_DATA_SUCCESS, { logs, cursor });
+
commit(types.SET_CURRENT_POD_NAME, pod_name);
commit(types.RECEIVE_PODS_DATA_SUCCESS, pods);
- commit(types.RECEIVE_LOGS_DATA_SUCCESS, { logs, cursor });
})
.catch(() => {
commit(types.RECEIVE_PODS_DATA_ERROR);
diff --git a/app/assets/javascripts/logs/stores/getters.js b/app/assets/javascripts/logs/stores/getters.js
index 58f2dbf4835..8770306fdd6 100644
--- a/app/assets/javascripts/logs/stores/getters.js
+++ b/app/assets/javascripts/logs/stores/getters.js
@@ -1,7 +1,7 @@
import { formatDate } from '../utils';
-const mapTrace = ({ timestamp = null, message = '' }) =>
- [timestamp ? formatDate(timestamp) : '', message].join(' | ');
+const mapTrace = ({ timestamp = null, pod = '', message = '' }) =>
+ [timestamp ? formatDate(timestamp) : '', pod, message].join(' | ');
export const trace = state => state.logs.lines.map(mapTrace).join('\n');
diff --git a/app/assets/javascripts/logs/stores/mutation_types.js b/app/assets/javascripts/logs/stores/mutation_types.js
index 5ff49135e41..7e7771a9df8 100644
--- a/app/assets/javascripts/logs/stores/mutation_types.js
+++ b/app/assets/javascripts/logs/stores/mutation_types.js
@@ -14,6 +14,5 @@ export const REQUEST_LOGS_DATA_PREPEND = 'REQUEST_LOGS_DATA_PREPEND';
export const RECEIVE_LOGS_DATA_PREPEND_SUCCESS = 'RECEIVE_LOGS_DATA_PREPEND_SUCCESS';
export const RECEIVE_LOGS_DATA_PREPEND_ERROR = 'RECEIVE_LOGS_DATA_PREPEND_ERROR';
-export const REQUEST_PODS_DATA = 'REQUEST_PODS_DATA';
export const RECEIVE_PODS_DATA_SUCCESS = 'RECEIVE_PODS_DATA_SUCCESS';
export const RECEIVE_PODS_DATA_ERROR = 'RECEIVE_PODS_DATA_ERROR';
diff --git a/app/assets/javascripts/logs/stores/mutations.js b/app/assets/javascripts/logs/stores/mutations.js
index d94d71cd25a..d77c2894a05 100644
--- a/app/assets/javascripts/logs/stores/mutations.js
+++ b/app/assets/javascripts/logs/stores/mutations.js
@@ -1,8 +1,9 @@
import * as types from './mutation_types';
import { convertToFixedRange } from '~/lib/utils/datetime_range';
-const mapLine = ({ timestamp, message }) => ({
+const mapLine = ({ timestamp, pod, message }) => ({
timestamp,
+ pod,
message,
});
@@ -21,6 +22,10 @@ export default {
// Environments Data
[types.SET_PROJECT_ENVIRONMENT](state, environmentName) {
state.environments.current = environmentName;
+
+ // Clear current pod options
+ state.pods.current = null;
+ state.pods.options = [];
},
[types.REQUEST_ENVIRONMENTS_DATA](state) {
state.environments.options = [];
@@ -81,9 +86,6 @@ export default {
[types.SET_CURRENT_POD_NAME](state, podName) {
state.pods.current = podName;
},
- [types.REQUEST_PODS_DATA](state) {
- state.pods.options = [];
- },
[types.RECEIVE_PODS_DATA_SUCCESS](state, podOptions) {
state.pods.options = podOptions;
},
diff --git a/app/assets/javascripts/logs/stores/state.js b/app/assets/javascripts/logs/stores/state.js
index e058f15b6b4..2c8f47294cc 100644
--- a/app/assets/javascripts/logs/stores/state.js
+++ b/app/assets/javascripts/logs/stores/state.js
@@ -1,4 +1,4 @@
-import { timeRanges, defaultTimeRange } from '~/monitoring/constants';
+import { timeRanges, defaultTimeRange } from '~/vue_shared/constants';
import { convertToFixedRange } from '~/lib/utils/datetime_range';
export default () => ({
diff --git a/app/assets/javascripts/monitoring/components/dashboard.vue b/app/assets/javascripts/monitoring/components/dashboard.vue
index a0bd45bef5e..dbfb3e97c20 100644
--- a/app/assets/javascripts/monitoring/components/dashboard.vue
+++ b/app/assets/javascripts/monitoring/components/dashboard.vue
@@ -31,7 +31,8 @@ import DashboardsDropdown from './dashboards_dropdown.vue';
import TrackEventDirective from '~/vue_shared/directives/track_event';
import { getAddMetricTrackingOptions, timeRangeToUrl, timeRangeFromUrl } from '../utils';
-import { defaultTimeRange, timeRanges, metricStates } from '../constants';
+import { metricStates } from '../constants';
+import { defaultTimeRange, timeRanges } from '~/vue_shared/constants';
export default {
components: {
diff --git a/app/assets/javascripts/monitoring/components/embed.vue b/app/assets/javascripts/monitoring/components/embed.vue
index 826b73908a4..6182b570e76 100644
--- a/app/assets/javascripts/monitoring/components/embed.vue
+++ b/app/assets/javascripts/monitoring/components/embed.vue
@@ -3,7 +3,8 @@ import { mapActions, mapState, mapGetters } from 'vuex';
import PanelType from 'ee_else_ce/monitoring/components/panel_type.vue';
import { convertToFixedRange } from '~/lib/utils/datetime_range';
import { timeRangeFromUrl, removeTimeRangeParams } from '../utils';
-import { sidebarAnimationDuration, defaultTimeRange } from '../constants';
+import { sidebarAnimationDuration } from '../constants';
+import { defaultTimeRange } from '~/vue_shared/constants';
let sidebarMutationObserver;
diff --git a/app/assets/javascripts/monitoring/constants.js b/app/assets/javascripts/monitoring/constants.js
index ddf6c9878df..cc7f5af2259 100644
--- a/app/assets/javascripts/monitoring/constants.js
+++ b/app/assets/javascripts/monitoring/constants.js
@@ -1,5 +1,3 @@
-import { __ } from '~/locale';
-
export const PROMETHEUS_TIMEOUT = 120000; // TWO_MINUTES
/**
@@ -89,37 +87,3 @@ export const dateFormats = {
timeOfDay: 'h:MM TT',
default: 'dd mmm yyyy, h:MMTT',
};
-
-export const timeRanges = [
- {
- label: __('30 minutes'),
- duration: { seconds: 60 * 30 },
- },
- {
- label: __('3 hours'),
- duration: { seconds: 60 * 60 * 3 },
- },
- {
- label: __('8 hours'),
- duration: { seconds: 60 * 60 * 8 },
- default: true,
- },
- {
- label: __('1 day'),
- duration: { seconds: 60 * 60 * 24 * 1 },
- },
- {
- label: __('3 days'),
- duration: { seconds: 60 * 60 * 24 * 3 },
- },
- {
- label: __('1 week'),
- duration: { seconds: 60 * 60 * 24 * 7 * 1 },
- },
- {
- label: __('1 month'),
- duration: { seconds: 60 * 60 * 24 * 30 },
- },
-];
-
-export const defaultTimeRange = timeRanges.find(tr => tr.default);
diff --git a/app/assets/javascripts/vue_shared/components/date_time_picker/date_time_picker.vue b/app/assets/javascripts/vue_shared/components/date_time_picker/date_time_picker.vue
index 9ac687f5e2c..7b09337eb15 100644
--- a/app/assets/javascripts/vue_shared/components/date_time_picker/date_time_picker.vue
+++ b/app/assets/javascripts/vue_shared/components/date_time_picker/date_time_picker.vue
@@ -43,6 +43,11 @@ export default {
required: false,
default: () => defaultTimeRanges,
},
+ customEnabled: {
+ type: Boolean,
+ required: false,
+ default: true,
+ },
},
data() {
return {
@@ -166,6 +171,7 @@ export default {
>
<div class="d-flex justify-content-between gl-p-2">
<gl-form-group
+ v-if="customEnabled"
:label="__('Custom range')"
label-for="custom-from-time"
label-class="gl-pb-1"
diff --git a/app/assets/javascripts/vue_shared/constants.js b/app/assets/javascripts/vue_shared/constants.js
new file mode 100644
index 00000000000..63ce4212717
--- /dev/null
+++ b/app/assets/javascripts/vue_shared/constants.js
@@ -0,0 +1,56 @@
+import { __ } from '~/locale';
+
+const INTERVALS = {
+ minute: 'minute',
+ hour: 'hour',
+ day: 'day',
+};
+
+export const timeRanges = [
+ {
+ label: __('30 minutes'),
+ duration: { seconds: 60 * 30 },
+ name: 'thirtyMinutes',
+ interval: INTERVALS.minute,
+ },
+ {
+ label: __('3 hours'),
+ duration: { seconds: 60 * 60 * 3 },
+ name: 'threeHours',
+ interval: INTERVALS.hour,
+ },
+ {
+ label: __('8 hours'),
+ duration: { seconds: 60 * 60 * 8 },
+ name: 'eightHours',
+ default: true,
+ interval: INTERVALS.hour,
+ },
+ {
+ label: __('1 day'),
+ duration: { seconds: 60 * 60 * 24 * 1 },
+ name: 'oneDay',
+ interval: INTERVALS.hour,
+ },
+ {
+ label: __('3 days'),
+ duration: { seconds: 60 * 60 * 24 * 3 },
+ name: 'threeDays',
+ interval: INTERVALS.hour,
+ },
+ {
+ label: __('1 week'),
+ duration: { seconds: 60 * 60 * 24 * 7 * 1 },
+ name: 'oneWeek',
+ interval: INTERVALS.day,
+ },
+ {
+ label: __('1 month'),
+ duration: { seconds: 60 * 60 * 24 * 30 },
+ name: 'oneMonth',
+ interval: INTERVALS.day,
+ },
+];
+
+export const defaultTimeRange = timeRanges.find(tr => tr.default);
+export const getTimeWindow = timeWindowName => timeRanges.find(tr => tr.name === timeWindowName);
diff --git a/app/services/pod_logs/base_service.rb b/app/services/pod_logs/base_service.rb
index d94d4e92eb6..8cc8fb913a2 100644
--- a/app/services/pod_logs/base_service.rb
+++ b/app/services/pod_logs/base_service.rb
@@ -55,22 +55,10 @@ module PodLogs
return error(_('Cluster does not exist')) if cluster.nil?
return error(_('Namespace is empty')) if namespace.blank?
- success(result)
- end
-
- def check_param_lengths(_result)
- pod_name = params['pod_name'].presence
- container_name = params['container_name'].presence
+ result[:pod_name] = params['pod_name'].presence
+ result[:container_name] = params['container_name'].presence
- if pod_name&.length.to_i > K8S_NAME_MAX_LENGTH
- return error(_('pod_name cannot be larger than %{max_length}'\
- ' chars' % { max_length: K8S_NAME_MAX_LENGTH }))
- elsif container_name&.length.to_i > K8S_NAME_MAX_LENGTH
- return error(_('container_name cannot be larger than'\
- ' %{max_length} chars' % { max_length: K8S_NAME_MAX_LENGTH }))
- end
-
- success(pod_name: pod_name, container_name: container_name)
+ success(result)
end
def get_raw_pods(result)
@@ -85,40 +73,6 @@ module PodLogs
success(result)
end
- def check_pod_name(result)
- # If pod_name is not received as parameter, get the pod logs of the first
- # pod of this namespace.
- result[:pod_name] ||= result[:pods].first
-
- unless result[:pod_name]
- return error(_('No pods available'))
- end
-
- unless result[:pods].include?(result[:pod_name])
- return error(_('Pod does not exist'))
- end
-
- success(result)
- end
-
- def check_container_name(result)
- pod_details = result[:raw_pods].first { |p| p.metadata.name == result[:pod_name] }
- containers = pod_details.spec.containers.map(&:name)
-
- # select first container if not specified
- result[:container_name] ||= containers.first
-
- unless result[:container_name]
- return error(_('No containers available'))
- end
-
- unless containers.include?(result[:container_name])
- return error(_('Container does not exist'))
- end
-
- success(result)
- end
-
def pod_logs(result)
raise NotImplementedError
end
diff --git a/app/services/pod_logs/elasticsearch_service.rb b/app/services/pod_logs/elasticsearch_service.rb
index 3bb6e2bd846..11862de4ade 100644
--- a/app/services/pod_logs/elasticsearch_service.rb
+++ b/app/services/pod_logs/elasticsearch_service.rb
@@ -3,11 +3,8 @@
module PodLogs
class ElasticsearchService < PodLogs::BaseService
steps :check_arguments,
- :check_param_lengths,
:get_raw_pods,
:get_pod_names,
- :check_pod_name,
- :check_container_name,
:check_times,
:check_search,
:check_cursor,
@@ -53,7 +50,7 @@ module PodLogs
response = ::Gitlab::Elasticsearch::Logs.new(client).pod_logs(
namespace,
- result[:pod_name],
+ pod_name: result[:pod_name],
container_name: result[:container_name],
search: result[:search],
start_time: result[:start],
diff --git a/app/services/pod_logs/kubernetes_service.rb b/app/services/pod_logs/kubernetes_service.rb
index 6c8ed74f8e1..92ebb84b877 100644
--- a/app/services/pod_logs/kubernetes_service.rb
+++ b/app/services/pod_logs/kubernetes_service.rb
@@ -8,7 +8,6 @@ module PodLogs
EncodingHelperError = Class.new(StandardError)
steps :check_arguments,
- :check_param_lengths,
:get_raw_pods,
:get_pod_names,
:check_pod_name,
@@ -22,6 +21,50 @@ module PodLogs
private
+ def check_pod_name(result)
+ # If pod_name is not received as parameter, get the pod logs of the first
+ # pod of this namespace.
+ result[:pod_name] ||= result[:pods].first
+
+ unless result[:pod_name]
+ return error(_('No pods available'))
+ end
+
+ unless result[:pod_name].length.to_i <= K8S_NAME_MAX_LENGTH
+ return error(_('pod_name cannot be larger than %{max_length}'\
+ ' chars' % { max_length: K8S_NAME_MAX_LENGTH }))
+ end
+
+ unless result[:pods].include?(result[:pod_name])
+ return error(_('Pod does not exist'))
+ end
+
+ success(result)
+ end
+
+ def check_container_name(result)
+ pod_details = result[:raw_pods].first { |p| p.metadata.name == result[:pod_name] }
+ containers = pod_details.spec.containers.map(&:name)
+
+ # select first container if not specified
+ result[:container_name] ||= containers.first
+
+ unless result[:container_name]
+ return error(_('No containers available'))
+ end
+
+ unless result[:container_name].length.to_i <= K8S_NAME_MAX_LENGTH
+ return error(_('container_name cannot be larger than'\
+ ' %{max_length} chars' % { max_length: K8S_NAME_MAX_LENGTH }))
+ end
+
+ unless containers.include?(result[:container_name])
+ return error(_('Container does not exist'))
+ end
+
+ success(result)
+ end
+
def pod_logs(result)
result[:logs] = cluster.kubeclient.get_pod_log(
result[:pod_name],
@@ -62,7 +105,8 @@ module PodLogs
values = line.split(' ', 2)
{
timestamp: values[0],
- message: values[1]
+ message: values[1],
+ pod: result[:pod_name]
}
end