Upgrade monasca-kibana-plugin for Elkstack update
Story: 2006376 Task: 36179 Besides the plugin update, tests should get remade as well as Zuul jobs due to plugin being built in a different way. Change-Id: Id5d0bb53d10fa8823ceda2c8e922ea36b9b27501
This commit is contained in:
parent
d26887599b
commit
bfa95367e0
@ -1,7 +1,7 @@
|
||||
- project:
|
||||
templates:
|
||||
- nodejs4-jobs
|
||||
check:
|
||||
jobs:
|
||||
- monascalog-python3-tempest:
|
||||
voting: false
|
||||
- monasca-tempest-log-python3-influxdb
|
||||
gate:
|
||||
jobs:
|
||||
- monasca-tempest-log-python3-influxdb
|
||||
|
30
README.rst
30
README.rst
@ -1,15 +1,26 @@
|
||||
Monasca Kibana plugin
|
||||
=====================
|
||||
|
||||
Keystone authentication support and multi-tenancy for Kibana 4.6.x
|
||||
Keystone authentication support and multi-tenancy for Kibana 7.3.x
|
||||
|
||||
Build
|
||||
-----
|
||||
|
||||
After installing Node JS 10.15.2 and yarn, do the following to
|
||||
initiate Kibana development environment.
|
||||
|
||||
::
|
||||
|
||||
npm install
|
||||
npm run package
|
||||
git clone https://github.com/elastic/kibana --branch 7.3
|
||||
cd kibana
|
||||
|
||||
Clone the plugin to plugins/ inside the environment and run.
|
||||
|
||||
::
|
||||
|
||||
yarn kbn bootstrap
|
||||
cd plugins/monasca-kibana-plugin
|
||||
yarn build
|
||||
|
||||
Installation
|
||||
------------
|
||||
@ -35,9 +46,9 @@ Then install using the Kibana plugin manager tool:
|
||||
|
||||
::
|
||||
|
||||
$ /opt/kibana/bin/kibana plugin --install monasca-kibana-plugin --url file:///tmp/monasca-kibana-plugin-0.0.1.tar.gz
|
||||
$ /opt/kibana/bin/kibana-plugin install file:///tmp/kibana/plugins/monasca-kibana-plugin/build/monasca-kibana-plugin-7.3.0.zip
|
||||
Installing monasca-kibana-plugin
|
||||
Attempting to transfer from file:///tmp/monasca-kibana-plugin-0.0.1.tar.gz
|
||||
Attempting to transfer from file:///tmp/kibana/plugins/monasca-kibana-plugin/build/monasca-kibana-plugin-7.3.0.zip
|
||||
Transferring 7567007 bytes....................
|
||||
Transfer complete
|
||||
Extracting plugin archive
|
||||
@ -45,11 +56,16 @@ Then install using the Kibana plugin manager tool:
|
||||
Optimizing and caching browser bundles...
|
||||
Plugin installation complete
|
||||
|
||||
$ /opt/kibana/bin/kibana plugin --list
|
||||
monasca-kibana-plugin
|
||||
$ /opt/kibana/bin/kibana-plugin list
|
||||
monasca-kibana-plugin@7.3.0
|
||||
|
||||
Now start/restart your Kibana server by running:
|
||||
|
||||
::
|
||||
|
||||
$ service kibana restart
|
||||
|
||||
|
||||
Valuable resources:
|
||||
- Kibana plugin notes - https://github.com/nreese/kibana-plugin-notes
|
||||
- Elastic forum - https://discuss.elastic.co
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016 FUJITSU LIMITED
|
||||
* Copyright 2020 FUJITSU LIMITED
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
@ -32,12 +32,12 @@ var pkg = require('./package.json');
|
||||
var packageName = pkg.name + '-' + pkg.version;
|
||||
|
||||
// relative location of Kibana install
|
||||
var pathToKibana = '../kibana';
|
||||
var pathToKibana = '../../kibana';
|
||||
|
||||
var buildDir = path.resolve(__dirname, 'build');
|
||||
var targetDir = path.resolve(__dirname, 'target');
|
||||
var buildTarget = path.resolve(buildDir, pkg.name);
|
||||
var kibanaPluginDir = path.resolve(__dirname, pathToKibana, 'installedPlugins', pkg.name);
|
||||
var kibanaPluginDir = path.resolve(__dirname, pathToKibana, 'plugins', pkg.name);
|
||||
|
||||
var exclude = [
|
||||
'.git',
|
||||
|
19
index.js
19
index.js
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2017 FUJITSU LIMITED
|
||||
* Copyright 2020 FUJITSU LIMITED
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
@ -56,6 +56,11 @@ export default (kibana) => {
|
||||
})
|
||||
.default();
|
||||
|
||||
//Elasticsearch parameter added due to the fact that retrieving elasticsearch url via server.config() is impossible
|
||||
const elasticsearch = Joi.object({
|
||||
url: Joi.string().uri({scheme: ['http', 'https']})
|
||||
}).default();
|
||||
|
||||
return Joi
|
||||
.object({
|
||||
enabled: Joi.boolean().default(true),
|
||||
@ -65,7 +70,8 @@ export default (kibana) => {
|
||||
defaultEventsTimeField: Joi.string().default('@timestamp'),
|
||||
logsIndexPrefix: Joi.string().default('logs-<project_id>'),
|
||||
eventsIndexPrefix: Joi.string().default('events-<project_id>'),
|
||||
cookie: cookie
|
||||
cookie: cookie,
|
||||
elasticsearch: elasticsearch
|
||||
})
|
||||
.concat(deprecated_keystone)
|
||||
.concat(valid_keystone)
|
||||
@ -74,12 +80,11 @@ export default (kibana) => {
|
||||
.default();
|
||||
}
|
||||
|
||||
function init(server) {
|
||||
server.log(['status', 'debug', 'keystone'], 'Initializing keystone plugin');
|
||||
async function init(server) {
|
||||
server.log(['MKP','status', 'debug', 'keystone'], 'Initializing keystone plugin');
|
||||
binding(server).start();
|
||||
session(server).start();
|
||||
await session(server).start();
|
||||
healthCheck(this, server).start();
|
||||
server.log(['status', 'debug', 'keystone'], 'Initialized keystone plugin');
|
||||
server.log(['MKP','status', 'debug', 'keystone'], 'Initialized keystone plugin');
|
||||
}
|
||||
|
||||
};
|
||||
|
73
package.json
73
package.json
@ -1,45 +1,43 @@
|
||||
{
|
||||
"name": "monasca-kibana-plugin",
|
||||
"version": "1.5.0",
|
||||
"description": "Keystone authentication & multitenancy support for Kibana 4.6.x",
|
||||
"author": "OpenStack",
|
||||
"license": "Apache-2.0",
|
||||
"keywords": [
|
||||
"kibana",
|
||||
"authentication",
|
||||
"keystone",
|
||||
"multitenancy",
|
||||
"plugin"
|
||||
],
|
||||
"scripts": {
|
||||
"start": "gulp dev",
|
||||
"build": "gulp build",
|
||||
"package": "gulp package",
|
||||
"test": "gulp test",
|
||||
"lint": "gulp lint"
|
||||
"name": "monasca-kibana-plugin",
|
||||
"version": "7.3.0",
|
||||
"description": "Keystone authentication & multitenancy support for Kibana 7.3.x",
|
||||
"main": "gulpfile.js",
|
||||
"kibana": {
|
||||
"version": "7.3.0",
|
||||
"templateVersion": "1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "4.4.7",
|
||||
"npm": "2.15.8"
|
||||
},
|
||||
"main": "gulpfile.js",
|
||||
"dependencies": {
|
||||
"hoek": "^4.0.1",
|
||||
"keystone-v3-client": "~0.0.8",
|
||||
"yar": "^7.x.x"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/openstack/monasca-kibana-plugin.git"
|
||||
"scripts": {
|
||||
"preinstall": "node ../../preinstall_check",
|
||||
"kbn": "node ../../scripts/kbn",
|
||||
"es": "node ../../scripts/es",
|
||||
"lint": "eslint .",
|
||||
"start": "plugin-helpers start",
|
||||
"test:server": "plugin-helpers test:server",
|
||||
"test:browser": "plugin-helpers test:browser",
|
||||
"build": "plugin-helpers build"
|
||||
},
|
||||
"devDependencies": {
|
||||
"babel-eslint": "^4.1.8",
|
||||
"babel-preset-es2015": "^6.3.13",
|
||||
"babel-register": "^6.4.3",
|
||||
"@elastic/eslint-config-kibana": "link:../../packages/eslint-config-kibana",
|
||||
"@elastic/eslint-import-resolver-kibana": "link:../../packages/kbn-eslint-import-resolver-kibana",
|
||||
"@kbn/expect": "link:../../packages/kbn-expect",
|
||||
"@kbn/plugin-helpers": "link:../../packages/kbn-plugin-helpers"
|
||||
},
|
||||
"dependencies": {
|
||||
"babel-eslint": "^10.0.1",
|
||||
"eslint": "^5.16.0",
|
||||
"eslint-plugin-babel": "^5.3.0",
|
||||
"eslint-plugin-import": "^2.16.0",
|
||||
"eslint-plugin-jest": "^22.4.1",
|
||||
"eslint-plugin-jsx-a11y": "^6.2.1",
|
||||
"eslint-plugin-mocha": "^5.3.0",
|
||||
"eslint-plugin-no-unsanitized": "^3.0.2",
|
||||
"eslint-plugin-prefer-object-spread": "^1.2.1",
|
||||
"eslint-plugin-react": "^7.12.4",
|
||||
"@hapi/wreck": "^15.0.1",
|
||||
"bluebird": "^3.2.1",
|
||||
"boom": "^2.8.0",
|
||||
"chai": "^3.5.0",
|
||||
"eslint-plugin-mocha": "^1.1.0",
|
||||
"gulp": "^3.9.0",
|
||||
"gulp-eslint": "^1.1.1",
|
||||
"gulp-gzip": "^1.2.0",
|
||||
@ -54,6 +52,9 @@
|
||||
"rsync": "^0.4.0",
|
||||
"semver": "^5.3.0",
|
||||
"sinon": "^1.17.3",
|
||||
"wreck": "^8.0.0"
|
||||
"hoek": "^4.0.1",
|
||||
"keystone-v3-client": "~0.0.8",
|
||||
"@hapi/yar": "^9.2.x",
|
||||
"request": "^2.88.0"
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2017 FUJITSU LIMITED
|
||||
* Copyright 2020 FUJITSU LIMITED
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016 FUJITSU LIMITED
|
||||
* Copyright 2020 FUJITSU LIMITED
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
@ -21,7 +21,8 @@ export const SESSION_TOKEN_CHANGED = `monasca-kibana-plugin-token-changed-${NOW_
|
||||
|
||||
export const TOKEN_CHANGED_VALUE = Symbol('token-changed');
|
||||
|
||||
export const RELOAD_MARKUP = `<html>
|
||||
<head><script type="text/javascript">window.location.reload();</script></head>
|
||||
<body>reloading...</body>
|
||||
</html>`;
|
||||
export const RELOAD_MARKUP = `
|
||||
<html>
|
||||
<head><script src="#" type="text/javascript">window.location.reload();</script></head>
|
||||
<body>reloading...</body>
|
||||
</html>`;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2017 FUJITSU LIMITED
|
||||
* Copyright 2020 FUJITSU LIMITED
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
@ -36,7 +36,7 @@ module.exports = function healthcheck(plugin, server) {
|
||||
}
|
||||
};
|
||||
|
||||
server.on('stop', stop);
|
||||
server.events.on('stop', stop);
|
||||
|
||||
return service;
|
||||
|
||||
@ -105,7 +105,7 @@ module.exports = function healthcheck(plugin, server) {
|
||||
|
||||
function getRequest() {
|
||||
let required;
|
||||
if (util.startsWith(keystoneUrl, 'https')) {
|
||||
if (keystoneUrl.startsWith('https')) {
|
||||
required = require('https');
|
||||
} else {
|
||||
required = require('http');
|
||||
@ -121,7 +121,7 @@ module.exports = function healthcheck(plugin, server) {
|
||||
port : getPort(),
|
||||
method : 'GET'
|
||||
};
|
||||
if (util.startsWith(keystoneUrl, 'https')) {
|
||||
if (keystoneUrl.startsWith('https')) {
|
||||
params.rejectUnauthorized = false;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016 FUJITSU LIMITED
|
||||
* Copyright 2020 FUJITSU LIMITED
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
@ -12,17 +12,16 @@
|
||||
* the License.
|
||||
*/
|
||||
|
||||
import Boom from 'boom';
|
||||
import Joi from 'joi';
|
||||
|
||||
import { SESSION_USER_KEY, RELOAD_MARKUP } from '../../const';
|
||||
import {RELOAD_MARKUP, SESSION_USER_KEY} from '../../const';
|
||||
import lookupToken from './token';
|
||||
import RELOAD from './reload';
|
||||
|
||||
const NOOP = ()=> {
|
||||
const NOOP = () => {
|
||||
};
|
||||
const SCHEMA = {
|
||||
tokenOk : Joi.func().default(NOOP),
|
||||
tokenOk: Joi.func().default(NOOP),
|
||||
tokenBad: Joi.func().default(NOOP)
|
||||
};
|
||||
|
||||
@ -43,15 +42,23 @@ export default (server, opts) => {
|
||||
server.log(['status', 'debug', 'keystone'],
|
||||
'Received error object from token lookup'
|
||||
);
|
||||
return reply(token);
|
||||
return reply.unauthenticated(token);
|
||||
} else if (token === RELOAD) {
|
||||
// TODO: this part is basically ineffective now due to Kibana rejecting
|
||||
// any HTML injection
|
||||
server.log(['status', 'debug', 'keystone'],
|
||||
'Received reload markup object from token lookup'
|
||||
);
|
||||
return reply(RELOAD_MARKUP).type('text/html');
|
||||
return reply.response(RELOAD_MARKUP).type('text/html').takeover();
|
||||
} else if (userObj && 'project' in userObj) {
|
||||
server.log(['status','info','keystone'], `${token} already authorized`);
|
||||
return reply.continue({credentials:token});
|
||||
server.log(['status', 'info', 'keystone'], `${token} already authorized`);
|
||||
return reply.authenticated(
|
||||
{
|
||||
credentials: token,
|
||||
artifacts: {
|
||||
project: userObj.project.id
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
server.log(['status', 'debug', 'keystone'],
|
||||
@ -61,7 +68,7 @@ export default (server, opts) => {
|
||||
return tokensApi
|
||||
.validate({
|
||||
headers: {
|
||||
'X-Auth-Token' : token,
|
||||
'X-Auth-Token': token,
|
||||
'X-Subject-Token': token
|
||||
}
|
||||
})
|
||||
@ -69,18 +76,24 @@ export default (server, opts) => {
|
||||
(data) => {
|
||||
userObj = data.data.token;
|
||||
return callbackOk(token, userObj, session)
|
||||
.then(()=> {
|
||||
.then(() => {
|
||||
server.log(['status', 'debug', 'keystone'],
|
||||
`Auth process completed for user ${userObj.user.id}`);
|
||||
return reply.continue({credentials: token});
|
||||
return reply.authenticated({
|
||||
credentials: token,
|
||||
artifacts: {
|
||||
project: userObj.project.id
|
||||
}
|
||||
});
|
||||
});
|
||||
})
|
||||
.catch((error) => {
|
||||
server.log(['_auth-error'], error);
|
||||
return callbackBad(token, error, session)
|
||||
.then((err)=> {
|
||||
.then((err) => {
|
||||
server.log(['status', 'error', 'keystone'], `Auth process did not complete for token ${token}`);
|
||||
server.log(['status', 'error', 'keystone'], `${err}`);
|
||||
return reply(Boom.wrap(err));
|
||||
return reply.unauthenticated(err);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016 FUJITSU LIMITED
|
||||
* Copyright 2020 FUJITSU LIMITED
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016 FUJITSU LIMITED
|
||||
* Copyright 2020 FUJITSU LIMITED
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
@ -13,9 +13,11 @@
|
||||
*/
|
||||
|
||||
import authenticateFactory from './_authenticate';
|
||||
import verify from './verify'
|
||||
|
||||
export default (server, opts) => {
|
||||
return {
|
||||
authenticate: authenticateFactory(server, opts)
|
||||
authenticate: authenticateFactory(server, opts),
|
||||
verify: verify(server)
|
||||
};
|
||||
};
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016 FUJITSU LIMITED
|
||||
* Copyright 2020 FUJITSU LIMITED
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
@ -15,7 +15,6 @@
|
||||
import Boom from 'boom';
|
||||
import Promise from 'bluebird';
|
||||
|
||||
import kibanaIndex from '../kibana';
|
||||
import defaultIndexPattern from '../kibana/defaultIndexPattern';
|
||||
import userProjects from '../projects';
|
||||
|
||||
@ -36,11 +35,7 @@ export default (server) => {
|
||||
session.set(SESSION_TOKEN_KEY, token);
|
||||
session.set(SESSION_USER_KEY, userObj);
|
||||
|
||||
return Promise
|
||||
.all([
|
||||
userProjects(server, session, userObj),
|
||||
kibanaIndex(server, userObj)
|
||||
])
|
||||
return userProjects(server, session, userObj)
|
||||
.then(defaultIndexPattern(server, userObj))
|
||||
.then(() => {
|
||||
server.log(['status', 'info', 'keystone'], `User ${userObj.user.id} authorized with keystone`);
|
||||
@ -49,7 +44,7 @@ export default (server) => {
|
||||
.catch(err => {
|
||||
server.log(['status', 'info', 'keystone'],
|
||||
`Error caught in process of authorization, err was ${err}`);
|
||||
throw err;
|
||||
throw new Error(err);
|
||||
});
|
||||
}
|
||||
|
||||
@ -63,13 +58,11 @@ export default (server) => {
|
||||
if (error.statusCode === 401) {
|
||||
err = Boom.forbidden('\You\'re not logged in as a user who\'s authorized to access log information');
|
||||
} else {
|
||||
err = Boom.internal(
|
||||
error.message || 'Unexpected error during Keystone communication',
|
||||
{},
|
||||
err = Boom.internal(error.message || 'Unexpected error during Keystone communication',
|
||||
error.statusCode
|
||||
);
|
||||
}
|
||||
return resolve(err);
|
||||
resolve(err);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016 FUJITSU LIMITED
|
||||
* Copyright 2020 FUJITSU LIMITED
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
@ -38,7 +38,8 @@ const HEADER_NAME = 'x-auth-token';
|
||||
*/
|
||||
module.exports = (server, request) => {
|
||||
|
||||
if (!request.yar || request.yar === null) {
|
||||
|
||||
if (!request.yar) {
|
||||
server.log(['status', 'keystone', 'error'], 'Session is not enabled');
|
||||
throw new Error('Session support is missing');
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016 FUJITSU LIMITED
|
||||
* Copyright 2020 FUJITSU LIMITED
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
@ -15,26 +15,24 @@
|
||||
import Boom from 'boom';
|
||||
|
||||
import {
|
||||
SESSION_PROJECTS_KEY,
|
||||
SESSION_USER_KEY,
|
||||
SESSION_TOKEN_CHANGED,
|
||||
TOKEN_CHANGED_VALUE,
|
||||
RELOAD_MARKUP
|
||||
} from '../../const';
|
||||
|
||||
export default () => {
|
||||
return (request, reply) => {
|
||||
export default (server) => {
|
||||
return async (request, reply) => {
|
||||
|
||||
let session = request.yar;
|
||||
let userObj = session.get(SESSION_USER_KEY);
|
||||
let tokenChanged = session.get(SESSION_TOKEN_CHANGED);
|
||||
|
||||
if (tokenChanged === TOKEN_CHANGED_VALUE) {
|
||||
request.log(['status', 'info', 'keystone'],
|
||||
'Detected that token has been changed, replaying the request'
|
||||
);
|
||||
//TODO: This part doesn't really have any effect now because Kibana won't allow HTML injection
|
||||
server.log(['status', 'info', 'keystone'], 'Detected that token has been changed, replaying the request');
|
||||
session.clear(SESSION_TOKEN_CHANGED);
|
||||
return reply(RELOAD_MARKUP).type('text/html');
|
||||
return reply.response(RELOAD_MARKUP).type('text/html');
|
||||
} else if (userObj) {
|
||||
let expiresAt = new Date(userObj.expires_at).valueOf();
|
||||
let now = new Date().valueOf();
|
||||
@ -44,19 +42,17 @@ export default () => {
|
||||
session.reset();
|
||||
return reply(Boom.unauthorized('User token has expired'));
|
||||
} else {
|
||||
return reply.continue({
|
||||
request.yar.set({
|
||||
credentials: userObj,
|
||||
artifacts : {
|
||||
projects: session.get(SESSION_PROJECTS_KEY)
|
||||
},
|
||||
log : {
|
||||
log: {
|
||||
tags: 'keystone ok'
|
||||
}
|
||||
});
|
||||
return reply.continue;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(trebskit) should actually throw error here I guess
|
||||
return reply.continue();
|
||||
};
|
||||
return reply.continue;
|
||||
}
|
||||
};
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016 FUJITSU LIMITED
|
||||
* Copyright 2020 FUJITSU LIMITED
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
@ -12,28 +12,25 @@
|
||||
* the License.
|
||||
*/
|
||||
|
||||
export default {
|
||||
export default {
|
||||
bind: (server) => {
|
||||
server.log(['status', 'info', 'keystone'], 'Registering keystone-auth schema');
|
||||
return Promise.all([
|
||||
bindAuthScheme(server),
|
||||
bindExt(server),
|
||||
bindRouting(server)
|
||||
]);
|
||||
}
|
||||
};
|
||||
|
||||
//I suppose the handler that would prevent user from deleting his default index pattern should be implemented as well
|
||||
function bindRouting(server) {
|
||||
const kibanaIndex = server.config().get('kibana.index');
|
||||
return require('./routing')(server)
|
||||
.then((route)=> {
|
||||
route(server, 'GET', '/{paths*}');
|
||||
route(server, 'POST', '/_mget');
|
||||
route(server, 'POST', '/{index}/_search');
|
||||
route(server, 'POST', '/{index}/_field_stats');
|
||||
route(server, 'POST', '/_msearch');
|
||||
route(server, 'POST', '/_search/scroll');
|
||||
route(server, ['PUT', 'POST', 'DELETE'], '/' + kibanaIndex + '/{paths*}');
|
||||
.then((route) => {
|
||||
route(server, ['GET', 'POST'], '/{paths*}');
|
||||
route(server, ['GET', 'POST'], '/{search_pattern}/_search');
|
||||
route(server, 'GET', '/api/saved_objects/_find');
|
||||
route(server, 'GET', '/api/kibana/management/saved_objects/_find');
|
||||
route(server, 'POST', '/api/saved_objects/_bulk_get');
|
||||
});
|
||||
}
|
||||
|
||||
@ -44,21 +41,11 @@ function bindAuthScheme(server) {
|
||||
require('./auth/scheme')
|
||||
),
|
||||
server.auth.strategy(
|
||||
'session',
|
||||
'keystone-session',
|
||||
'keystone-token',
|
||||
false,
|
||||
require('./auth/strategy')(server)
|
||||
)
|
||||
]);
|
||||
}
|
||||
|
||||
function bindExt(server) {
|
||||
return Promise.all([
|
||||
server.ext(
|
||||
'onPreAuth',
|
||||
require('./auth/verify')(server),
|
||||
{after: ['yar']}
|
||||
),
|
||||
server.ext('onRequest', require('./verify')(server))
|
||||
]);
|
||||
}
|
||||
//bindExt is removed due to verify being a part of authentication scheme and the other one was no longer relevant
|
||||
|
@ -1,57 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 FUJITSU LIMITED
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
* or implied. See the License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
import semver from 'semver';
|
||||
|
||||
const VERSION_REGEX = /(\d+\.\d+\.\d+)\-rc(\d+)/i;
|
||||
|
||||
export default (server, doc) => {
|
||||
const config = server.config();
|
||||
|
||||
if (/beta|snapshot/i.test(doc._id)) {
|
||||
return false;
|
||||
}
|
||||
if (!doc._id) {
|
||||
return false;
|
||||
}
|
||||
if (doc._id === config.get('pkg.version')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
let packageRcRelease = Infinity;
|
||||
let rcRelease = Infinity;
|
||||
let packageVersion = config.get('pkg.version');
|
||||
let version = doc._id;
|
||||
let matches = doc._id.match(VERSION_REGEX);
|
||||
let packageMatches = config.get('pkg.version').match(VERSION_REGEX);
|
||||
|
||||
if (matches) {
|
||||
version = matches[1];
|
||||
rcRelease = parseInt(matches[2], 10);
|
||||
}
|
||||
|
||||
if (packageMatches) {
|
||||
packageVersion = packageMatches[1];
|
||||
packageRcRelease = parseInt(packageMatches[2], 10);
|
||||
}
|
||||
|
||||
try {
|
||||
if (semver.gte(version, packageVersion) && rcRelease >= packageRcRelease) {
|
||||
return false;
|
||||
}
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
@ -1,107 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 FUJITSU LIMITED
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
* or implied. See the License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
import { find } from 'lodash';
|
||||
import Promise from 'bluebird';
|
||||
|
||||
import canUpgradeConfig from './_can_upgrade';
|
||||
|
||||
export default (server, indexName) => {
|
||||
const config = server.config();
|
||||
const client = server.plugins.elasticsearch.client;
|
||||
const options = {
|
||||
index: indexName,
|
||||
type : 'config',
|
||||
body : {
|
||||
size: 1000,
|
||||
sort: [
|
||||
{
|
||||
buildNum: {
|
||||
order : 'desc',
|
||||
ignore_unmapped: true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
};
|
||||
|
||||
server.log(['status', 'debug', 'keystone'], `Configuring index ${indexName}`);
|
||||
|
||||
return client
|
||||
.search(options)
|
||||
.then(upgradeConfig(server, indexName))
|
||||
.then(()=>{
|
||||
return Promise
|
||||
.delay(666)
|
||||
.then(() => {
|
||||
server.log(['status', 'debug', 'keystone'], `Index ${indexName} has been configured`);
|
||||
return indexName;
|
||||
});
|
||||
})
|
||||
.catch((err)=> {
|
||||
throw new Error(`Configuring ${indexName} failed, error is ${err}`);
|
||||
});
|
||||
|
||||
function upgradeConfig(server, indexName) {
|
||||
const client = server.plugins.elasticsearch.client;
|
||||
const config = server.config();
|
||||
|
||||
return (response) => {
|
||||
if (response.hits.hits.length === 0) {
|
||||
return client.create({
|
||||
index: indexName,
|
||||
type : 'config',
|
||||
body : {
|
||||
buildNum: config.get('pkg.buildNum')
|
||||
},
|
||||
id : config.get('pkg.version')
|
||||
});
|
||||
}
|
||||
|
||||
// if we already have a the current version in the index then we need to stop
|
||||
var devConfig = find(response.hits.hits, function currentVersion(hit) {
|
||||
return hit._id !== '@@version' && hit._id === config.get('pkg.version');
|
||||
});
|
||||
|
||||
if (devConfig) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
// Look for upgradeable configs. If none of them are upgradeable
|
||||
// then resolve with null.
|
||||
let body = find(response.hits.hits, canUpgradeConfig.bind(null, server));
|
||||
if (!body) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
// if the build number is still the template string (which it wil be in development)
|
||||
// then we need to set it to the max interger. Otherwise we will set it to the build num
|
||||
body._source.buildNum = config.get('pkg.buildNum');
|
||||
|
||||
server.log(['plugin', 'elasticsearch'], {
|
||||
tmpl : 'Upgrade config from <%= prevVersion %> to <%= newVersion %>',
|
||||
prevVersion: body._id,
|
||||
newVersion : config.get('pkg.version')
|
||||
});
|
||||
|
||||
return client.create({
|
||||
index: indexName,
|
||||
type : 'config',
|
||||
body : body._source,
|
||||
id : config.get('pkg.version')
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
};
|
@ -1,76 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 FUJITSU LIMITED
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
* or implied. See the License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
import Boom from 'boom';
|
||||
|
||||
import { exists as indexExists } from './_exists';
|
||||
|
||||
export default (server, indexName) => {
|
||||
const client = server.plugins.elasticsearch.client;
|
||||
|
||||
server.log(['status', 'info', 'keystone'], `Creating user index ${indexName}`);
|
||||
|
||||
return client.indices
|
||||
.create({
|
||||
index: indexName,
|
||||
body : {
|
||||
settings: {
|
||||
number_of_shards: 1
|
||||
},
|
||||
mappings: {
|
||||
config: {
|
||||
properties: {
|
||||
buildNum: {
|
||||
type : 'string',
|
||||
index: 'not_analyzed'
|
||||
}
|
||||
}
|
||||
},
|
||||
'index-pattern': {
|
||||
properties: {
|
||||
title: {
|
||||
type: 'string'
|
||||
},
|
||||
timeFieldName: {
|
||||
type: 'string'
|
||||
},
|
||||
notExpandable: {
|
||||
type: 'boolean'
|
||||
},
|
||||
intervalName: {
|
||||
type: 'string'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch((err)=> {
|
||||
throw Boom.wrap(err, 500,
|
||||
`Failed to create index ${indexName}`);
|
||||
})
|
||||
.then(() => {
|
||||
return indexExists(server, indexName, 'yellow')
|
||||
.catch((err)=> {
|
||||
throw Boom.wrap(err, 500,
|
||||
`Waiting for index ${indexName} to come online failed`);
|
||||
})
|
||||
.then(()=> {
|
||||
server.log(['status', 'info', 'keystone'],
|
||||
`Index ${indexName} has been created`);
|
||||
return Promise.resolve(indexName);
|
||||
});
|
||||
});
|
||||
|
||||
};
|
@ -1,38 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 FUJITSU LIMITED
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
* or implied. See the License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
import kibanaIndex from './kibanaIndex';
|
||||
|
||||
export default (server, userObj) => {
|
||||
const indexName = kibanaIndex(server, userObj);
|
||||
return exists(server, indexName)
|
||||
.then((resp) => {
|
||||
return {indexName, resp};
|
||||
});
|
||||
};
|
||||
|
||||
export function exists(server, indexName, status) {
|
||||
const es = server.plugins.elasticsearch.client;
|
||||
const opts = {
|
||||
timeout : '5s',
|
||||
index : indexName,
|
||||
ignore : [408],
|
||||
waitForActiveShards: 1
|
||||
};
|
||||
if (status) {
|
||||
opts.waitForStatus = status;
|
||||
}
|
||||
return es.cluster.health(opts);
|
||||
}
|
||||
|
51
server/mt/kibana/defaultIndexPattern/_create.js
Normal file
51
server/mt/kibana/defaultIndexPattern/_create.js
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright 2020 FUJITSU LIMITED
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
* or implied. See the License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
import {createSavedObject} from '../savedObjectsToolkit';
|
||||
|
||||
export async function createLogsIndexPattern(server, userObj) {
|
||||
server.log(['status', 'info', 'keystone'],
|
||||
`Creating default logs-index pattern for ${userObj.project.id}`);
|
||||
const pattern = server.config().get('monasca-kibana-plugin.logsIndexPrefix')
|
||||
.replace('<project_id>', `${userObj.project.id}`) + '*';
|
||||
|
||||
return await createIndexPattern(server, pattern);
|
||||
}
|
||||
|
||||
export async function createEventsIndexPattern(server, userObj) {
|
||||
server.log(['status', 'info', 'keystone'],
|
||||
`Creating default events-index pattern for ${userObj.project.id}`);
|
||||
const pattern = server.config().get('monasca-kibana-plugin.eventsIndexPrefix')
|
||||
.replace('<project_id>', `${userObj.project.id}`) + '*';
|
||||
|
||||
return await createIndexPattern(server, pattern);
|
||||
}
|
||||
|
||||
async function createIndexPattern(server, pattern) {
|
||||
let timeFieldName = server.config().get('monasca-kibana-plugin.defaultTimeField');
|
||||
const type = 'index-pattern';
|
||||
const params = {
|
||||
title: pattern,
|
||||
timeFieldName: timeFieldName,
|
||||
};
|
||||
const options = {
|
||||
id: pattern,
|
||||
overwrite: true
|
||||
};
|
||||
|
||||
return createSavedObject(type, params, options)
|
||||
.then(() => {
|
||||
server.log(['status', 'info', 'keystone', 'create'], `Created ${type} ${pattern}`);
|
||||
});
|
||||
}
|
33
server/mt/kibana/defaultIndexPattern/_delete.js
Normal file
33
server/mt/kibana/defaultIndexPattern/_delete.js
Normal file
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2020 FUJITSU LIMITED
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
* or implied. See the License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
import {deleteSavedObject} from '../savedObjectsToolkit';
|
||||
|
||||
export async function deleteDefaultLogsIndex(server, userObj) {
|
||||
const pattern = server.config().get('monasca-kibana-plugin.logsIndexPrefix')
|
||||
.replace('<project_id>', `${userObj.project.id}`);
|
||||
server.log(['status', 'info', 'keystone'],
|
||||
`Attempting to delete logs-index pattern ${pattern}`);
|
||||
|
||||
return await deleteSavedObject('index-pattern', pattern);
|
||||
}
|
||||
|
||||
export async function deleteDefaultEventsIndex(server, userObj) {
|
||||
const pattern = server.config().get('monasca-kibana-plugin.eventsIndexPrefix')
|
||||
.replace('<project_id>', `${userObj.project.id}`);
|
||||
server.log(['status', 'info', 'keystone'],
|
||||
`Attempting to delete events-index pattern ${pattern}`);
|
||||
|
||||
return await deleteSavedObject('index-pattern', pattern);
|
||||
}
|
@ -1,58 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 FUJITSU LIMITED
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
* or implied. See the License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
import Promise from 'bluebird';
|
||||
|
||||
export default (server, indexName, userObj) => {
|
||||
server.log(['status', 'info', 'keystone'],
|
||||
`Creating default events-index pattern for ${indexName}`);
|
||||
|
||||
const client = server.plugins.elasticsearch.client;
|
||||
const pattern = server.config().get('monasca-kibana-plugin.eventsIndexPrefix')
|
||||
.replace('<project_id>', `${userObj.project.id}`) + '*';
|
||||
|
||||
return client.create({
|
||||
index: indexName,
|
||||
type : 'index-pattern',
|
||||
body : {
|
||||
title: pattern,
|
||||
timeFieldName : server.config().get('monasca-kibana-plugin.defaultEventsTimeField')
|
||||
},
|
||||
id : pattern
|
||||
})
|
||||
.then(() => {
|
||||
return client.update({
|
||||
index: indexName,
|
||||
type: 'config',
|
||||
id: server.config().get('pkg.version'),
|
||||
body: {
|
||||
doc: {
|
||||
defaultIndex: pattern
|
||||
}
|
||||
}
|
||||
});
|
||||
})
|
||||
.then(() => {
|
||||
return client.indices.refresh({
|
||||
index: indexName,
|
||||
force: true
|
||||
});
|
||||
})
|
||||
.then((response) => {
|
||||
return Promise.resolve(response);
|
||||
})
|
||||
.catch((err)=> {
|
||||
throw new Error(`Unable to setup events-index pattern, error is ${err}`);
|
||||
});
|
||||
};
|
@ -1,30 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 FUJITSU LIMITED
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
* or implied. See the License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
export default (server, indexName, userObj) => {
|
||||
const client = server.plugins.elasticsearch.client;
|
||||
const options = {
|
||||
index: indexName,
|
||||
type : 'index-pattern',
|
||||
id : server.config().get('monasca-kibana-plugin.eventsIndexPrefix')
|
||||
.replace('<project_id>', `${userObj.project.id}`) + '*',
|
||||
};
|
||||
server.log(['status', 'info', 'keystone'],
|
||||
`Deleting events-index pattern for ${indexName}...`);
|
||||
return client
|
||||
.delete(options)
|
||||
.catch((err)=> {
|
||||
throw new Error(`Deleting events-index pattern for ${indexName} failed, error is ${err}`);
|
||||
});
|
||||
};
|
@ -1,33 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 FUJITSU LIMITED
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
* or implied. See the License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
export default (server, indexName, userObj) => {
|
||||
const client = server.plugins.elasticsearch.client;
|
||||
const options = {
|
||||
index: indexName,
|
||||
type : 'index-pattern',
|
||||
id : server.config().get('monasca-kibana-plugin.eventsIndexPrefix')
|
||||
.replace('<project_id>', `${userObj.project.id}`) + '*',
|
||||
};
|
||||
server.log(['status', 'debug', 'keystone'],
|
||||
`Checking if default events-index pattern for ${indexName} exists...`);
|
||||
return client
|
||||
.exists(options)
|
||||
.then((resp) => {
|
||||
return resp;
|
||||
})
|
||||
.catch((err)=> {
|
||||
throw new Error(`Getting events-index pattern for ${indexName} failed, error is ${err}`);
|
||||
});
|
||||
};
|
47
server/mt/kibana/defaultIndexPattern/_exists.js
Normal file
47
server/mt/kibana/defaultIndexPattern/_exists.js
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright 2020 FUJITSU LIMITED
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
* or implied. See the License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
import {find} from "../savedObjectsToolkit";
|
||||
|
||||
export async function defaultLogsIndexExists(server, userObj) {
|
||||
const pattern = server.config().get('monasca-kibana-plugin.logsIndexPrefix')
|
||||
.replace('<project_id>', `${userObj.project.id}`) + '*';
|
||||
server.log(['status', 'debug', 'keystone'],
|
||||
`Checking if default logs-index pattern for ${userObj.project.id} exists...`);
|
||||
|
||||
return await patternExists(server, pattern);
|
||||
}
|
||||
|
||||
export async function defaultEventsIndexExists(server, userObj) {
|
||||
const pattern = server.config().get('monasca-kibana-plugin.eventsIndexPrefix')
|
||||
.replace('<project_id>', `${userObj.project.id}`) + '*';
|
||||
server.log(['status', 'debug', 'keystone'],
|
||||
`Checking if default events-index pattern for ${userObj.project.id} exists...`);
|
||||
|
||||
return await patternExists(pattern);
|
||||
}
|
||||
|
||||
async function patternExists(pattern) {
|
||||
const params = {
|
||||
type: 'index-pattern',
|
||||
fields: ['title'],
|
||||
};
|
||||
|
||||
return find(params)
|
||||
.then((response) => {
|
||||
return response.saved_objects.some(el => el.attributes.title === pattern);
|
||||
}).catch((err) => {
|
||||
throw new Error(`Checking if ${pattern} exists failed, error is ${err}`);
|
||||
});
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright 2020 FUJITSU LIMITED
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
* or implied. See the License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
export default function (server, project) {
|
||||
const logsEnabled = server.config().get('monasca-kibana-plugin.logs');
|
||||
const eventsEnabled = server.config().get('monasca-kibana-plugin.events');
|
||||
|
||||
let output = [];
|
||||
if (logsEnabled) {
|
||||
const pattern = server.config().get('monasca-kibana-plugin.logsIndexPrefix')
|
||||
.replace('<project_id>', `${project}`) + '*';
|
||||
output += pattern;
|
||||
}
|
||||
if (eventsEnabled) {
|
||||
const pattern = server.config().get('monasca-kibana-plugin.eventsIndexPrefix')
|
||||
.replace('<project_id>', `${project}`) + '*';
|
||||
output += pattern;
|
||||
}
|
||||
return output;
|
||||
}
|
@ -1,57 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 FUJITSU LIMITED
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
* or implied. See the License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
import Promise from 'bluebird';
|
||||
|
||||
export default (server, indexName, userObj) => {
|
||||
server.log(['status', 'info', 'keystone'],
|
||||
`Creating default logs-index pattern for ${indexName}`);
|
||||
|
||||
const client = server.plugins.elasticsearch.client;
|
||||
const pattern = server.config().get('monasca-kibana-plugin.logsIndexPrefix')
|
||||
.replace('<project_id>', `${userObj.project.id}`) + '*';
|
||||
return client.create({
|
||||
index: indexName,
|
||||
type : 'index-pattern',
|
||||
body : {
|
||||
title: pattern,
|
||||
timeFieldName : server.config().get('monasca-kibana-plugin.defaultTimeField')
|
||||
},
|
||||
id : pattern
|
||||
})
|
||||
.then(() => {
|
||||
return client.update({
|
||||
index: indexName,
|
||||
type: 'config',
|
||||
id: server.config().get('pkg.version'),
|
||||
body: {
|
||||
doc: {
|
||||
defaultIndex: pattern
|
||||
}
|
||||
}
|
||||
});
|
||||
})
|
||||
.then(() => {
|
||||
return client.indices.refresh({
|
||||
index: indexName,
|
||||
force: true
|
||||
});
|
||||
})
|
||||
.then((response) => {
|
||||
return Promise.resolve(response);
|
||||
})
|
||||
.catch((err)=> {
|
||||
throw new Error(`Unable to setup logs-index pattern, error is ${err}`);
|
||||
});
|
||||
};
|
@ -1,30 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 FUJITSU LIMITED
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
* or implied. See the License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
export default (server, indexName, userObj) => {
|
||||
const client = server.plugins.elasticsearch.client;
|
||||
const options = {
|
||||
index: indexName,
|
||||
type : 'index-pattern',
|
||||
id : server.config().get('monasca-kibana-plugin.logsIndexPrefix')
|
||||
.replace('<project_id>', `${userObj.project.id}`) + '*',
|
||||
};
|
||||
server.log(['status', 'info', 'keystone'],
|
||||
`Deleting logs-index pattern for ${indexName}...`);
|
||||
return client
|
||||
.delete(options)
|
||||
.catch((err)=> {
|
||||
throw new Error(`Deleting logs-index pattern for ${indexName} failed, error is ${err}`);
|
||||
});
|
||||
};
|
@ -1,33 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 FUJITSU LIMITED
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
* or implied. See the License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
export default (server, indexName, userObj) => {
|
||||
const client = server.plugins.elasticsearch.client;
|
||||
const options = {
|
||||
index: indexName,
|
||||
type : 'index-pattern',
|
||||
id : server.config().get('monasca-kibana-plugin.logsIndexPrefix')
|
||||
.replace('<project_id>', `${userObj.project.id}`) + '*',
|
||||
};
|
||||
server.log(['status', 'debug', 'keystone'],
|
||||
`Checking if default logs-index pattern for ${indexName} exists...`);
|
||||
return client
|
||||
.exists(options)
|
||||
.then((resp) => {
|
||||
return resp;
|
||||
})
|
||||
.catch((err)=> {
|
||||
throw new Error(`Getting logs-index pattern for ${indexName} failed, error is ${err}`);
|
||||
});
|
||||
};
|
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright 2020 FUJITSU LIMITED
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
* or implied. See the License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
|
||||
import {updateConfig} from "../savedObjectsToolkit";
|
||||
|
||||
export async function updateLogsConfig(server, userObj) {
|
||||
const pattern = server.config().get('monasca-kibana-plugin.logsIndexPrefix')
|
||||
.replace('<project_id>', `${userObj.project.id}`) + '*';
|
||||
|
||||
return await updateDefaultIndexPattern(server, pattern);
|
||||
}
|
||||
|
||||
export async function updateEventsConfig(server, userObj) {
|
||||
const pattern = server.config().get('monasca-kibana-plugin.eventsIndexPrefix')
|
||||
.replace('<project_id>', `${userObj.project.id}`) + '*';
|
||||
|
||||
return await updateDefaultIndexPattern(server, pattern);
|
||||
}
|
||||
|
||||
async function updateDefaultIndexPattern(server, pattern) {
|
||||
const type = 'config';
|
||||
const version = server.config().get('pkg.version');
|
||||
const changes = {
|
||||
defaultIndex: pattern
|
||||
};
|
||||
|
||||
return await updateConfig(type, version, changes)
|
||||
.catch((err) => {
|
||||
server.log(['updateConfig'], `Can't set ${pattern} as default index pattern, error is: ${err}`);
|
||||
})
|
||||
.then(() => {
|
||||
server.log(['updateConfig'], `Default index pattern is ${pattern}`);
|
||||
});
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016 FUJITSU LIMITED
|
||||
* Copyright 2020 FUJITSU LIMITED
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
@ -12,72 +12,73 @@
|
||||
* the License.
|
||||
*/
|
||||
|
||||
import Promise from 'bluebird';
|
||||
import defaultLogsIndexExists from './_logs_exists';
|
||||
import defaultEventsIndexExists from './_events_exists';
|
||||
import createLogsDefaultIndex from './_logs_create';
|
||||
import createEventsDefaultIndex from './_events_create';
|
||||
import deleteLogsDefaultIndex from './_logs_delete';
|
||||
import deleteEventsDefaultIndex from './_events_delete';
|
||||
import kibanaIndex from '../kibanaIndex';
|
||||
import {createEventsIndexPattern, createLogsIndexPattern} from "./_create";
|
||||
import {defaultEventsIndexExists, defaultLogsIndexExists} from "./_exists";
|
||||
import {deleteDefaultEventsIndex, deleteDefaultLogsIndex} from "./_delete";
|
||||
import {updateEventsConfig, updateLogsConfig} from "./_set_default_index_pattern";
|
||||
|
||||
export default (server, userObj) => {
|
||||
return () => {
|
||||
const indexName = kibanaIndex(server, userObj);
|
||||
return defaultLogsIndexExists(server, indexName, userObj)
|
||||
const project = userObj.project.id;
|
||||
return defaultLogsIndexExists(server, userObj)
|
||||
.then((logsExists) => {
|
||||
if (server.config().get('monasca-kibana-plugin.logs')) {
|
||||
server.log(['status', 'info', 'keystone'],
|
||||
`Default logs-index pattern is enabled in kibana config file`);
|
||||
if (!logsExists) {
|
||||
server.log(['status', 'warning', 'keystone'],
|
||||
`Default logs-index pattern for ${indexName} does not exist`);
|
||||
return createLogsDefaultIndex(server, indexName, userObj);
|
||||
`Default logs-index pattern for ${project} does not exist`);
|
||||
return createLogsIndexPattern(server, userObj)
|
||||
.then(() => {
|
||||
return updateLogsConfig(server, userObj);
|
||||
});
|
||||
} else {
|
||||
server.log(['status', 'info', 'keystone'],
|
||||
`Default logs-index pattern for ${indexName} already exists`);
|
||||
`Default logs-index pattern for ${project} already exists`);
|
||||
}
|
||||
|
||||
} else {
|
||||
server.log(['status', 'info', 'keystone'],
|
||||
`Default logs-index pattern is disabled in kibana config file`);
|
||||
if (logsExists) {
|
||||
server.log(['status', 'warning', 'keystone'],
|
||||
`Default logs-index pattern for ${indexName} exists, but it should not`);
|
||||
return deleteLogsDefaultIndex(server, indexName, userObj);
|
||||
`Default logs-index pattern for ${project} exists, but it should not`);
|
||||
return deleteDefaultLogsIndex(server, userObj);
|
||||
} else {
|
||||
server.log(['status', 'info', 'keystone'],
|
||||
`Default logs-index pattern for ${indexName} does not exist`);
|
||||
`Default logs-index pattern for ${project} does not exist`);
|
||||
}
|
||||
}
|
||||
})
|
||||
.then(() => {
|
||||
defaultEventsIndexExists(server, indexName, userObj)
|
||||
defaultEventsIndexExists(server, userObj)
|
||||
.then((eventsExists) => {
|
||||
if (server.config().get('monasca-kibana-plugin.events')) {
|
||||
server.log(['status', 'info', 'keystone'],
|
||||
`Default events-index pattern is enabled in kibana config file`);
|
||||
if (!eventsExists) {
|
||||
server.log(['status', 'warning', 'keystone'],
|
||||
`Default events-index pattern for ${indexName} does not exist`);
|
||||
return createEventsDefaultIndex(server, indexName, userObj);
|
||||
`Default events-index pattern for ${project} does not exist`);
|
||||
return createEventsIndexPattern(server, userObj)
|
||||
.then(() => {
|
||||
return updateEventsConfig(server, userObj)
|
||||
});
|
||||
} else {
|
||||
server.log(['status', 'info', 'keystone'],
|
||||
`Default events-index pattern for ${indexName} already exists`);
|
||||
`Default events-index pattern for ${project} already exists`);
|
||||
}
|
||||
} else {
|
||||
server.log(['status', 'info', 'keystone'],
|
||||
`Default events-index pattern is disabled in kibana config file`);
|
||||
if (eventsExists) {
|
||||
server.log(['status', 'warning', 'keystone'],
|
||||
`Default events-index pattern for ${indexName} exists, but it should not`);
|
||||
return deleteEventsDefaultIndex(server, indexName, userObj);
|
||||
`Default events-index pattern for ${project} exists, but it should not`);
|
||||
return deleteDefaultEventsIndex(server, userObj);
|
||||
} else {
|
||||
server.log(['status', 'info', 'keystone'],
|
||||
`Default events-index pattern for ${indexName} does not exist`);
|
||||
`Default events-index pattern for ${project} does not exist`);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
})
|
||||
})
|
||||
};
|
||||
};
|
||||
|
@ -1,39 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 FUJITSU LIMITED
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
* or implied. See the License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
import indexExists from './_exists';
|
||||
import createIndex from './_create';
|
||||
import configureIndex from './_configure';
|
||||
|
||||
export default (server, userObj) => {
|
||||
return doCheck();
|
||||
|
||||
function doCheck() {
|
||||
return indexExists(server, userObj)
|
||||
.then(({indexName, resp}) => {
|
||||
if (!resp || resp.timed_out) {
|
||||
server.log(['status', 'warning', 'keystone'], `Index ${indexName} does not exists`);
|
||||
return createIndex(server, indexName);
|
||||
}
|
||||
if (resp.status === 'red') {
|
||||
server.log(['status', 'warning', 'keystone'], `Shards not ready for index ${indexName}`);
|
||||
return Promise.delay(2500).then(doCheck);
|
||||
}
|
||||
return Promise.resolve(indexName);
|
||||
})
|
||||
.then((indexName)=> {
|
||||
return configureIndex(server, indexName);
|
||||
});
|
||||
}
|
||||
};
|
@ -1,29 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 FUJITSU LIMITED
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
* or implied. See the License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Returns tenant/project-aware kibana index
|
||||
*
|
||||
* @param server server object
|
||||
* @param userObj user details as retrieved from keystone
|
||||
* @returns {string} project aware kibana index
|
||||
*
|
||||
*/
|
||||
export default (server, userObj) => {
|
||||
return `${server.config().get('kibana.index')}-${getProjectId(userObj)}`;
|
||||
};
|
||||
|
||||
function getProjectId(userObj) {
|
||||
return userObj.project.id;
|
||||
}
|
138
server/mt/kibana/savedObjectsToolkit/index.js
Normal file
138
server/mt/kibana/savedObjectsToolkit/index.js
Normal file
@ -0,0 +1,138 @@
|
||||
/*
|
||||
* Copyright 2020 FUJITSU LIMITED
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
* or implied. See the License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
let savedObjectsClient;
|
||||
|
||||
export function initClients(server) {
|
||||
const elasticsearchClient = server.plugins.elasticsearch.getCluster('admin').callWithInternalUser;
|
||||
const {SavedObjectsClient, getSavedObjectsRepository} = server.savedObjects;
|
||||
const internalRepository = getSavedObjectsRepository(elasticsearchClient);
|
||||
|
||||
savedObjectsClient = new SavedObjectsClient(internalRepository);
|
||||
}
|
||||
|
||||
export function findWithMeta(server, params) {
|
||||
const version = server.config().get('pkg.version');
|
||||
|
||||
params.fields ? params.fields.push('title') : params.fields = ['title'];
|
||||
params.fields.push('visState');
|
||||
|
||||
return find(params)
|
||||
.then((response) => {
|
||||
response.saved_objects.forEach(el => _createMetaForSavedObject(el, version));
|
||||
return response;
|
||||
})
|
||||
.catch((err) => {
|
||||
throw new Error(err);
|
||||
});
|
||||
}
|
||||
|
||||
export async function bulkGetSavedObjects(params) {
|
||||
return await savedObjectsClient.bulkGet(params)
|
||||
.catch((err) => {
|
||||
throw new Error(err);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function _createMetaForSavedObject(object, version) {
|
||||
const inAppPrefix = '/app/kibana#';
|
||||
const managementPrefix = '/management/kibana';
|
||||
switch (object.type) {
|
||||
case 'config':
|
||||
object.meta = {
|
||||
title: `Advanced Settings [${version}]`,
|
||||
inAppUrl: {
|
||||
path: `${inAppPrefix}${managementPrefix}/settings`,
|
||||
uiCapabilitiesPath: "advancedSettings.show"
|
||||
}
|
||||
};
|
||||
break;
|
||||
case 'index-pattern':
|
||||
object.meta = {
|
||||
icon: 'indexPatternApp',
|
||||
title: object.attributes.title,
|
||||
editUrl: `${managementPrefix}/index_patterns/${object.title}`,
|
||||
inAppUrl: {
|
||||
path: `${inAppPrefix}${managementPrefix}/index_patterns/${object.id}`,
|
||||
uiCapabilitiesPath: "management.kibana.index_patterns"
|
||||
}
|
||||
};
|
||||
break;
|
||||
case 'search':
|
||||
object.meta = {
|
||||
icon: 'search',
|
||||
title: object.attributes.title,
|
||||
editUrl: `${managementPrefix}/objects/savedSearches/${object.id}`,
|
||||
inAppUrl: {
|
||||
path: `${inAppPrefix}/discover/${object.id}`,
|
||||
uiCapabilitiesPath: "discover.show"
|
||||
}
|
||||
};
|
||||
break;
|
||||
case 'visualization':
|
||||
object.meta = {
|
||||
icon: 'visualizeApp',
|
||||
title: object.attributes.title,
|
||||
editUrl: `${managementPrefix}/objects/savedVisualizations/${object.id}`,
|
||||
inAppUrl: {
|
||||
path: `${inAppPrefix}/visualize/edit/${object.id}`,
|
||||
uiCapabilitiesPath: "visualize.show"
|
||||
}
|
||||
};
|
||||
break;
|
||||
case 'dashboard':
|
||||
object.meta = {
|
||||
icon: 'dashboardApp',
|
||||
title: object.attributes.title,
|
||||
editUrl: `${managementPrefix}/objects/savedDashboards/${object.id}`,
|
||||
inAppUrl: {
|
||||
path: `${inAppPrefix}/dashboard/${object.id}`,
|
||||
uiCapabilitiesPath: "dashboard.show"
|
||||
}
|
||||
};
|
||||
break;
|
||||
default:
|
||||
throw new Error(`Unknown saved object type ${object.type}`);
|
||||
}
|
||||
return object;
|
||||
}
|
||||
|
||||
export async function createSavedObject(type, options, params) {
|
||||
return await savedObjectsClient.create(type, options, params)
|
||||
.catch((err) => {
|
||||
throw new Error(`Unable to create ${type} ${options}, error is ${err}`);
|
||||
});
|
||||
}
|
||||
|
||||
export async function find(params) {
|
||||
return await savedObjectsClient.find(params)
|
||||
.catch((err) => {
|
||||
throw new Error(`Can't perform search ${params}, error is: ${err}`);
|
||||
});
|
||||
}
|
||||
|
||||
export async function updateConfig(type, version, changes) {
|
||||
return await savedObjectsClient.update(type, version, changes)
|
||||
.catch((err) => {
|
||||
throw new Error(`Can't update ${type} with ${changes}, error is: ${err}`);
|
||||
});
|
||||
}
|
||||
|
||||
export async function deleteSavedObject(type, id) {
|
||||
return await savedObjectsClient.delete(type, id)
|
||||
.catch((err) => {
|
||||
throw new Error(`Can't delete ${type} ${id}, error is: ${err}`);
|
||||
});
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016 FUJITSU LIMITED
|
||||
* Copyright 2020 FUJITSU LIMITED
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016 FUJITSU LIMITED
|
||||
* Copyright 2020 FUJITSU LIMITED
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
@ -27,7 +27,8 @@ const readFile = (file) => fs.readFileSync(file, 'utf8');
|
||||
|
||||
module.exports = memoize(function (server) {
|
||||
const config = server.config();
|
||||
const target = url.parse(config.get('elasticsearch.url'));
|
||||
|
||||
const target = url.parse(config.get('monasca-kibana-plugin.elasticsearch.url'));
|
||||
|
||||
if (!/^https/.test(target.protocol)) {
|
||||
return new http.Agent();
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016 FUJITSU LIMITED
|
||||
* Copyright 2020 FUJITSU LIMITED
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
@ -16,27 +16,36 @@ import { PREFIX } from './_utils';
|
||||
|
||||
module.exports = (server, method, route) => {
|
||||
|
||||
const serverConfig = server.config();
|
||||
const pre = '/elasticsearch';
|
||||
const sep = route[0] === '/' ? '' : '/';
|
||||
const path = `${PREFIX}${pre}${sep}${route}`;
|
||||
let path;
|
||||
if (/\/api.*\//.test(route)) {
|
||||
path = `${PREFIX}${sep}${route}`;
|
||||
} else {
|
||||
path = `${PREFIX}${pre}${sep}${route}`;
|
||||
}
|
||||
|
||||
server.log(['create-proxy-path'], path + '; ' + method);
|
||||
|
||||
let options;
|
||||
|
||||
switch (route) {
|
||||
case '/_mget':
|
||||
options = require('./routes/mget')(server, method, path);
|
||||
case '/_search':
|
||||
options = require('./routes/search')(server, method, path);
|
||||
break;
|
||||
case '/{paths*}':
|
||||
options = require('./routes/paths')(server, method, path);
|
||||
case '/{search_pattern}/_search':
|
||||
options = require('./routes/pattern_search')(server, method, path);
|
||||
break;
|
||||
case '/api/saved_objects/_bulk_get':
|
||||
options = require('./routes/bulk_get')(server, method, path);
|
||||
break;
|
||||
default:
|
||||
if (route === `/${serverConfig.get('kibana.index')}/{paths*}`) {
|
||||
options = require('./routes/kibana_index')(server, method, path);
|
||||
if (/\/api.*\/saved_objects\/_find/.test(route)) {
|
||||
options = require('./routes/find')(server, method, path);
|
||||
} else {
|
||||
options = require('./routes/default')(server, method, path);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return server.route(options);
|
||||
};
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016 FUJITSU LIMITED
|
||||
* Copyright 2020 FUJITSU LIMITED
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
@ -23,10 +23,10 @@ import { PREFIX } from './_utils';
|
||||
|
||||
export default (server, request) => {
|
||||
const config = server.config();
|
||||
const path = request.path.replace(`${PREFIX}/elasticsearch`, '');
|
||||
const path = request.path.replace(`${PREFIX}`, '').replace(`/elasticsearch`, '');
|
||||
const query = querystring.stringify(request.query);
|
||||
|
||||
let url = config.get('elasticsearch.url');
|
||||
let url = config.get('monasca-kibana-plugin.elasticsearch.url');
|
||||
|
||||
if (path) {
|
||||
if (/\/$/.test(url)) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016 FUJITSU LIMITED
|
||||
* Copyright 2020 FUJITSU LIMITED
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
@ -12,16 +12,17 @@
|
||||
* the License.
|
||||
*/
|
||||
|
||||
import utils from '../../util';
|
||||
import {isRouted, requestPath} from '../../util';
|
||||
import { PREFIX } from './_utils';
|
||||
|
||||
module.exports = function reRoute(server) {
|
||||
return (request, reply) => {
|
||||
const requestPath = utils.requestPath(request);
|
||||
if (utils.isESRequest(request)) {
|
||||
server.log(['status', 'debug', 'keystone'], `Routing ${requestPath} onto ${PREFIX}${requestPath}`);
|
||||
request.setUrl(`${PREFIX}${requestPath}`);
|
||||
const path = requestPath(request);
|
||||
if (isRouted(request)) {
|
||||
server.log(['status', 'debug', 'keystone'], `Routing ${path} onto ${PREFIX}${path}`);
|
||||
request.setUrl(`${PREFIX}${path}`);
|
||||
}
|
||||
return reply.continue();
|
||||
return reply.continue;
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016 FUJITSU LIMITED
|
||||
* Copyright 2020 FUJITSU LIMITED
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
@ -13,19 +13,20 @@
|
||||
*/
|
||||
|
||||
import createAgent from './_create_agent';
|
||||
import {bulkGetSavedObjects} from "../kibana/savedObjectsToolkit";
|
||||
|
||||
export const PREFIX = '/mt';
|
||||
|
||||
export function getOpts(server, request, url, payload) {
|
||||
|
||||
let options = {
|
||||
headers : {},
|
||||
redirects : true,
|
||||
passThrough : true,
|
||||
xforward : true,
|
||||
timeout : 1000 * 60 * 3,
|
||||
headers: {},
|
||||
redirects: true,
|
||||
passThrough: true,
|
||||
xforward: true,
|
||||
search_timeout: '10s',
|
||||
localStatePassThrough: false,
|
||||
agent : createAgent(server),
|
||||
agent: createAgent(server),
|
||||
};
|
||||
let protocol = url.split(':', 1)[0];
|
||||
|
||||
@ -35,7 +36,7 @@ export function getOpts(server, request, url, payload) {
|
||||
|
||||
if (options.passThrough) {
|
||||
options.headers = require('hoek').clone(request.headers);
|
||||
delete options.headers.host;
|
||||
//delete options.headers.host;
|
||||
if (options.acceptEncoding === false) {
|
||||
delete options.headers['accept-encoding'];
|
||||
}
|
||||
@ -46,11 +47,11 @@ export function getOpts(server, request, url, payload) {
|
||||
request.info.remotePort) {
|
||||
|
||||
options.headers['x-forwarded-for'] = (options.headers['x-forwarded-for'] ?
|
||||
options.headers['x-forwarded-for'] + ',' : '') + request.info.remoteAddress;
|
||||
options.headers['x-forwarded-for'] + ',' : '') + request.info.remoteAddress;
|
||||
options.headers['x-forwarded-port'] = (options.headers['x-forwarded-port'] ?
|
||||
options.headers['x-forwarded-port'] + ',' : '') + request.info.remotePort;
|
||||
options.headers['x-forwarded-port'] + ',' : '') + request.info.remotePort;
|
||||
options.headers['x-forwarded-proto'] = (options.headers['x-forwarded-proto'] ?
|
||||
options.headers['x-forwarded-proto'] + ',' : '') + protocol;
|
||||
options.headers['x-forwarded-proto'] + ',' : '') + protocol;
|
||||
}
|
||||
|
||||
const contentType = request.headers['content-type'];
|
||||
@ -68,3 +69,60 @@ export function parsePayload(request) {
|
||||
}
|
||||
return JSON.parse(payload.toString('utf-8'));
|
||||
}
|
||||
|
||||
|
||||
function isAllowedSavedObject(element, patterns) {
|
||||
let references = [];
|
||||
switch (element.type) {
|
||||
case 'index-pattern':
|
||||
return patterns.includes(element.id);
|
||||
case 'config':
|
||||
return true;
|
||||
case 'visualization':
|
||||
case 'search':
|
||||
references = element.references.filter(element => patterns.includes(element.id));
|
||||
return references.length > 0;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// We have to retrieve savedObjects once again because some of the searches may not contain the references of references
|
||||
// Dashboard would be allowed only if it references saved objects accessible to the user
|
||||
function isAllowedDashboard(element, patterns) {
|
||||
|
||||
const dashboardRefs = element.references.map((el) => {
|
||||
return {id: el.id, type: el.type}
|
||||
});
|
||||
|
||||
return bulkGetSavedObjects(dashboardRefs)
|
||||
.then((response) => {
|
||||
let onlyAllowed = true;
|
||||
const references = response.saved_objects.map((el) => el.references)[0];
|
||||
references.forEach((hit) => {
|
||||
if (!patterns.includes(hit.id)) onlyAllowed = false;
|
||||
});
|
||||
return onlyAllowed;
|
||||
});
|
||||
}
|
||||
|
||||
async function filterDashboards(object, patterns) {
|
||||
let dashboards = [];
|
||||
for (let element of object) {
|
||||
if (element.type === 'dashboard' && await isAllowedDashboard(element, patterns)) {
|
||||
dashboards.push(element);
|
||||
}
|
||||
}
|
||||
return dashboards;
|
||||
}
|
||||
|
||||
// Dashboards have to be processed separately because it's references in saved_objects
|
||||
// don't contain the references to index-pattern
|
||||
// Dashboard is deemed allowed only if it contains allowed references only.
|
||||
export async function filterResponse(data, patterns) {
|
||||
let savedObjects = data.saved_objects.filter(el => isAllowedSavedObject(el, patterns));
|
||||
let savedDashboards = await filterDashboards(data.saved_objects, patterns);
|
||||
|
||||
data.saved_objects = savedObjects.concat(savedDashboards);
|
||||
return data;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016 FUJITSU LIMITED
|
||||
* Copyright 2020 FUJITSU LIMITED
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
|
42
server/mt/routing/routes/bulk_get.js
Normal file
42
server/mt/routing/routes/bulk_get.js
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 2020 FUJITSU LIMITED
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
* or implied. See the License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
import {bulkGetSavedObjects} from '../../kibana/savedObjectsToolkit';
|
||||
import getAllowedPatterns from '../../kibana/defaultIndexPattern/_get_allowed_patterns'
|
||||
import {SESSION_USER_KEY} from '../../../const';
|
||||
|
||||
export default function (server, method, path) {
|
||||
return {
|
||||
method: method,
|
||||
path: path,
|
||||
config: {
|
||||
auth: 'keystone-session',
|
||||
},
|
||||
handler: handler
|
||||
};
|
||||
|
||||
async function handler(request, reply) {
|
||||
const userObj = request.yar.get(SESSION_USER_KEY);
|
||||
const patterns = getAllowedPatterns(server, userObj.project.id);
|
||||
const params = request.payload;
|
||||
|
||||
if (params.type === 'index-pattern') {
|
||||
if (!patterns.includes(params.id)) {
|
||||
server.log(['error', 'api-bulk-get'], `Index-pattern ${params.id} is not allowed`);
|
||||
throw new Error(`Index-pattern ${params.id} is not allowed`);
|
||||
}
|
||||
}
|
||||
return bulkGetSavedObjects(params);
|
||||
}
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016 FUJITSU LIMITED
|
||||
* Copyright 2020 FUJITSU LIMITED
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
@ -20,14 +20,17 @@ module.exports = function defaultHandler(server, method, path) {
|
||||
method : method,
|
||||
path : path,
|
||||
config : {
|
||||
auth : 'session'
|
||||
auth : 'keystone-session'
|
||||
},
|
||||
handler: {
|
||||
proxy: {
|
||||
mapUri : (request, done) => {
|
||||
mapUri : (request) => {
|
||||
server.log(['route-handler-default'], request.url.path);
|
||||
server.log(['status', 'debug', 'keystone'],
|
||||
`mapUri for path ${request.path}`);
|
||||
done(null, mapUri(server, request));
|
||||
`mapUri for path ${request.url.path}`);
|
||||
return {
|
||||
uri: mapUri(server, request)
|
||||
};
|
||||
},
|
||||
agent : createAgent(server),
|
||||
passThrough: true,
|
||||
|
51
server/mt/routing/routes/find.js
Normal file
51
server/mt/routing/routes/find.js
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright 2020 FUJITSU LIMITED
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
* or implied. See the License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
import {findWithMeta} from '../../kibana/savedObjectsToolkit';
|
||||
import {filterResponse} from "../_utils";
|
||||
import {SESSION_USER_KEY} from '../../../const';
|
||||
import getAllowedPatterns from '../../kibana/defaultIndexPattern/_get_allowed_patterns';
|
||||
|
||||
export default function (server, method, path) {
|
||||
return {
|
||||
method: method,
|
||||
path: path,
|
||||
config: {
|
||||
auth: 'keystone-session',
|
||||
},
|
||||
handler: handler
|
||||
};
|
||||
|
||||
async function handler(request, reply) {
|
||||
const userObj = request.yar.get(SESSION_USER_KEY);
|
||||
const project = userObj.project.id;
|
||||
const patterns = getAllowedPatterns(server, project);
|
||||
const params = request.query;
|
||||
|
||||
if (params.fields && !(params.fields instanceof Array)) {
|
||||
params.fields = [params.fields];
|
||||
}
|
||||
return findWithMeta(server, params)
|
||||
.then((response) => {
|
||||
return filterResponse(response, patterns, server)
|
||||
})
|
||||
.then((response) => {
|
||||
response.total = response.saved_objects.length;
|
||||
return response;
|
||||
})
|
||||
.catch((e) => {
|
||||
throw new Error(`Find route failed, error: ${e}`);
|
||||
});
|
||||
}
|
||||
}
|
@ -1,57 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 FUJITSU LIMITED
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
* or implied. See the License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
import Wreck from 'wreck';
|
||||
|
||||
import { SESSION_USER_KEY } from '../../../const';
|
||||
import { getOpts, parsePayload } from '../_utils';
|
||||
import kibanaIndex from '../../kibana/kibanaIndex';
|
||||
import mapUri from '../_map_uri';
|
||||
|
||||
export default function (server, method, path) {
|
||||
|
||||
const defaultKibanaIndex = server.config().get('kibana.index');
|
||||
|
||||
return {
|
||||
method : method,
|
||||
path : path,
|
||||
config : {
|
||||
auth : 'session',
|
||||
payload: {
|
||||
output: 'data',
|
||||
parse : false
|
||||
}
|
||||
},
|
||||
handler: handler
|
||||
};
|
||||
|
||||
function handler(request, reply) {
|
||||
const url = getUrl(request);
|
||||
const opts = getOpts(server, request, url, parsePayload(request));
|
||||
return Wreck.request(request.method, url, opts, (err, res) => {
|
||||
return reply(res).code(res.statusCode).passThrough(!!opts.passThrough);
|
||||
});
|
||||
}
|
||||
|
||||
function getUrl(request) {
|
||||
const session = request.yar._store;
|
||||
|
||||
let url = mapUri(server, request).split('/');
|
||||
let indexPos = url.findIndex((item) => item === defaultKibanaIndex);
|
||||
|
||||
url[indexPos] = kibanaIndex(server, session[SESSION_USER_KEY]);
|
||||
|
||||
return url.join('/');
|
||||
}
|
||||
}
|
@ -1,69 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 FUJITSU LIMITED
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
* or implied. See the License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
import Boom from 'boom';
|
||||
import Wreck from 'wreck';
|
||||
|
||||
import { SESSION_USER_KEY } from '../../../const';
|
||||
import { getOpts, parsePayload } from '../_utils';
|
||||
import kibanaIndex from '../../kibana/kibanaIndex';
|
||||
import mapUri from '../_map_uri';
|
||||
|
||||
export default function (server, method, path) {
|
||||
|
||||
return {
|
||||
method : method,
|
||||
path : path,
|
||||
config : {
|
||||
auth : 'session',
|
||||
payload: {
|
||||
output: 'data',
|
||||
parse : false
|
||||
}
|
||||
},
|
||||
handler: handler
|
||||
};
|
||||
|
||||
function handler(request, reply) {
|
||||
const url = mapUri(server, request);
|
||||
const session = request.yar._store;
|
||||
const payload = parsePayload(request);
|
||||
|
||||
payload.docs.forEach((doc) => {
|
||||
doc._index = kibanaIndex(server, session[SESSION_USER_KEY]);
|
||||
});
|
||||
|
||||
const opts = getOpts(server, request, url, payload);
|
||||
return Wreck.request(request.method, url, opts, (err, res) => {
|
||||
if (err) {
|
||||
server.log(
|
||||
['status', 'error', 'keystone'],
|
||||
`Failed to request ${url}, error is ${err}`);
|
||||
return reply(Boom.wrap(err));
|
||||
}
|
||||
return Wreck.read(res, {json: true}, (err, body)=> {
|
||||
if (err) {
|
||||
server.log(
|
||||
['status', 'error', 'keystone'],
|
||||
`Failed to read response from ${url}, error is ${err}`);
|
||||
return reply(Boom.wrap(err));
|
||||
}
|
||||
|
||||
return reply(body)
|
||||
.code(res.statusCode)
|
||||
.passThrough(!!opts.passThrough);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
@ -1,81 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 FUJITSU LIMITED
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
* or implied. See the License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
import Wreck from 'wreck';
|
||||
import Boom from 'boom';
|
||||
|
||||
import { SESSION_USER_KEY } from '../../../const';
|
||||
import { getOpts } from '../_utils';
|
||||
import kibanaIndex from '../../kibana/kibanaIndex';
|
||||
import mapUri from '../_map_uri';
|
||||
|
||||
export default function (server, method, path) {
|
||||
const defaultKibanaIndex = server.config().get('kibana.index');
|
||||
const logIndexPostionInUrl = 3;
|
||||
|
||||
return {
|
||||
method : method,
|
||||
path : path,
|
||||
config : {
|
||||
tags: ['elasticsearch', 'multitenancy'],
|
||||
auth: 'session'
|
||||
},
|
||||
handler: handler
|
||||
};
|
||||
|
||||
function handler(request, reply) {
|
||||
const session = request.yar._store;
|
||||
|
||||
let url = mapUri(server, request).split('/');
|
||||
let kibanaIndexRequest = false;
|
||||
|
||||
let indexPos = url.findIndex((item) => item === defaultKibanaIndex);
|
||||
let logsIndexPref = server.config().get('monasca-kibana-plugin.logsIndexPrefix');
|
||||
let eventsIndexPref = server.config().get('monasca-kibana-plugin.eventsIndexPrefix');
|
||||
logsIndexPref = logsIndexPref.replace('<project_id>', session[SESSION_USER_KEY].project.id);
|
||||
eventsIndexPref = eventsIndexPref.replace('<project_id>', session[SESSION_USER_KEY].project.id);
|
||||
|
||||
server.log(['status', 'info', 'keystone'],
|
||||
`Allowing only these Index-Prefix ${logsIndexPref}, ${eventsIndexPref}`);
|
||||
|
||||
if (indexPos > -1) {
|
||||
url[indexPos] = kibanaIndex(server, session[SESSION_USER_KEY]);
|
||||
kibanaIndexRequest = true;
|
||||
} else if (url.length > logIndexPostionInUrl
|
||||
&& !(url[logIndexPostionInUrl].startsWith(logsIndexPref)
|
||||
|| url[logIndexPostionInUrl].startsWith(eventsIndexPref))) {
|
||||
return reply(Boom.unauthorized('User does not have access to this resource'));
|
||||
}
|
||||
|
||||
url = url.join('/');
|
||||
|
||||
const opts = getOpts(server, request, url);
|
||||
return Wreck.request(request.method, url, opts, (err, res) => {
|
||||
return Wreck.read(res, {json: true}, (err, body)=> {
|
||||
let newData = {};
|
||||
|
||||
if (kibanaIndexRequest) {
|
||||
let tenantAwareIndex = Object.keys(body)[0];
|
||||
newData[defaultKibanaIndex] = body[tenantAwareIndex];
|
||||
} else {
|
||||
newData = body;
|
||||
}
|
||||
|
||||
return reply(newData)
|
||||
.code(res.statusCode)
|
||||
.passThrough(!!opts.passThrough);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
66
server/mt/routing/routes/pattern_search.js
Normal file
66
server/mt/routing/routes/pattern_search.js
Normal file
@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright 2020 FUJITSU LIMITED
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
* or implied. See the License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
import Wreck from '@hapi/wreck';
|
||||
|
||||
import {SESSION_USER_KEY} from '../../../const';
|
||||
import {getOpts} from '../_utils';
|
||||
import getAllowedPatterns from '../../kibana/defaultIndexPattern/_get_allowed_patterns';
|
||||
import mapUri from '../_map_uri';
|
||||
|
||||
export default function (server, method, path) {
|
||||
return {
|
||||
method: method,
|
||||
path: path,
|
||||
config: {
|
||||
auth: 'keystone-session',
|
||||
},
|
||||
handler: handler
|
||||
};
|
||||
|
||||
async function handler(request, reply) {
|
||||
|
||||
const session = request.yar;
|
||||
let url = mapUri(server, request).split('/');
|
||||
let project = session.get(SESSION_USER_KEY).project.id;
|
||||
|
||||
let logsIndexPref = server.config().get('monasca-kibana-plugin.logsIndexPrefix');
|
||||
let eventsIndexPref = server.config().get('monasca-kibana-plugin.eventsIndexPrefix');
|
||||
logsIndexPref = logsIndexPref.replace('<project_id>', project);
|
||||
eventsIndexPref = eventsIndexPref.replace('<project_id>', project);
|
||||
|
||||
server.log(['status', 'info', 'keystone'],
|
||||
`Allowing only these Index-Prefix ${logsIndexPref}, ${eventsIndexPref}`);
|
||||
|
||||
url = url.join('/');
|
||||
|
||||
const opts = getOpts(server, request, url, request.payload);
|
||||
const patterns = getAllowedPatterns(server, project);
|
||||
|
||||
try {
|
||||
const rawResponse = await Wreck.request(request.method, url, opts);
|
||||
const body = await Wreck.read(rawResponse, opts);
|
||||
let response = JSON.parse(body.toString());
|
||||
|
||||
if (response._shards.total > 0) {
|
||||
let indexHits = response.aggregations.indices.buckets;
|
||||
response.aggregations.indices.buckets =
|
||||
indexHits.filter(elem => patterns.includes(elem.key));
|
||||
}
|
||||
return reply.response(response).code(rawResponse.statusCode).passThrough(!!opts.passThrough);
|
||||
} catch (e) {
|
||||
throw new Error(e);
|
||||
}
|
||||
}
|
||||
}
|
47
server/mt/routing/routes/search.js
Normal file
47
server/mt/routing/routes/search.js
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright 2020 FUJITSU LIMITED
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
* or implied. See the License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
import Wreck from '@hapi/wreck';
|
||||
|
||||
import {getOpts, parsePayload} from '../_utils';
|
||||
import mapUri from '../_map_uri';
|
||||
|
||||
export default function (server, method, path) {
|
||||
|
||||
return {
|
||||
method: method,
|
||||
path: path,
|
||||
config: {
|
||||
auth: 'keystone-session',
|
||||
},
|
||||
handler: handler
|
||||
};
|
||||
|
||||
async function handler(request, reply) {
|
||||
const url = mapUri(server, request);
|
||||
const payload = parsePayload(request);
|
||||
const opts = getOpts(server, request, url, payload);
|
||||
|
||||
try {
|
||||
const rawResponse = await Wreck.request(request.method, url, opts);
|
||||
const body = await Wreck.read(rawResponse, opts);
|
||||
let response = JSON.parse(body.toString());
|
||||
|
||||
return reply.response(response).code(rawResponse.statusCode)
|
||||
.passThrough(!!opts.passThrough);
|
||||
} catch (e) {
|
||||
throw new Error(e);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 FUJITSU LIMITED
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
* or implied. See the License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
import Boom from 'boom';
|
||||
|
||||
import { SESSION_PROJECTS_KEY } from '../../const';
|
||||
import util from '../../util';
|
||||
|
||||
const INDEX_PATTER_POS = 2;
|
||||
|
||||
module.exports = (request, reply) => {
|
||||
const session = request.yar._store;
|
||||
const requestPath = util.requestPath(request);
|
||||
const splittedPath = requestPath.split('/');
|
||||
|
||||
let pattern = splittedPath[INDEX_PATTER_POS];
|
||||
let projects = session[SESSION_PROJECTS_KEY];
|
||||
|
||||
if ('*' === pattern) {
|
||||
return reply(Boom.badData('* as pattern is not supported at the moment'));
|
||||
} else if (projects.filter(filter).length === 0) {
|
||||
return reply(Boom.badData(`${pattern} do not match any project of current user`));
|
||||
}
|
||||
|
||||
return reply.continue();
|
||||
|
||||
function filter(project) {
|
||||
return new RegExp(`${project.id}.*`, 'gi').test(pattern);
|
||||
}
|
||||
};
|
@ -1,48 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 FUJITSU LIMITED
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License
|
||||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
* or implied. See the License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
import { SESSION_USER_KEY } from '../../const';
|
||||
import util from '../../util';
|
||||
|
||||
module.exports = (server) => {
|
||||
|
||||
return (request, reply) => {
|
||||
const session = request.yar._store;
|
||||
if (!(session && (SESSION_USER_KEY in session))) {
|
||||
server.log(['status', 'warning', 'keystone'], 'Session not yet available');
|
||||
return reply.continue();
|
||||
}
|
||||
|
||||
let requestPath = util.requestPath(request);
|
||||
let requestMethod = request.method;
|
||||
|
||||
if (util.isESRequest(request)) {
|
||||
let handler;
|
||||
if (isIndexPatternLookup()) {
|
||||
handler = require('./_verify_index_pattern');
|
||||
}
|
||||
if (handler) {
|
||||
return handler(request, reply);
|
||||
}
|
||||
}
|
||||
|
||||
return reply.continue();
|
||||
|
||||
function isIndexPatternLookup() {
|
||||
let regExp = /\/elasticsearch\/.*\/_mapping\/field\/.*/;
|
||||
return regExp.test(requestPath) && requestMethod.toLowerCase() === 'get';
|
||||
}
|
||||
|
||||
};
|
||||
};
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016 FUJITSU LIMITED
|
||||
* Copyright 2020 FUJITSU LIMITED
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
@ -11,40 +11,37 @@
|
||||
* or implied. See the License for the specific language governing permissions and limitations under
|
||||
* the License.
|
||||
*/
|
||||
|
||||
import yarCookie from 'yar';
|
||||
import yarCookie from "@hapi/yar"
|
||||
import multiTenancy from '../mt';
|
||||
import {initClients} from "../mt/kibana/savedObjectsToolkit";
|
||||
|
||||
export default (server) => {
|
||||
const config = server.config();
|
||||
return {
|
||||
start: ()=> {
|
||||
server.register({
|
||||
register: yarCookie,
|
||||
options : {
|
||||
start: async () => {
|
||||
await server.register({
|
||||
plugin: yarCookie,
|
||||
options: {
|
||||
maxCookieSize: 4096,
|
||||
name : config.get('monasca-kibana-plugin.cookie.name'),
|
||||
storeBlank : false,
|
||||
cache : {
|
||||
name: config.get('monasca-kibana-plugin.cookie.name'),
|
||||
storeBlank: false,
|
||||
cache: {
|
||||
expiresIn: config.get('monasca-kibana-plugin.cookie.expiresIn')
|
||||
},
|
||||
cookieOptions: {
|
||||
password : config.get('monasca-kibana-plugin.cookie.password'),
|
||||
isSecure : config.get('monasca-kibana-plugin.cookie.isSecure'),
|
||||
password: config.get('monasca-kibana-plugin.cookie.password'),
|
||||
isSecure: config.get('monasca-kibana-plugin.cookie.isSecure'),
|
||||
ignoreErrors: config.get('monasca-kibana-plugin.cookie.ignoreErrors'),
|
||||
clearInvalid: false
|
||||
}
|
||||
}
|
||||
}, (error) => {
|
||||
if (!error) {
|
||||
server.log(['status', 'info', 'keystone'], 'Session registered');
|
||||
multiTenancy.bind(server);
|
||||
} else {
|
||||
server.log(['status', 'error', 'keystone'], error);
|
||||
throw error;
|
||||
}
|
||||
}).catch((err) => {
|
||||
throw new Error(err);
|
||||
});
|
||||
server.log(['status', 'info', 'keystone'], 'Session registered');
|
||||
initClients(server);
|
||||
await multiTenancy.bind(server);
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2017 FUJITSU LIMITED
|
||||
* Copyright 2020 FUJITSU LIMITED
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
|
||||
* in compliance with the License. You may obtain a copy of the License at
|
||||
@ -13,9 +13,8 @@
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
startsWith: startsWith,
|
||||
requestPath: getRequestPath,
|
||||
isESRequest: isESRequest,
|
||||
isRouted: isRoutedRequest,
|
||||
keystoneUrl: keystoneUrl
|
||||
};
|
||||
|
||||
@ -37,20 +36,19 @@ function keystoneUrl(config) {
|
||||
return url;
|
||||
}
|
||||
|
||||
function startsWith(str) {
|
||||
var prefixes = Array.prototype.slice.call(arguments, 1);
|
||||
for (var i = 0; i < prefixes.length; ++i) {
|
||||
if (str.lastIndexOf(prefixes[i], 0) === 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function getRequestPath(request) {
|
||||
return request.url.path;
|
||||
}
|
||||
|
||||
function isESRequest(request) {
|
||||
return startsWith(getRequestPath(request), '/elasticsearch');
|
||||
return getRequestPath(request).startsWith('/elasticsearch');
|
||||
}
|
||||
|
||||
function isSavedObjectsRequest(request) {
|
||||
return /\/api.*\/saved_objects\/_/.test(getRequestPath(request));
|
||||
}
|
||||
|
||||
function isRoutedRequest(request) {
|
||||
return isESRequest(request) || isSavedObjectsRequest(request);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user