mirror of
https://github.com/jc21/nginx-proxy-manager.git
synced 2024-08-30 18:22:48 +00:00
Sqlite Tweaks
- Added cypress testing in CI for sqlite - Cleaned up promises in setup - Ensure check for settings is strict
This commit is contained in:
parent
04412f3624
commit
492d450d26
21
.jenkins/config-sqlite.json
Normal file
21
.jenkins/config-sqlite.json
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
{
|
||||||
|
"database": {
|
||||||
|
"engine": "knex-native",
|
||||||
|
"knex": {
|
||||||
|
"client": "sqlite3",
|
||||||
|
"connection": {
|
||||||
|
"filename": "/data/database.sqlite"
|
||||||
|
},
|
||||||
|
"pool": {
|
||||||
|
"min": 0,
|
||||||
|
"max": 1,
|
||||||
|
"createTimeoutMillis": 3000,
|
||||||
|
"acquireTimeoutMillis": 30000,
|
||||||
|
"idleTimeoutMillis": 30000,
|
||||||
|
"reapIntervalMillis": 1000,
|
||||||
|
"createRetryIntervalMillis": 100,
|
||||||
|
"propagateCreateError": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
36
Jenkinsfile
vendored
36
Jenkinsfile
vendored
@ -83,11 +83,11 @@ pipeline {
|
|||||||
'''
|
'''
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
stage('Test') {
|
stage('Integration Tests Sqlite') {
|
||||||
steps {
|
steps {
|
||||||
// Bring up a stack
|
// Bring up a stack
|
||||||
sh 'docker-compose up -d fullstack'
|
sh 'docker-compose up -d fullstack-sqlite'
|
||||||
sh './scripts/wait-healthy $(docker-compose ps -q fullstack) 120'
|
sh './scripts/wait-healthy $(docker-compose ps -q fullstack-sqlite) 120'
|
||||||
|
|
||||||
// Run tests
|
// Run tests
|
||||||
sh 'rm -rf test/results'
|
sh 'rm -rf test/results'
|
||||||
@ -99,8 +99,36 @@ pipeline {
|
|||||||
always {
|
always {
|
||||||
// Dumps to analyze later
|
// Dumps to analyze later
|
||||||
sh 'mkdir -p debug'
|
sh 'mkdir -p debug'
|
||||||
sh 'docker-compose logs fullstack | gzip > debug/docker_fullstack.log.gz'
|
sh 'docker-compose logs fullstack-sqlite | gzip > debug/docker_fullstack_sqlite.log.gz'
|
||||||
sh 'docker-compose logs db | gzip > debug/docker_db.log.gz'
|
sh 'docker-compose logs db | gzip > debug/docker_db.log.gz'
|
||||||
|
sh 'docker-compose down'
|
||||||
|
// Cypress videos and screenshot artifacts
|
||||||
|
dir(path: 'test/results') {
|
||||||
|
archiveArtifacts allowEmptyArchive: true, artifacts: '**/*', excludes: '**/*.xml'
|
||||||
|
}
|
||||||
|
junit 'test/results/junit/*'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stage('Integration Tests Mysql') {
|
||||||
|
steps {
|
||||||
|
// Bring up a stack
|
||||||
|
sh 'docker-compose up -d fullstack-mysql'
|
||||||
|
sh './scripts/wait-healthy $(docker-compose ps -q fullstack-mysql) 120'
|
||||||
|
|
||||||
|
// Run tests
|
||||||
|
sh 'rm -rf test/results'
|
||||||
|
sh 'docker-compose up cypress'
|
||||||
|
// Get results
|
||||||
|
sh 'docker cp -L "$(docker-compose ps -q cypress):/results" test/'
|
||||||
|
}
|
||||||
|
post {
|
||||||
|
always {
|
||||||
|
// Dumps to analyze later
|
||||||
|
sh 'mkdir -p debug'
|
||||||
|
sh 'docker-compose logs fullstack-mysql | gzip > debug/docker_fullstack_mysql.log.gz'
|
||||||
|
sh 'docker-compose logs db | gzip > debug/docker_db.log.gz'
|
||||||
|
sh 'docker-compose down'
|
||||||
// Cypress videos and screenshot artifacts
|
// Cypress videos and screenshot artifacts
|
||||||
dir(path: 'test/results') {
|
dir(path: 'test/results') {
|
||||||
archiveArtifacts allowEmptyArchive: true, artifacts: '**/*', excludes: '**/*.xml'
|
archiveArtifacts allowEmptyArchive: true, artifacts: '**/*', excludes: '**/*.xml'
|
||||||
|
211
backend/setup.js
211
backend/setup.js
@ -8,92 +8,101 @@ const authModel = require('./models/auth');
|
|||||||
const settingModel = require('./models/setting');
|
const settingModel = require('./models/setting');
|
||||||
const debug_mode = process.env.NODE_ENV !== 'production' || !!process.env.DEBUG;
|
const debug_mode = process.env.NODE_ENV !== 'production' || !!process.env.DEBUG;
|
||||||
|
|
||||||
function setupJwt(resolve, reject) {
|
/**
|
||||||
// Now go and check if the jwt gpg keys have been created and if not, create them
|
* Creates a new JWT RSA Keypair if not alread set on the config
|
||||||
if (!config.has('jwt') || !config.has('jwt.key') || !config.has('jwt.pub')) {
|
*
|
||||||
logger.info('Creating a new JWT key pair...');
|
* @returns {Promise}
|
||||||
|
*/
|
||||||
|
const setupJwt = () => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
// Now go and check if the jwt gpg keys have been created and if not, create them
|
||||||
|
if (!config.has('jwt') || !config.has('jwt.key') || !config.has('jwt.pub')) {
|
||||||
|
logger.info('Creating a new JWT key pair...');
|
||||||
|
|
||||||
// jwt keys are not configured properly
|
// jwt keys are not configured properly
|
||||||
const filename = config.util.getEnv('NODE_CONFIG_DIR') + '/' + (config.util.getEnv('NODE_ENV') || 'default') + '.json';
|
const filename = config.util.getEnv('NODE_CONFIG_DIR') + '/' + (config.util.getEnv('NODE_ENV') || 'default') + '.json';
|
||||||
let config_data = {};
|
let config_data = {};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
config_data = require(filename);
|
config_data = require(filename);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// do nothing
|
// do nothing
|
||||||
|
if (debug_mode) {
|
||||||
|
logger.debug(filename + ' config file could not be required');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now create the keys and save them in the config.
|
||||||
|
let key = new NodeRSA({ b: 2048 });
|
||||||
|
key.generateKeyPair();
|
||||||
|
|
||||||
|
config_data.jwt = {
|
||||||
|
key: key.exportKey('private').toString(),
|
||||||
|
pub: key.exportKey('public').toString(),
|
||||||
|
};
|
||||||
|
|
||||||
|
// Write config
|
||||||
|
fs.writeFile(filename, JSON.stringify(config_data, null, 2), (err) => {
|
||||||
|
if (err) {
|
||||||
|
logger.error('Could not write JWT key pair to config file: ' + filename);
|
||||||
|
reject(err);
|
||||||
|
} else {
|
||||||
|
logger.info('Wrote JWT key pair to config file: ' + filename);
|
||||||
|
|
||||||
|
logger.warn('Restarting interface to apply new configuration');
|
||||||
|
process.exit(0);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// JWT key pair exists
|
||||||
if (debug_mode) {
|
if (debug_mode) {
|
||||||
logger.debug(filename + ' config file could not be required');
|
logger.debug('JWT Keypair already exists');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
resolve();
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
// Now create the keys and save them in the config.
|
/**
|
||||||
let key = new NodeRSA({b: 2048});
|
* Creates a default admin users if one doesn't already exist in the database
|
||||||
key.generateKeyPair();
|
*
|
||||||
|
* @returns {Promise}
|
||||||
config_data.jwt = {
|
*/
|
||||||
key: key.exportKey('private').toString(),
|
const setupDefaultUser = () => {
|
||||||
pub: key.exportKey('public').toString()
|
return userModel
|
||||||
};
|
|
||||||
|
|
||||||
// Write config
|
|
||||||
fs.writeFile(filename, JSON.stringify(config_data, null, 2), (err) => {
|
|
||||||
if (err) {
|
|
||||||
logger.error('Could not write JWT key pair to config file: ' + filename);
|
|
||||||
reject(err);
|
|
||||||
} else {
|
|
||||||
logger.info('Wrote JWT key pair to config file: ' + filename);
|
|
||||||
|
|
||||||
logger.warn('Restarting interface to apply new configuration');
|
|
||||||
process.exit(0);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// JWT key pair exists
|
|
||||||
if (debug_mode) {
|
|
||||||
logger.debug('JWT Keypair already exists');
|
|
||||||
}
|
|
||||||
|
|
||||||
resolve();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function setupDefaultUser() {
|
|
||||||
(userModel
|
|
||||||
.query()
|
.query()
|
||||||
.select(userModel.raw('COUNT(`id`) as `count`'))
|
.select(userModel.raw('COUNT(`id`) as `count`'))
|
||||||
.where('is_deleted', 0)
|
.where('is_deleted', 0)
|
||||||
.first()
|
.first()
|
||||||
).then( (row) => {
|
.then((row) => {
|
||||||
if (!row.count) {
|
if (!row.count) {
|
||||||
// Create a new user and set password
|
// Create a new user and set password
|
||||||
logger.info('Creating a new user: admin@example.com with password: changeme');
|
logger.info('Creating a new user: admin@example.com with password: changeme');
|
||||||
|
|
||||||
let data = {
|
let data = {
|
||||||
is_deleted: 0,
|
is_deleted: 0,
|
||||||
email: 'admin@example.com',
|
email: 'admin@example.com',
|
||||||
name: 'Administrator',
|
name: 'Administrator',
|
||||||
nickname: 'Admin',
|
nickname: 'Admin',
|
||||||
avatar: '',
|
avatar: '',
|
||||||
roles: ['admin']
|
roles: ['admin'],
|
||||||
};
|
};
|
||||||
|
|
||||||
return userModel
|
return userModel
|
||||||
.query()
|
.query()
|
||||||
.insertAndFetch(data)
|
.insertAndFetch(data)
|
||||||
.then( (user) => {
|
.then((user) => {
|
||||||
return authModel
|
return authModel
|
||||||
.query()
|
.query()
|
||||||
.insert({
|
.insert({
|
||||||
user_id: user.id,
|
user_id: user.id,
|
||||||
type: 'password',
|
type: 'password',
|
||||||
secret: 'changeme',
|
secret: 'changeme',
|
||||||
meta: {}
|
meta: {},
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
return userPermissionModel
|
return userPermissionModel.query().insert({
|
||||||
.query()
|
|
||||||
.insert({
|
|
||||||
user_id: user.id,
|
user_id: user.id,
|
||||||
visibility: 'all',
|
visibility: 'all',
|
||||||
proxy_hosts: 'manage',
|
proxy_hosts: 'manage',
|
||||||
@ -101,25 +110,31 @@ function setupDefaultUser() {
|
|||||||
dead_hosts: 'manage',
|
dead_hosts: 'manage',
|
||||||
streams: 'manage',
|
streams: 'manage',
|
||||||
access_lists: 'manage',
|
access_lists: 'manage',
|
||||||
certificates: 'manage'
|
certificates: 'manage',
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
logger.info('Initial admin setup completed');
|
logger.info('Initial admin setup completed');
|
||||||
});
|
});
|
||||||
} else if (debug_mode) {
|
} else if (debug_mode) {
|
||||||
logger.debug('Admin user setup not required');
|
logger.debug('Admin user setup not required');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
function setupDefaultSettings() {
|
/**
|
||||||
|
* Creates default settings if they don't already exist in the database
|
||||||
|
*
|
||||||
|
* @returns {Promise}
|
||||||
|
*/
|
||||||
|
const setupDefaultSettings = () => {
|
||||||
return settingModel
|
return settingModel
|
||||||
.query()
|
.query()
|
||||||
.select(userModel.raw('COUNT(`id`) as `count`'))
|
.select(settingModel.raw('COUNT(`id`) as `count`'))
|
||||||
|
.where({id: 'default-site'})
|
||||||
.first()
|
.first()
|
||||||
.then( (row) => {
|
.then((row) => {
|
||||||
if (!row.count) {
|
if (!row.count) {
|
||||||
settingModel
|
settingModel
|
||||||
.query()
|
.query()
|
||||||
@ -128,22 +143,20 @@ function setupDefaultSettings() {
|
|||||||
name: 'Default Site',
|
name: 'Default Site',
|
||||||
description: 'What to show when Nginx is hit with an unknown Host',
|
description: 'What to show when Nginx is hit with an unknown Host',
|
||||||
value: 'congratulations',
|
value: 'congratulations',
|
||||||
meta: {}
|
meta: {},
|
||||||
}).then(() => {
|
})
|
||||||
|
.then(() => {
|
||||||
logger.info('Default settings added');
|
logger.info('Default settings added');
|
||||||
});
|
});
|
||||||
} if (debug_mode) {
|
}
|
||||||
|
if (debug_mode) {
|
||||||
logger.debug('Default setting setup not required');
|
logger.debug('Default setting setup not required');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
module.exports = function () {
|
module.exports = function () {
|
||||||
return new Promise((resolve, reject) => {
|
return setupJwt()
|
||||||
return setupJwt(resolve, reject);
|
.then(setupDefaultUser)
|
||||||
}).then(() => {
|
.then(setupDefaultSettings);
|
||||||
return setupDefaultUser();
|
|
||||||
}).then(() => {
|
|
||||||
return setupDefaultSettings();
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
@ -2,14 +2,14 @@
|
|||||||
version: "3"
|
version: "3"
|
||||||
services:
|
services:
|
||||||
|
|
||||||
fullstack:
|
fullstack-mysql:
|
||||||
image: ${IMAGE}:ci-${BUILD_NUMBER}
|
image: ${IMAGE}:ci-${BUILD_NUMBER}
|
||||||
environment:
|
environment:
|
||||||
- NODE_ENV=development
|
- NODE_ENV=development
|
||||||
- FORCE_COLOR=1
|
- FORCE_COLOR=1
|
||||||
volumes:
|
volumes:
|
||||||
- npm_data:/data
|
- npm_data:/data
|
||||||
- ../.jenkins/config.json:/app/config/production.json
|
- ../.jenkins/config-mysql.json:/app/config/production.json
|
||||||
expose:
|
expose:
|
||||||
- 81
|
- 81
|
||||||
- 80
|
- 80
|
||||||
@ -17,6 +17,19 @@ services:
|
|||||||
depends_on:
|
depends_on:
|
||||||
- db
|
- db
|
||||||
|
|
||||||
|
fullstack-sqlite:
|
||||||
|
image: ${IMAGE}:ci-${BUILD_NUMBER}
|
||||||
|
environment:
|
||||||
|
- NODE_ENV=development
|
||||||
|
- FORCE_COLOR=1
|
||||||
|
volumes:
|
||||||
|
- npm_data:/data
|
||||||
|
- ../.jenkins/config-sqlite.json:/app/config/production.json
|
||||||
|
expose:
|
||||||
|
- 81
|
||||||
|
- 80
|
||||||
|
- 443
|
||||||
|
|
||||||
db:
|
db:
|
||||||
image: jc21/mariadb-aria
|
image: jc21/mariadb-aria
|
||||||
environment:
|
environment:
|
||||||
|
Loading…
Reference in New Issue
Block a user