1
0
mirror of https://github.com/OpenNebula/one.git synced 2024-12-22 13:33:52 +03:00

F#3951: Consult zones and check by api (#81)

Signed-off-by: Jorge Lobo <jlobo@opennebula.io>
This commit is contained in:
Jorge Miguel Lobo Escalona 2020-07-07 12:03:54 +02:00 committed by GitHub
parent e46241c62d
commit 5b047c158d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 59 additions and 8994 deletions

3
.gitignore vendored
View File

@ -55,6 +55,7 @@ src/fireedge/yarn-error.log
src/fireedge/.DS_Store
src/fireedge/cypress/screenshots
src/fireedge/yarn.lock
src/fireedge/package-lock.json
src/onedb/local/
src/onedb/shared/
@ -66,4 +67,4 @@ share/esx-fw-vnc/.vagrant*
share/context/*
!share/context/download_context.sh
!share/context/SConstruct
!share/context/SConstruct

View File

@ -11,7 +11,7 @@ CORS: true
# Webpack mode:
# - development
# - production
MODE: development
MODE: production
# JWT user password encryption key (AUTH)
TOKEN_SECRET: token_secreto
@ -19,20 +19,4 @@ TOKEN_SECRET: token_secreto
# JWT life time
LIMIT_TOKEN:
MIN: 14
MAX: 30
# Zones Opeennebula
# -ID: identificator zone
# -RPC: URL connect to RPC (OPENNEBULA)
# -ZEROMQ: URL connect to socket ZEROMQ
# -VNC: URL connect to socket VNC
OPENNEBULA_ZONES:
- ID: 0
RPC: http://127.0.0.1:2633/RPC2
ZEROMQ:
VNC:
- ID: 1
RPC: http://localhost:2633/RPC2
ZEROMQ:
VNC:
MAX: 30

View File

@ -34,7 +34,7 @@ const {
defaultConfigLogPath,
defaultConfigLogFile,
defaultTypeLog
} = require('./utils/contants');
} = require('./utils/contants/defaults');
const {
entrypoint404,
entrypointApi,
@ -56,7 +56,7 @@ const cert = `${__dirname}/../cert/cert.pem`;
let log = morgan('dev');
if (userLog === defaultTypeLog) {
let logPath = `${defaultConfigLogPath}`;
if (env?.ONE_LOCATION) {
if (env && env.ONE_LOCATION) {
logPath = env.ONE_LOCATION + logPath;
}
try {

View File

@ -18,6 +18,8 @@ const { Map } = require('immutable');
const {
httpMethod,
defaultMethodLogin,
defaultMethodZones,
defaultMethodConfig,
defaultMethodUserInfo,
default2FAOpennebulaVar,
defaultNamespace,
@ -32,8 +34,6 @@ const {
checkOpennebulaCommand
} = require('../../../../utils/opennebula');
const { zones, oneConfig } = global;
const appConfig = getConfig();
const namespace = appConfig.NAMESPACE || defaultNamespace;
@ -156,13 +156,45 @@ const genJWT = informationUser => {
};
const setZones = () => {
if (!zones) {
console.log('setZones');
if (global && !global.zones) {
const oneConnect = connectOpennebula();
const dataSource = dataSourceWithExpirateDate();
oneConnect(
defaultMethodZones,
getOpennebulaMethod(dataSource),
(err, value) => {
// res, err, value, response, next
responseOpennebula(
() => undefined,
err,
value,
zonesOpennebula => {
if (
zonesOpennebula &&
zonesOpennebula.ZONE_POOL &&
zonesOpennebula.ZONE_POOL.ZONE
) {
const oneZones = !Array.isArray(zonesOpennebula.ZONE_POOL.ZONE)
? [zonesOpennebula.ZONE_POOL.ZONE]
: zonesOpennebula.ZONE_POOL.ZONE;
global.zones = oneZones.map(oneZone => ({
ID: oneZone.ID || '',
NAME: oneZone.NAME || '',
RPC:
(oneZone && oneZone.TEMPLATE && oneZone.TEMPLATE.ENDPOINT) ||
''
}));
}
},
next
);
}
);
}
};
const setOneConfig = () => {
if (!oneConfig) {
if (global && global.oneConfig && global.oneConfig.length === 0) {
console.log('setConfig');
}
};

View File

@ -50,11 +50,6 @@ const router = express.Router();
express();
// user config
const appConfig = getConfig();
const opennebulaZones = appConfig.OPENNEBULA_ZONES || defaultOpennebulaZones;
const paramsToRoutes = () =>
Object.keys(params).reduce(
(resources, param) => String(resources).concat(`/:${params[param]}?`),
@ -63,11 +58,12 @@ const paramsToRoutes = () =>
const getDataZone = () => {
let rtn;
if (opennebulaZones && Array.isArray(opennebulaZones)) {
const Zones = (global && global.zones) || defaultOpennebulaZones;
if (Zones && Array.isArray(Zones)) {
const { federation } = getParamsState();
rtn = opennebulaZones[0];
rtn = Zones[0];
if (federation !== null) {
rtn = opennebulaZones.find(
rtn = Zones.find(
zone => zone && zone.ID !== undefined && String(zone.ID) === federation
);
}

View File

@ -1,167 +0,0 @@
/* Copyright 2002-2019, OpenNebula Project, OpenNebula Systems */
/* */
/* 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. */
/* -------------------------------------------------------------------------- */
const express = require('express');
const { Map } = require('immutable');
const { defaults, httpCodes, params } = require('../../utils/contants');
const { getConfig } = require('../../utils/yml');
const {
opennebulaConnect,
checkRouteFunction,
commandXML,
checkOpennebulaCommand,
validateRouteFunction,
responseOpennebula
} = require('../../utils');
const {
validateResource,
optionalParameters,
optionalQueries,
clearStates,
getParamsState,
getQueriesState,
getIdUserOpennebula,
getUserOpennebula,
getPassOpennebula
} = require('./middlewares');
const {
defaultOpennebulaZones,
defaultMessageInvalidZone,
defaultGetMethod,
httpMethod: httpMethods,
from: fromData
} = defaults;
const router = express.Router();
express();
// user config
const appConfig = getConfig();
const opennebulaZones = appConfig.OPENNEBULA_ZONES || defaultOpennebulaZones;
const paramsToRoutes = () =>
Object.keys(params).reduce(
(resources, param) => String(resources).concat(`/:${params[param]}?`),
'/:resource?'
);
const getDataZone = () => {
let rtn;
if (opennebulaZones && Array.isArray(opennebulaZones)) {
const { federation } = getParamsState();
rtn = opennebulaZones[0];
if (federation !== null) {
rtn = opennebulaZones.find(
zone => zone && zone.ID !== undefined && String(zone.ID) === federation
);
}
}
return rtn;
};
router.all(
paramsToRoutes(),
[validateResource, optionalParameters, optionalQueries],
(req, res, next) => {
const { internalServerError, ok, methodNotAllowed } = httpCodes;
const { method: httpMethod } = req;
res.locals.httpCode = Map(internalServerError).toObject();
const zone = getDataZone();
if (zone) {
const { RPC } = zone;
const connectOpennebula = (
user = getUserOpennebula(),
pass = getPassOpennebula()
) => opennebulaConnect(user, pass, RPC);
const { resource } = req.params;
const routeFunction = checkRouteFunction(resource);
res.locals.httpCode = Map(methodNotAllowed).toObject();
const dataSources = {
[fromData.resource]: getParamsState(),
[fromData.query]: getQueriesState(),
[fromData.postBody]: req.body
};
if (routeFunction) {
const valRouteFunction = validateRouteFunction(
routeFunction,
httpMethod
);
if (valRouteFunction) {
valRouteFunction(
dataSources,
res,
next,
connectOpennebula,
getIdUserOpennebula()
);
} else {
next();
}
} else {
const { method } = getParamsState();
const command = commandXML(
resource,
method,
httpMethod === httpMethods.GET && defaultGetMethod
);
const getOpennebulaMethod = checkOpennebulaCommand(command, httpMethod);
if (getOpennebulaMethod) {
const response = val => {
res.locals.httpCode = Map(ok).toObject();
res.locals.httpCode.data = val || {};
if (typeof val === 'string') {
res.locals.httpCode.data = {};
res.locals.httpCode.message = val;
}
next();
};
const updaterResponse = code => {
if ('id' in code && 'message' in code) {
res.locals.httpCode = code;
}
};
const connect = connectOpennebula(
getUserOpennebula(),
getPassOpennebula(),
RPC
);
connect(
command,
getOpennebulaMethod(dataSources),
(err, value) =>
responseOpennebula(updaterResponse, err, value, response, next)
);
} else {
next();
}
}
} else {
res.locals.httpCode.message += `: ${defaultMessageInvalidZone}`;
next();
}
},
(req, res) => {
clearStates();
const { httpCode } = res.locals;
res.status(httpCode.id).json(httpCode);
}
);
module.exports = router;

