Skip to content

Commit

Permalink
chore: add ytAuthCluster to settings requests [#349]
Browse files Browse the repository at this point in the history
  • Loading branch information
vitshev committed Feb 7, 2024
1 parent 66d1b2e commit 015428b
Show file tree
Hide file tree
Showing 15 changed files with 138 additions and 88 deletions.
6 changes: 3 additions & 3 deletions packages/ui/src/@types/core.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,9 @@ export interface YTCoreConfig {
* The OAuthRobot should have read/write access to mapNodePath
*/
userSettingsConfig?: {
cluster: string;
cluster?: string;
// path to a map node with user-settings files
mapNodePath: string;
mapNodePath?: string;
};

/**
Expand All @@ -70,7 +70,7 @@ export interface YTCoreConfig {
* The OAuthRobot should have read/write access to the table.
*/
userColumnPresets?: {
cluster: string;
cluster?: string;
dynamicTablePath: string;
};

Expand Down
11 changes: 9 additions & 2 deletions packages/ui/src/server/components/layout-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,14 @@ interface Params {

export async function getLayoutConfig(req: Request, params: Params): Promise<AppLayoutConfig> {
const {login, ytConfig, settings} = params;
const {ytApiUseCORS, uiSettings, metrikaCounter, allowPasswordAuth, odinBaseUrl} = req.ctx
.config as YTCoreConfig;
const {
ytApiUseCORS,
uiSettings,
metrikaCounter,
allowPasswordAuth,
odinBaseUrl,
userSettingsConfig,
} = req.ctx.config as YTCoreConfig;
const YT = ytConfig;
const uiVersion = getInterfaceVersion();

Expand Down Expand Up @@ -49,6 +55,7 @@ export async function getLayoutConfig(req: Request, params: Params): Promise<App
`window.YT.environment = window.YT.environment || (${isProduction} ? 'production' : 'development');`,
],
data: {
userSettingsCluster: userSettingsConfig?.cluster,
settings,
ytApiUseCORS,
uiSettings,
Expand Down
53 changes: 30 additions & 23 deletions packages/ui/src/server/components/settings.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import {AppContext} from '@gravity-ui/nodekit';
import {YTCoreConfig} from '../../@types/core';
import {getApp} from '../ServerFactory';
import {getRobotYTApiSetup} from './requestsSetup';

Expand All @@ -9,13 +8,20 @@ function makeConfigError() {
return new Error('Remote user settings are not configured. Please provide userSettingsConfig.');
}

function getSettingsConfig(): Partial<Required<YTCoreConfig>['userSettingsConfig']> {
export function getSettingsConfig(cluster: string): {
cluster: string;
mapNodePath?: string;
} {
const {userSettingsConfig} = getApp().config;
return userSettingsConfig || {};

return {
cluster,
...userSettingsConfig,
};
}

function getSettingsSetup() {
return getRobotYTApiSetup(getSettingsConfig().cluster!).setup;
function getSettingsSetup(cluster: string) {
return getRobotYTApiSetup(getSettingsConfig(cluster).cluster).setup;
}

export function isRemoteSettingsConfigured() {
Expand All @@ -26,18 +32,19 @@ export function isRemoteSettingsConfigured() {
interface Params {
ctx: AppContext;
username: string;
cluster: string;
}

export function create({ctx, username}: Params) {
export function create({ctx, username, cluster}: Params) {
ctx.log('settings.create', {username});
if (!isRemoteSettingsConfigured()) {
return Promise.reject(makeConfigError());
}

return yt.v3.create({
setup: getSettingsSetup(),
setup: getSettingsSetup(cluster),
parameters: {
path: getSettingsConfig().mapNodePath + '/' + username,
path: getSettingsConfig(cluster).mapNodePath + '/' + username,
type: 'document',
ignore_existing: true, // No error if exists
attributes: {
Expand All @@ -47,16 +54,16 @@ export function create({ctx, username}: Params) {
});
}

export function get({ctx, username}: Params) {
ctx.log('settings.get', {username});
export function get({ctx, username, cluster}: Params) {
ctx.log('settings.get', {username, cluster});
if (!isRemoteSettingsConfigured()) {
return Promise.reject(makeConfigError());
}

return yt.v3.get({
setup: getSettingsSetup(),
setup: getSettingsSetup(cluster),
parameters: {
path: getSettingsConfig().mapNodePath + '/' + username,
path: getSettingsConfig(cluster).mapNodePath + '/' + username,
output_format: {
$value: 'json',
$attributes: {
Expand All @@ -70,16 +77,16 @@ export function get({ctx, username}: Params) {
interface GetParams extends Params {
path: string;
}
export function getItem({ctx, username, path}: GetParams) {
export function getItem({ctx, username, path, cluster}: GetParams) {
ctx.log('settings.getItem', {username, path});
if (!isRemoteSettingsConfigured()) {
return Promise.reject(makeConfigError());
}

return yt.v3.get({
setup: getSettingsSetup(),
setup: getSettingsSetup(cluster),
parameters: {
path: getSettingsConfig().mapNodePath + '/' + username + '/' + path,
path: getSettingsConfig(cluster).mapNodePath + '/' + username + '/' + path,
output_format: {
$value: 'json',
$attributes: {
Expand All @@ -93,16 +100,16 @@ export function getItem({ctx, username, path}: GetParams) {
interface SetParams extends GetParams {
value: any;
}
export function setItem({ctx, username, path, value}: SetParams) {
ctx.log('settings.setItem', {username, path, value});
export function setItem({ctx, username, path, value, cluster}: SetParams) {
ctx.log('settings.setItem', {username, path, value, cluster});
if (!isRemoteSettingsConfigured()) {
return Promise.reject(makeConfigError());
}

return yt.v3.set({
setup: getSettingsSetup(),
setup: getSettingsSetup(cluster),
parameters: {
path: getSettingsConfig().mapNodePath + '/' + username + '/' + path,
path: getSettingsConfig(cluster).mapNodePath + '/' + username + '/' + path,
input_format: {
$value: 'json',
$attributes: {
Expand All @@ -113,16 +120,16 @@ export function setItem({ctx, username, path, value}: SetParams) {
data: value,
});
}
export function deleteItem({ctx, username, path}: GetParams) {
ctx.log('settings.deleteItem', {username, path});
export function deleteItem({ctx, username, path, cluster}: GetParams) {
ctx.log('settings.deleteItem', {username, path, cluster});
if (!isRemoteSettingsConfigured()) {
return Promise.reject(makeConfigError());
}

return yt.v3.remove({
setup: getSettingsSetup(),
setup: getSettingsSetup(cluster),
parameters: {
path: getSettingsConfig().mapNodePath + '/' + username + '/' + path,
path: getSettingsConfig(cluster).mapNodePath + '/' + username + '/' + path,
},
});
}
12 changes: 7 additions & 5 deletions packages/ui/src/server/components/table.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,20 @@ const yt = ytLib();
const SHA1_REGEXP = /^[0-9a-f]{40}$/;

interface PresetConfig {
cluster: string;
cluster?: string;
dynamicTablePath: string;
}

export async function getColumnPreset(
{cluster, dynamicTablePath}: PresetConfig,
{dynamicTablePath, cluster}: PresetConfig,
hash: string,
ytAuthCluster: string,
): Promise<Array<string> | undefined> {
if (!SHA1_REGEXP.test(hash)) {
throw new Error('The hash parameter should be defined as a valid sha1-hash string');
}

const {setup: setupConfig} = getRobotYTApiSetup(cluster);
const {setup: setupConfig} = getRobotYTApiSetup(cluster || ytAuthCluster);

const query = `* FROM [${dynamicTablePath}] WHERE hash="${hash}" LIMIT 1`;
const result = await yt.v3.selectRows({
Expand Down Expand Up @@ -56,14 +57,15 @@ export async function getColumnPreset(
}

export async function saveColumnPreset(
{cluster, dynamicTablePath}: PresetConfig,
{dynamicTablePath, cluster}: PresetConfig,
columns: unknown | Array<string>,
ytAuthCluster: string,
): Promise<string> {
if (!Array.isArray(columns) || _.some(columns, (i) => 'string' !== typeof i)) {
throw new Error('Request body should contain JSON-array of strings');
}

const {setup: setupConfig} = getRobotYTApiSetup(cluster);
const {setup: setupConfig} = getRobotYTApiSetup(cluster || ytAuthCluster);

const hash = objectHash.sha1(columns);

Expand Down
11 changes: 8 additions & 3 deletions packages/ui/src/server/controllers/home.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import ServerFactory, {getApp} from '../ServerFactory';
import {isLocalModeByEnvironment} from '../utils';
import {getDafaultUserSettings} from '../utils/default-settings';
import {ODIN_PAGE_ID} from '../../shared/constants';
import {getSettingsConfig} from '../../server/components/settings';

function isRootPage(page: string) {
const rootPages = [
Expand Down Expand Up @@ -68,10 +69,14 @@ export async function homeIndex(req: Request, res: Response) {
},
};

if (login && useRemoteSettings) {
const settingsConfig = getSettingsConfig(cluster!);

if (login && useRemoteSettings && settingsConfig.cluster) {
try {
await create({ctx, username: login});
const userSettings = login ? await get({ctx, username: login}) : {};
await create({ctx, username: login, cluster: settingsConfig.cluster});
const userSettings = login
? await get({ctx, username: login, cluster: settingsConfig.cluster})
: {};
settings.data = {...settings.data, ...userSettings};
} catch (e) {
const message = `Error in getting user settings for ${login}`;
Expand Down
20 changes: 10 additions & 10 deletions packages/ui/src/server/controllers/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,51 +9,51 @@ function sendResponse(_req: Request, res: Response, data: object) {
export function settingsCreate(req: Request, res: Response) {
const {
ctx,
params: {username},
params: {username, ytAuthCluster},
} = req;

return create({ctx, username})
return create({ctx, username, cluster: ytAuthCluster})
.then(sendResponse.bind(null, req, res))
.catch(sendError.bind(null, res));
}
export function settingsGet(req: Request, res: Response) {
const {
ctx,
params: {username},
params: {username, ytAuthCluster},
} = req;

return get({ctx, username})
return get({ctx, username, cluster: ytAuthCluster})
.then(sendResponse.bind(null, req, res))
.catch(sendError.bind(null, res));
}
export async function settingsGetItem(req: Request, res: Response) {
const {
ctx,
params: {username, path},
params: {username, path, ytAuthCluster},
} = req;

return getItem({ctx, username, path})
return getItem({ctx, username, path, cluster: ytAuthCluster})
.then(sendResponse.bind(null, req, res))
.catch(sendError.bind(null, res));
}
export function settingsSetItem(req: Request, res: Response) {
const {
ctx,
params: {username, path},
params: {username, path, ytAuthCluster},
body: {value} = {},
} = req;

return setItem({ctx, username, path, value})
return setItem({ctx, username, path, value, cluster: ytAuthCluster})
.then(sendResponse.bind(null, req, res))
.catch(sendError.bind(null, res));
}
export function settingsDeleteItem(req: Request, res: Response) {
const {
ctx,
params: {username, path},
params: {username, path, ytAuthCluster},
} = req;

return deleteItem({ctx, username, path})
return deleteItem({ctx, username, path, cluster: ytAuthCluster})
.then(sendResponse.bind(null, req, res))
.catch(sendError.bind(null, res));
}
10 changes: 7 additions & 3 deletions packages/ui/src/server/controllers/table-column-preset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ import {prepareErrorToSend} from '../utils';

export async function tableColumnPresetGet(req: Request, res: Response) {
const {
params: {hash},
params: {hash, ytAuthCluster},
} = req;
try {
const presetsConfig = checkEnabled(req);
const columns = await getColumnPreset(presetsConfig, hash);
const columns = await getColumnPreset(presetsConfig, hash, ytAuthCluster);
if (!columns) {
const err = new Error(`Cannot find column-preset by the hash '${hash}'`);
req.ctx.logError('Failed to get preset of columns', err);
Expand All @@ -24,9 +24,13 @@ export async function tableColumnPresetGet(req: Request, res: Response) {

export async function tableColumnPresetSave(req: Request, res: Response) {
const {body} = req;
const {
params: {ytAuthCluster},
} = req;

try {
const presetsConfig = checkEnabled(req);
const result = await saveColumnPreset(presetsConfig, body);
const result = await saveColumnPreset(presetsConfig, body, ytAuthCluster);
res.status(200).send(result);
} catch (err) {
req.ctx.logError('Failed to save preset of columns', err);
Expand Down
14 changes: 7 additions & 7 deletions packages/ui/src/server/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,16 +58,16 @@ const routes: AppRoutes = {

'POST /api/chyt/:ytAuthCluster/:action': {handler: chytProxyApi},

'GET /api/settings/:username': {handler: settingsGet},
'POST /api/settings/:username': {handler: settingsCreate},
'GET /api/settings/:username/:path': {handler: settingsGetItem},
'PUT /api/settings/:username/:path': {handler: settingsSetItem},
'DELETE /api/settings/:username/:path': {handler: settingsDeleteItem},
'GET /api/settings/:ytAuthCluster/:username': {handler: settingsGet},
'POST /api/settings/:ytAuthCluster/:username': {handler: settingsCreate},
'GET /api/settings/:ytAuthCluster/:username/:path': {handler: settingsGetItem},
'PUT /api/settings/:ytAuthCluster/:username/:path': {handler: settingsSetItem},
'DELETE /api/settings/:ytAuthCluster/:username/:path': {handler: settingsDeleteItem},

'GET /api/table-column-preset/:hash': {
'GET /api/table-column-preset/:ytAuthCluster/:hash': {
handler: tableColumnPresetGet,
},
'POST /api/table-column-preset': {handler: tableColumnPresetSave},
'POST /api/table-column-preset/:ytAuthCluster': {handler: tableColumnPresetSave},

'GET /:ytAuthCluster/': HOME_INDEX_TARGET,
'GET /:ytAuthCluster/maintenance': {handler: homeRedirect},
Expand Down
1 change: 1 addition & 0 deletions packages/ui/src/shared/yt-types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,7 @@ export interface SettingsConfig {
}

export interface ConfigData {
userSettingsCluster?: string;
settings: SettingsConfig;
ytApiUseCORS?: boolean;
uiSettings?: UISettings;
Expand Down
Loading

0 comments on commit 015428b

Please sign in to comment.