[MM-53019] Add file storage permission check to workspace health dashboard (#24403)
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
3d81a63b4e
Коммит
4ed32be6d2
@@ -153,7 +153,7 @@ func getSystemPing(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||||||
// Enhanced ping health check:
|
// Enhanced ping health check:
|
||||||
// If an extra form value is provided then perform extra health checks for
|
// If an extra form value is provided then perform extra health checks for
|
||||||
// database and file storage backends.
|
// database and file storage backends.
|
||||||
if r.FormValue("get_server_status") != "" {
|
if r.FormValue("get_server_status") == "true" {
|
||||||
dbStatusKey := "database_status"
|
dbStatusKey := "database_status"
|
||||||
s[dbStatusKey] = model.StatusOk
|
s[dbStatusKey] = model.StatusOk
|
||||||
|
|
||||||
|
|||||||
@@ -444,9 +444,9 @@ export function restartServer() {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function ping() {
|
export function ping(getServerStatus, deviceId) {
|
||||||
return async () => {
|
return async () => {
|
||||||
const data = await Client4.ping();
|
const data = await Client4.ping(getServerStatus, deviceId);
|
||||||
return data;
|
return data;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ import type {useIntl} from 'react-intl';
|
|||||||
|
|
||||||
import type {AdminConfig} from '@mattermost/types/config';
|
import type {AdminConfig} from '@mattermost/types/config';
|
||||||
|
|
||||||
|
import {Client4} from 'mattermost-redux/client';
|
||||||
|
|
||||||
import {ConsolePages, DocLinks} from 'utils/constants';
|
import {ConsolePages, DocLinks} from 'utils/constants';
|
||||||
|
|
||||||
import {impactModifiers} from '../dashboard.data';
|
import {impactModifiers} from '../dashboard.data';
|
||||||
@@ -74,6 +76,40 @@ const sessionLength = (
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const fileStorage = async (
|
||||||
|
config: Partial<AdminConfig>,
|
||||||
|
formatMessage: ReturnType<typeof useIntl>['formatMessage'],
|
||||||
|
options: Options,
|
||||||
|
) => {
|
||||||
|
const testFileStorage = async () => {
|
||||||
|
const pingResponse = await Client4.ping(true);
|
||||||
|
|
||||||
|
return pingResponse.filestore_status === 'OK' ? ItemStatus.OK : ItemStatus.ERROR;
|
||||||
|
};
|
||||||
|
|
||||||
|
const status = await testFileStorage();
|
||||||
|
|
||||||
|
return {
|
||||||
|
id: 'file_storage,',
|
||||||
|
title: formatMessage({
|
||||||
|
id: 'admin.reporting.workspace_optimization.configuration.file_storage.title',
|
||||||
|
defaultMessage: 'File storage access is faulty.',
|
||||||
|
}),
|
||||||
|
description: formatMessage({
|
||||||
|
id: 'admin.reporting.workspace_optimization.configuration.file_storage.description',
|
||||||
|
defaultMessage: 'Check your file storage settings to ensure your Mattermost workspace has access to the configured file storage.',
|
||||||
|
}),
|
||||||
|
configUrl: ConsolePages.FILE_STORAGE,
|
||||||
|
configText: formatMessage({id: 'admin.reporting.workspace_optimization.configuration.file_storage.cta', defaultMessage: 'Config file storage'}),
|
||||||
|
infoUrl: DocLinks.FILE_STORAGE,
|
||||||
|
infoText: formatMessage({id: 'admin.reporting.workspace_optimization.cta.learnMore', defaultMessage: 'Learn more'}),
|
||||||
|
telemetryAction: 'file_storage',
|
||||||
|
status,
|
||||||
|
scoreImpact: 50,
|
||||||
|
impactModifier: impactModifiers[status],
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
export const runConfigChecks = async (
|
export const runConfigChecks = async (
|
||||||
config: Partial<AdminConfig>,
|
config: Partial<AdminConfig>,
|
||||||
formatMessage: ReturnType<typeof useIntl>['formatMessage'],
|
formatMessage: ReturnType<typeof useIntl>['formatMessage'],
|
||||||
@@ -82,6 +118,7 @@ export const runConfigChecks = async (
|
|||||||
const checks = [
|
const checks = [
|
||||||
ssl,
|
ssl,
|
||||||
sessionLength,
|
sessionLength,
|
||||||
|
fileStorage,
|
||||||
];
|
];
|
||||||
const results = await Promise.all(checks.map((check) => check(config, formatMessage, options)));
|
const results = await Promise.all(checks.map((check) => check(config, formatMessage, options)));
|
||||||
return results;
|
return results;
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ const RenewalLink = (props: RenewalLinkProps) => {
|
|||||||
const handleLinkClick = async (e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {
|
const handleLinkClick = async (e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
try {
|
try {
|
||||||
const {status} = await Client4.ping();
|
const {status} = await Client4.ping(false);
|
||||||
if (status === 'OK' && renewalLink !== '') {
|
if (status === 'OK' && renewalLink !== '') {
|
||||||
if (props.telemetryInfo?.success) {
|
if (props.telemetryInfo?.success) {
|
||||||
trackEvent('renew_license', props.telemetryInfo.success);
|
trackEvent('renew_license', props.telemetryInfo.success);
|
||||||
|
|||||||
@@ -1972,6 +1972,9 @@
|
|||||||
"admin.reporting.workspace_optimization.chip_warnings": "Warnings: {count}",
|
"admin.reporting.workspace_optimization.chip_warnings": "Warnings: {count}",
|
||||||
"admin.reporting.workspace_optimization.configuration.description": "You have configuration issues to resolve",
|
"admin.reporting.workspace_optimization.configuration.description": "You have configuration issues to resolve",
|
||||||
"admin.reporting.workspace_optimization.configuration.descriptionOk": "You seem to have good configuration for SSL and Session Lengths!",
|
"admin.reporting.workspace_optimization.configuration.descriptionOk": "You seem to have good configuration for SSL and Session Lengths!",
|
||||||
|
"admin.reporting.workspace_optimization.configuration.file_storage.cta": "Config file storage",
|
||||||
|
"admin.reporting.workspace_optimization.configuration.file_storage.description": "Check your file storage settings to ensure your Mattermost workspace has access to the configured file storage.",
|
||||||
|
"admin.reporting.workspace_optimization.configuration.file_storage.title": "File storage access is faulty.",
|
||||||
"admin.reporting.workspace_optimization.configuration.session_length.cta": "Configure session length",
|
"admin.reporting.workspace_optimization.configuration.session_length.cta": "Configure session length",
|
||||||
"admin.reporting.workspace_optimization.configuration.session_length.description": "Your session length is set to the default of 30 days. A longer session length provides convenience, and a shorter session provides tighter security. We recommend adjusting this based on your organization's security policies.",
|
"admin.reporting.workspace_optimization.configuration.session_length.description": "Your session length is set to the default of 30 days. A longer session length provides convenience, and a shorter session provides tighter security. We recommend adjusting this based on your organization's security policies.",
|
||||||
"admin.reporting.workspace_optimization.configuration.session_length.title": "Session lengths is set to default",
|
"admin.reporting.workspace_optimization.configuration.session_length.title": "Session lengths is set to default",
|
||||||
|
|||||||
@@ -1100,6 +1100,7 @@ export const DocLinks = {
|
|||||||
ENABLE_CLIENT_SIDE_CERTIFICATION: 'https://mattermost.com/pl/enable-client-side-certification',
|
ENABLE_CLIENT_SIDE_CERTIFICATION: 'https://mattermost.com/pl/enable-client-side-certification',
|
||||||
ENABLE_HARDENED_MODE: 'https://mattermost.com/pl/enable-hardened-mode',
|
ENABLE_HARDENED_MODE: 'https://mattermost.com/pl/enable-hardened-mode',
|
||||||
FORMAT_MESSAGES: 'https://mattermost.com/pl/format-messages',
|
FORMAT_MESSAGES: 'https://mattermost.com/pl/format-messages',
|
||||||
|
FILE_STORAGE: 'https://mattermost.com/pl/configure-file-storage',
|
||||||
GUEST_ACCOUNTS: 'https://docs.mattermost.com/onboard/guest-accounts.html',
|
GUEST_ACCOUNTS: 'https://docs.mattermost.com/onboard/guest-accounts.html',
|
||||||
HIGH_AVAILABILITY_CLUSTER: 'https://mattermost.com/pl/high-availability-cluster',
|
HIGH_AVAILABILITY_CLUSTER: 'https://mattermost.com/pl/high-availability-cluster',
|
||||||
IN_PRODUCT_NOTICES: 'https://mattermost.com/pl/in-product-notices',
|
IN_PRODUCT_NOTICES: 'https://mattermost.com/pl/in-product-notices',
|
||||||
@@ -2044,6 +2045,7 @@ export const ConsolePages = {
|
|||||||
GUEST_ACCOUNTS: '/admin_console/authentication/guest_access',
|
GUEST_ACCOUNTS: '/admin_console/authentication/guest_access',
|
||||||
LICENSE: '/admin_console/about/license',
|
LICENSE: '/admin_console/about/license',
|
||||||
SAML: '/admin_console/authentication/saml',
|
SAML: '/admin_console/authentication/saml',
|
||||||
|
FILE_STORAGE: '/admin_console/environment/file_storage',
|
||||||
SESSION_LENGTHS: '/admin_console/environment/session_lengths',
|
SESSION_LENGTHS: '/admin_console/environment/session_lengths',
|
||||||
WEB_SERVER: '/admin_console/environment/web_server',
|
WEB_SERVER: '/admin_console/environment/web_server',
|
||||||
PUSH_NOTIFICATION_CENTER: '/admin_console/environment/push_notification_server',
|
PUSH_NOTIFICATION_CENTER: '/admin_console/environment/push_notification_server',
|
||||||
|
|||||||
@@ -2343,13 +2343,15 @@ export default class Client4 {
|
|||||||
|
|
||||||
// General Routes
|
// General Routes
|
||||||
|
|
||||||
ping = () => {
|
ping = (getServerStatus: boolean, deviceId?: string) => {
|
||||||
return this.doFetch<{
|
return this.doFetch<{
|
||||||
status: string;
|
status: string;
|
||||||
ActiveSearchBackend: string;
|
ActiveSearchBackend: string;
|
||||||
|
database_status: string;
|
||||||
|
filestore_status: string;
|
||||||
}>(
|
}>(
|
||||||
`${this.getBaseRoute()}/system/ping?time=${Date.now()}`,
|
`${this.getBaseRoute()}/system/ping${buildQueryString({get_server_status: getServerStatus, device_id: deviceId})}`,
|
||||||
{method: 'get'},
|
{method: 'get', ignoreStatus: true},
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -4086,7 +4088,7 @@ export default class Client4 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (response.ok) {
|
if (response.ok || options.ignoreStatus) {
|
||||||
return {
|
return {
|
||||||
response,
|
response,
|
||||||
headers,
|
headers,
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ export type Options = {
|
|||||||
url?: string;
|
url?: string;
|
||||||
credentials?: 'omit' | 'same-origin' | 'include';
|
credentials?: 'omit' | 'same-origin' | 'include';
|
||||||
body?: any;
|
body?: any;
|
||||||
|
ignoreStatus?: boolean; /** If true, status codes > 300 are ignored and don't cause an error */
|
||||||
};
|
};
|
||||||
|
|
||||||
export type StatusOK = {
|
export type StatusOK = {
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user