View File

@ -19,7 +19,6 @@ const { renderToString } = require('react-dom/server');
const root = require('window-or-global');
const { createStore, compose, applyMiddleware } = require('redux');
const thunk = require('redux-thunk').default;
const classnames = require('classnames');
const { ServerStyleSheets } = require('@material-ui/core/styles');
const rootReducer = require('../../public/reducers');
const App = require('../../public/app').default;

View File

@ -1,142 +0,0 @@
/* Copyright 2002-2019, OpenNebula Project, OpenNebula Systems */
/* */
/* 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. */
/* -------------------------------------------------------------------------- */
const { Map } = require('immutable');
const {
private: authenticated,
public: nonAuthenticated
} = require('../../../api');
const { httpCodes, params } = require('../../../../utils/contants');
const {
validateAuth,
getAllowedQueryParams,
createParamsState,
createQueriesState
} = require('../../../../utils');
const defaultParams = Map(createParamsState());
const defaultQueries = Map(createQueriesState());
let paramsState = defaultParams.toObject();
let queriesState = defaultQueries.toObject();
let idUserOpennebula = '';
let userOpennebula = '';
let passOpennebula = '';
const getParamsState = () => paramsState;
const getQueriesState = () => queriesState;
const getIdUserOpennebula = () => idUserOpennebula;
const getUserOpennebula = () => userOpennebula;
const getPassOpennebula = () => passOpennebula;
const validateResource = (req, res, next) => {
const { badRequest, unauthorized, serviceUnavailable } = httpCodes;
let status = badRequest;
if (req && req.params && req.params.resource) {
const resource = req.params.resource;
status = serviceUnavailable;
if (resource in authenticated) {
const session = validateAuth(req);
if (
session &&
'iss' in session &&
'aud' in session &&
'jti' in session &&
'iat' in session &&
'exp' in session
) {
idUserOpennebula = session.iss;
userOpennebula = session.aud;
passOpennebula = session.jti;
next();
return;
}
status = unauthorized;
}
if (resource in nonAuthenticated) {
next();
return;
}
}
res.status(status.id).json(status);
};
const optionalParameters = (req, res, next) => {
if (req && req.params) {
let start = true;
const keys = Object.keys(req.params);
keys.forEach(param => {
if (start) {
start = false;
return start;
}
if (req.params[param]) {
const matches = req.params[param].match(/(^[\w]*=)/gi);
if (matches && matches[0]) {
params.forEach(parameter => {
if (
matches[0].replace(/=/g, '').toLowerCase() ===
parameter.toLowerCase()
) {
const removeKey = new RegExp(`^${parameter}=`, 'i');
if (paramsState[parameter] === null) {
paramsState[parameter] = req.params[param].replace(
removeKey,
''
);
}
}
});
} else {
paramsState[param] = req.params[param];
}
}
return '';
});
}
next();
};
const optionalQueries = (req, res, next) => {
if (req && req.query) {
const keys = Object.keys(req.query);
const queries = getAllowedQueryParams();
keys.forEach(query => {
if (req.query[query] && queries.includes(query)) {
queriesState[query] = req.query[query];
}
});
}
next();
};
const clearStates = () => {
paramsState = defaultParams.toObject();
queriesState = defaultQueries.toObject();
idUserOpennebula = '';
userOpennebula = '';
passOpennebula = '';
};
module.exports = {
validateResource,
optionalParameters,
optionalQueries,
clearStates,
getParamsState,
getQueriesState,
getIdUserOpennebula,
getUserOpennebula,
getPassOpennebula
};

