[MM-53019] Add file storage permission check to workspace health dashboard (#24403)

This commit is contained in:
Ben Schumacher 2023-10-19 17:31:09 +02:00 committed by GitHub
parent 3d81a63b4e
commit 4ed32be6d2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 53 additions and 8 deletions

View File

@ -153,7 +153,7 @@ func getSystemPing(c *Context, w http.ResponseWriter, r *http.Request) {
// Enhanced ping health check:
// If an extra form value is provided then perform extra health checks for
// database and file storage backends.
if r.FormValue("get_server_status") != "" {
if r.FormValue("get_server_status") == "true" {
dbStatusKey := "database_status"
s[dbStatusKey] = model.StatusOk

View File

@ -444,9 +444,9 @@ export function restartServer() {
};
}
export function ping() {
export function ping(getServerStatus, deviceId) {
return async () => {
const data = await Client4.ping();
const data = await Client4.ping(getServerStatus, deviceId);
return data;
};
}

View File

@ -7,6 +7,8 @@ import type {useIntl} from 'react-intl';
import type {AdminConfig} from '@mattermost/types/config';
import {Client4} from 'mattermost-redux/client';
import {ConsolePages, DocLinks} from 'utils/constants';
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 (
config: Partial<AdminConfig>,
formatMessage: ReturnType<typeof useIntl>['formatMessage'],
@ -82,6 +118,7 @@ export const runConfigChecks = async (
const checks = [
ssl,
sessionLength,
fileStorage,
];
const results = await Promise.all(checks.map((check) => check(config, formatMessage, options)));
return results;

View File

@ -52,7 +52,7 @@ const RenewalLink = (props: RenewalLinkProps) => {
const handleLinkClick = async (e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {
e.preventDefault();
try {
const {status} = await Client4.ping();
const {status} = await Client4.ping(false);
if (status === 'OK' && renewalLink !== '') {
if (props.telemetryInfo?.success) {
trackEvent('renew_license', props.telemetryInfo.success);

View File

@ -1972,6 +1972,9 @@
"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.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.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",

View File

@ -1100,6 +1100,7 @@ export const DocLinks = {
ENABLE_CLIENT_SIDE_CERTIFICATION: 'https://mattermost.com/pl/enable-client-side-certification',
ENABLE_HARDENED_MODE: 'https://mattermost.com/pl/enable-hardened-mode',
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',
HIGH_AVAILABILITY_CLUSTER: 'https://mattermost.com/pl/high-availability-cluster',
IN_PRODUCT_NOTICES: 'https://mattermost.com/pl/in-product-notices',
@ -2044,6 +2045,7 @@ export const ConsolePages = {
GUEST_ACCOUNTS: '/admin_console/authentication/guest_access',
LICENSE: '/admin_console/about/license',
SAML: '/admin_console/authentication/saml',
FILE_STORAGE: '/admin_console/environment/file_storage',
SESSION_LENGTHS: '/admin_console/environment/session_lengths',
WEB_SERVER: '/admin_console/environment/web_server',
PUSH_NOTIFICATION_CENTER: '/admin_console/environment/push_notification_server',

View File

@ -2343,13 +2343,15 @@ export default class Client4 {
// General Routes
ping = () => {
ping = (getServerStatus: boolean, deviceId?: string) => {
return this.doFetch<{
status: string;
ActiveSearchBackend: string;
database_status: string;
filestore_status: string;
}>(
`${this.getBaseRoute()}/system/ping?time=${Date.now()}`,
{method: 'get'},
`${this.getBaseRoute()}/system/ping${buildQueryString({get_server_status: getServerStatus, device_id: deviceId})}`,
{method: 'get', ignoreStatus: true},
);
};
@ -4086,7 +4088,7 @@ export default class Client4 {
}
}
if (response.ok) {
if (response.ok || options.ignoreStatus) {
return {
response,
headers,

View File

@ -20,6 +20,7 @@ export type Options = {
url?: string;
credentials?: 'omit' | 'same-origin' | 'include';
body?: any;
ignoreStatus?: boolean; /** If true, status codes > 300 are ignored and don't cause an error */
};
export type StatusOK = {