Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 32 additions & 23 deletions graylog2-web-interface/checkProductionBuild.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@
* <http://www.mongodb.com/licensing/server-side-public-license>.
*/
/* eslint-disable no-console */
const fs = require('fs');

Check warning on line 18 in graylog2-web-interface/checkProductionBuild.js

View workflow job for this annotation

GitHub Actions / Reviewbot

'require' is not defined.

See https://eslint.org/docs/rules/no-undef for details.

Check warning on line 18 in graylog2-web-interface/checkProductionBuild.js

View workflow job for this annotation

GitHub Actions / Reviewbot

A `require()` style import is forbidden.

const path = require('path');

Check warning on line 19 in graylog2-web-interface/checkProductionBuild.js

View workflow job for this annotation

GitHub Actions / Reviewbot

'require' is not defined.

See https://eslint.org/docs/rules/no-undef for details.

Check warning on line 19 in graylog2-web-interface/checkProductionBuild.js

View workflow job for this annotation

GitHub Actions / Reviewbot

A `require()` style import is forbidden.


const puppeteer = require('puppeteer');

Check warning on line 21 in graylog2-web-interface/checkProductionBuild.js

View workflow job for this annotation

GitHub Actions / Reviewbot

'require' is not defined.

See https://eslint.org/docs/rules/no-undef for details.

Check warning on line 21 in graylog2-web-interface/checkProductionBuild.js

View workflow job for this annotation

GitHub Actions / Reviewbot

A `require()` style import is forbidden.

const express = require('express');

Check warning on line 22 in graylog2-web-interface/checkProductionBuild.js

View workflow job for this annotation

GitHub Actions / Reviewbot

'require' is not defined.

See https://eslint.org/docs/rules/no-undef for details.

Check warning on line 22 in graylog2-web-interface/checkProductionBuild.js

View workflow job for this annotation

GitHub Actions / Reviewbot

A `require()` style import is forbidden.

const cors = require('cors');

Check warning on line 23 in graylog2-web-interface/checkProductionBuild.js

View workflow job for this annotation

GitHub Actions / Reviewbot

'require' is not defined.

See https://eslint.org/docs/rules/no-undef for details.

Check warning on line 23 in graylog2-web-interface/checkProductionBuild.js

View workflow job for this annotation

GitHub Actions / Reviewbot

A `require()` style import is forbidden.


const VENDORMODULE = 'vendor-module.json';
const BUILDMODULE = 'module.json';
Expand Down Expand Up @@ -50,8 +50,7 @@
app.use('/favicon.ico', express.static('public/images/favicon.png'));
app.use('/assets', express.static(buildDir));

Object.entries(pluginMounts)
.forEach(([name, pluginPath]) => app.use(`/assets/${name}`, express.static(pluginPath)));
Object.entries(pluginMounts).forEach(([name, pluginPath]) => app.use(`/assets/${name}`, express.static(pluginPath)));

const server = app.listen();
const { port } = server.address();
Expand All @@ -63,12 +62,13 @@
const api = express();
api.use(cors());

const rootHandler = (req, res) => res.json({
cluster_id: 'deadbeef',
node_id: 'deadbeef',
version: '3.0.0',
tagline: 'Manage your logs in the dark and have lasers going and make it look like you\'re from space!',
});
const rootHandler = (req, res) =>
res.json({
cluster_id: 'deadbeef',
node_id: 'deadbeef',
version: '3.0.0',
tagline: "Manage your logs in the dark and have lasers going and make it look like you're from space!",
});
api.get(prefix, rootHandler);