View File

@ -14,7 +14,8 @@
/* -------------------------------------------------------------------------- */
const default2FAOpennebulaVar = 'TWO_FACTOR_AUTH_SECRET';
module.exports = {
const defaultIp = 'http://127.0.0.1';
const defaults = {
httpMethod: {
GET: 'GET',
POST: 'POST',
@ -29,7 +30,8 @@ module.exports = {
defaultOpennebulaZones: [
{
ID: 0,
RPC: 'http://localhost:2633/RPC2',
NAME: 'OpenNebula',
RPC: `${defaultIp}:2633/RPC2`,
VNC: ''
}
],
@ -37,16 +39,18 @@ module.exports = {
defaultTypeLog: 'prod',
defaultWebpackMode: 'development',
defaultConfigLogPath: '/var/log/one/',
defaultConfigLogFile: 'sunstone.log',
defaultConfigLogFile: 'fireedge.log',
defaultBaseURL: '',
defaultNamespace: 'one.',
defaultMessageInvalidZone: 'Invalid Zone',
default2FAIssuer: 'sunstone-UI',
default2FAIssuer: 'fireedge-UI',
default2FAOpennebulaVar,
default2FAOpennebulaTmpVar: `TMP_${default2FAOpennebulaVar}`,
defaultGetMethod: 'info',
defaultMessageProblemOpennebula: 'Problem with conection or xml parser',
defaultMethodLogin: 'user.login',
defaultMethodZones: 'zonepool.info',
defaultMethodConfig: 'system.config',
defaultMethodUserUpdate: 'user.update',
defaultMethodUserInfo: 'user.info',
defaultLang: 'en_US',
@ -72,3 +76,5 @@ module.exports = {
es_ES: 'Spanish'
}
};
module.exports = defaults;

View File

@ -39,6 +39,7 @@ const js = {
}
}
};
const alias = {
alias: {
server: path.resolve(__dirname, 'src/'),
@ -46,7 +47,7 @@ const alias = {
'server-entrypoints': path.resolve(__dirname, 'src/routes/entrypoints/'),
'server-api': path.resolve(__dirname, 'src/routes/api/')
},
extensions: [".js"]
extensions: ['.js']
};
const serverConfig = {

File diff suppressed because it is too large Load Diff