const sessionHandler = (req, res) => res.json({ session_id: null, username: null, is_valid: false });
Expand Down Expand Up @@ -115,25 +115,24 @@
`;

function collectMounts(pluginModuleNames) {
return pluginModuleNames.map((pluginModuleName) => {
const pluginModule = JSON.parse(fs.readFileSync(pluginModuleName));
const name = Object.keys(pluginModule.files.chunks)[0];

return { [name]: path.dirname(pluginModuleName) };
}).reduce((prev, cur) => ({ ...prev, ...cur }), {});
return pluginModuleNames
.map((pluginModuleName) => {
const pluginModule = JSON.parse(fs.readFileSync(pluginModuleName));
const name = Object.keys(pluginModule.files.chunks)[0];

return { [name]: path.dirname(pluginModuleName) };
})
.reduce((prev, cur) => ({ ...prev, ...cur }), {});
}

function collectAssets(pluginModules) {
const vendorModule = JSON.parse(fs.readFileSync(`${buildDir}/${VENDORMODULE}`));
const buildModule = JSON.parse(fs.readFileSync(`${buildDir}/${BUILDMODULE}`));
const pluginAssets = pluginModules.flatMap((pluginModule) => pluginModule.files.js);

return [
'config.js',
...vendorModule.files.js,
...buildModule.files.js,
...pluginAssets,
].map((asset) => `/assets/${asset}`);
return ['config.js', ...vendorModule.files.js, ...buildModule.files.js, ...pluginAssets].map(
(asset) => `/assets/${asset}`,
);
}

const pluginModules = plugins.map((plugin) => JSON.parse(fs.readFileSync(plugin)));
Expand All @@ -147,13 +146,21 @@
const consoleLogs = [];

const trackEvent = (evt, arr) => {
const msg = { type: evt?.type(), message: evt?.text(), stack: JSON.stringify(evt?.stackTrace(), null, 2) };
const msg = {
type: evt?.name ?? evt?.type?.(),
message: evt?.message ?? evt?.text?.(),
stack: evt.stack ?? JSON.stringify(evt?.stackTrace?.() ?? {}, null, 2),
};
arr.push(msg);
};

const formatLog = (msg) => `${msg.type}: ${msg.message}\n${msg.stack}`;

const pagePromise = loadPage(url, (msg) => trackEvent(msg, pageErrors), (msg) => trackEvent(msg, consoleLogs));
const pagePromise = loadPage(
url,
(msg) => trackEvent(msg, pageErrors),
(msg) => trackEvent(msg, consoleLogs),
);

pagePromise
.catch((err) => {
Expand All @@ -173,7 +180,9 @@
console.log(consoleLogs.map(formatLog).join('\n'));
}

console.log(`\n${isSuccess ? 'Success' : 'Failure'}: Encountered ${pageErrors.length} errors and ${consoleLogs.length} messages on the console during loading.`);
console.log(
`\n${isSuccess ? 'Success' : 'Failure'}: Encountered ${pageErrors.length} errors and ${consoleLogs.length} messages on the console during loading.`,
);
process.exitCode = isSuccess ? 0 : 1;
})
.finally(async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,29 +14,13 @@
* along with this program. If not, see
* <http://www.mongodb.com/licensing/server-side-public-license>.
*/
import Reflux from 'reflux';
import type { ColorScheme } from '@graylog/sawmill';

import type { PREFERENCES_THEME_MODE } from 'theme/constants';
import fetch from 'logic/rest/FetchProvider';
import { qualifyUrl } from 'util/URLUtils';
import UserNotification from 'util/UserNotification';
import { singletonStore, singletonActions } from 'logic/singleton';

type PreferencesActionsType = {
saveUserPreferences: (
userName: string,
preferences: PreferencesUpdateMap,
callback?: (preferences: PreferencesUpdateMap) => void,
displaySuccessNotification?: boolean,
) => Promise<unknown>;
};
export const PreferencesActions = singletonActions('core.Preferences', () =>
Reflux.createActions<PreferencesActionsType>({
loadUserPreferences: { asyncResult: true },
saveUserPreferences: { asyncResult: true },
}),
);
import { CurrentUserStore } from 'stores/users/CurrentUserStore';

type BooleanString = 'true' | 'false';

Expand Down Expand Up @@ -69,42 +53,32 @@ const convertPreferences = (preferences: PreferencesUpdateMap): PreferencesMap =
}
});

// @ts-ignore
return convertedPreferences;
return convertedPreferences as PreferencesMap;
};

export const PreferencesStore = singletonStore('core.Preferences', () =>
Reflux.createStore({
listenables: [PreferencesActions],
URL: qualifyUrl('/users/'),
export const saveUserPreferences = (
userName: string,
preferences: PreferencesUpdateMap,
callback: (preferences: PreferencesUpdateMap) => void = () => {},
displaySuccessNotification = true,
): Promise<void> => {
const convertedPreferences = convertPreferences(preferences);
const url = `${qualifyUrl('/users/')}${encodeURIComponent(userName)}/preferences`;

saveUserPreferences(
userName: string,
preferences: PreferencesUpdateMap,
callback: (preferences: PreferencesUpdateMap) => void = () => {},
displaySuccessNotification = true,
) {
const convertedPreferences = convertPreferences(preferences);
const url = `${this.URL + encodeURIComponent(userName)}/preferences`;
const promise = fetch('PUT', url, { preferences: convertedPreferences }).then(
() => {
if (displaySuccessNotification) {
UserNotification.success('User preferences successfully saved');
}
return fetch('PUT', url, { preferences: convertedPreferences }).then(
() => {
if (displaySuccessNotification) {
UserNotification.success('User preferences successfully saved');
}

callback(preferences);
},
(errorThrown) => {
UserNotification.error(
`Saving of preferences for "${userName}" failed with status: ${errorThrown}`,
'Could not save user preferences',
);
},
callback(preferences);
CurrentUserStore.reload();
},
(errorThrown) => {
UserNotification.error(
`Saving of preferences for "${userName}" failed with status: ${errorThrown}`,
'Could not save user preferences',
);

PreferencesActions.saveUserPreferences.promise(promise);

return promise;
},
}),
);
);
};
35 changes: 35 additions & 0 deletions graylog2-web-interface/src/api/server-availability.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* Copyright (C) 2020 Graylog, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the Server Side Public License, version 1,
* as published by MongoDB, Inc.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* Server Side Public License for more details.
*
* You should have received a copy of the Server Side Public License
* along with this program. If not, see
* <http://www.mongodb.com/licensing/server-side-public-license>.
*/

type ErrorCallback = (error: unknown) => void;
type SuccessCallback = () => void;

let _onError: ErrorCallback | null = null;
let _onSuccess: SuccessCallback | null = null;

export const registerCallbacks = (onError: ErrorCallback | null, onSuccess: SuccessCallback | null) => {
_onError = onError;
_onSuccess = onSuccess;
};

export const reportError = (error: unknown) => {
_onError?.(error);
};

export const reportSuccess = () => {
_onSuccess?.();
};
43 changes: 43 additions & 0 deletions graylog2-web-interface/src/api/startpage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* Copyright (C) 2020 Graylog, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the Server Side Public License, version 1,
* as published by MongoDB, Inc.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* Server Side Public License for more details.
*
* You should have received a copy of the Server Side Public License
* along with this program. If not, see
* <http://www.mongodb.com/licensing/server-side-public-license>.
*/
import ApiRoutes from 'routing/ApiRoutes';
import UserNotification from 'util/UserNotification';
import { qualifyUrl } from 'util/URLUtils';
import fetch from 'logic/rest/FetchProvider';
import { CurrentUserStore } from 'stores/users/CurrentUserStore';

export const setStartpage = (userId: string, type: string, id: string): Promise<void> => {
const url = qualifyUrl(ApiRoutes.UsersApiController.update(userId).url);
const payload: { type?: string; id?: string } = {};

if (type && id) {
payload.type = type;
payload.id = id;
}

return fetch('PUT', url, { startpage: payload }).then(
() => {
CurrentUserStore.reload();
UserNotification.success('Your start page was changed successfully');
},
(error: unknown) =>
UserNotification.error(
`Changing your start page failed with error: ${error}`,
'Could not change your start page',
),
);
};
34 changes: 34 additions & 0 deletions graylog2-web-interface/src/api/system-load-balancer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Copyright (C) 2020 Graylog, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the Server Side Public License, version 1,
* as published by MongoDB, Inc.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* Server Side Public License for more details.
*
* You should have received a copy of the Server Side Public License
* along with this program. If not, see
* <http://www.mongodb.com/licensing/server-side-public-license>.
*/
import { qualifyUrl } from 'util/URLUtils';
import UserNotification from 'util/UserNotification';
import fetch from 'logic/rest/FetchProvider';

const sourceUrl = (nodeId: string) => `/cluster/${nodeId}/lbstatus`;

export const overrideLoadBalancerStatus = (nodeId: string, status: string): Promise<void> =>
fetch('PUT', qualifyUrl(`${sourceUrl(nodeId)}/override/${status}`)).then(
() => {
UserNotification.success(`Load balancer status successfully changed do '${status}' in node '${nodeId}'`);
},
(error: unknown) => {
UserNotification.error(
`Changing load balancer status in '${nodeId}' failed: ${error}`,
`Could not change load balancer status to '${status}' in node '${nodeId}'`,
);
},
);
47 changes: 47 additions & 0 deletions graylog2-web-interface/src/api/system-processing.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* Copyright (C) 2020 Graylog, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the Server Side Public License, version 1,
* as published by MongoDB, Inc.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* Server Side Public License for more details.
*
* You should have received a copy of the Server Side Public License
* along with this program. If not, see
* <http://www.mongodb.com/licensing/server-side-public-license>.
*/
import { qualifyUrl } from 'util/URLUtils';
import UserNotification from 'util/UserNotification';
import fetch from 'logic/rest/FetchProvider';

const sourceUrl = (nodeId: string) => `/cluster/${nodeId}/processing`;

export const pauseProcessing = (nodeId: string): Promise<void> =>
fetch('POST', qualifyUrl(`${sourceUrl(nodeId)}/pause`)).then(
() => {
UserNotification.success(`Message processing paused successfully in '${nodeId}'`);
},
(error: unknown) => {
UserNotification.error(
`Pausing message processing in '${nodeId}' failed: ${error}`,
`Could not pause message processing in node '${nodeId}'`,
);
},
);

export const resumeProcessing = (nodeId: string): Promise<void> =>
fetch('POST', qualifyUrl(`${sourceUrl(nodeId)}/resume`)).then(
() => {
UserNotification.success(`Message processing resumed successfully in '${nodeId}'`);
},
(error: unknown) => {
UserNotification.error(
`Resuming message processing in '${nodeId}' failed: ${error}`,
`Could not resume message processing in node '${nodeId}'`,
);
},
);
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ import { MoreActions } from 'components/common/EntityDataTable';
import { MenuItem } from 'components/bootstrap';
import Routes from 'routing/Routes';
import HideOnCloud from 'util/conditional/HideOnCloud';
import { SystemLoadBalancerStore } from 'stores/load-balancer/SystemLoadBalancerStore';
import { SystemProcessingStore } from 'stores/system-processing/SystemProcessingStore';
import { overrideLoadBalancerStatus } from 'api/system-load-balancer';
import { pauseProcessing, resumeProcessing } from 'api/system-processing';

import { LOAD_BALANCER_STATUS } from './fetchClusterGraylogNodes';
import type { ClusterGraylogNode as GraylogNode, LoadBalancerStatus } from './fetchClusterGraylogNodes';
Expand All @@ -41,15 +41,15 @@ const GraylogNodeActions = ({ node }: Props) => {

const toggleMessageProcessing = () => {
if (node.is_processing) {
SystemProcessingStore.pause(node.node_id);
pauseProcessing(node.node_id);
} else {
SystemProcessingStore.resume(node.node_id);
resumeProcessing(node.node_id);
}
setShowMessageProcessingModal(false);
};

const updateLoadBalancerStatus = (status: LoadBalancerStatus) => {
SystemLoadBalancerStore.override(node.node_id, status);
overrideLoadBalancerStatus(node.node_id, status);
setLoadBalancerStatusToConfirm(undefined);
};

Expand Down
Loading
Loading