Skip to content

Commit

Permalink
feat(connection-test): Add command to test connection to Sense server
Browse files Browse the repository at this point in the history
Implements #328
  • Loading branch information
Göran Sander committed Oct 26, 2023
1 parent 1bddb6a commit 328886e
Show file tree
Hide file tree
Showing 4 changed files with 169 additions and 44 deletions.
102 changes: 59 additions & 43 deletions .vscode/launch.json
Expand Up @@ -220,49 +220,49 @@
// // "--dry-run"
// ]

// ------------------------------------
// Get task tree
// ------------------------------------
"args": [
"task-get",
// "--auth-type",
// "cert",
"--host",
"192.168.100.109",
// "--auth-cert-file",
// "./cert/client.pem",
// "--auth-cert-key-file",
// "./cert/client_key.pem",
"--auth-user-dir",
"LAB",
"--auth-user-id",
"goran",
// "--task-id",
// "82bc3e66-c899-4e44-b52f-552145da5ee0",
// "--task-tag",
// "Test data",
"--output-format",
// "table",
"tree",
"--tree-icons",
"--tree-details",
// "taskid",
// "appname",
"--task-type",
// "reload",
"ext-program"

// "--output-dest",
// "screen",
// "file",
// "--output-file-name",
// "tasks.json",
// "--output-file-format",
// "json",

// "--text-color",
// "no",
]
// // ------------------------------------
// // Get task tree
// // ------------------------------------
// "args": [
// "task-get",
// // "--auth-type",
// // "cert",
// "--host",
// "192.168.100.109",
// // "--auth-cert-file",
// // "./cert/client.pem",
// // "--auth-cert-key-file",
// // "./cert/client_key.pem",
// "--auth-user-dir",
// "LAB",
// "--auth-user-id",
// "goran",
// // "--task-id",
// // "82bc3e66-c899-4e44-b52f-552145da5ee0",
// // "--task-tag",
// // "Test data",
// "--output-format",
// // "table",
// "tree",
// "--tree-icons",
// "--tree-details",
// // "taskid",
// // "appname",
// "--task-type",
// // "reload",
// "ext-program"

// // "--output-dest",
// // "screen",
// // "file",
// // "--output-file-name",
// // "tasks.json",
// // "--output-file-format",
// // "json",

// // "--text-color",
// // "no",
// ]

// ------------------------------------
// Get reload tasks as table
Expand Down Expand Up @@ -767,6 +767,22 @@
// "--log-level",
// "verbose"
// ]

// ------------------------------------
// Connection test
// ------------------------------------
"args": [
"connection-test",
"--host",
"192.168.100.109",
"--auth-user-dir",
"LAB",
"--auth-user-id",
"goran",
"--log-level",
"info"
]

}
]
}
31 changes: 30 additions & 1 deletion src/ctrl-q.js
Expand Up @@ -26,6 +26,7 @@ const { setTaskCustomProperty } = require('./lib/cmd/settaskcp');
const { importTaskFromFile } = require('./lib/cmd/importtask');
const { importAppFromFile } = require('./lib/cmd/importapp');
const { exportAppToFile } = require('./lib/cmd/exportapp');
const { testConnection } = require('./lib/cmd/testconnection');

const {
sharedParamAssertOptions,
Expand Down Expand Up @@ -549,7 +550,7 @@ const program = new Command();
.option('--auth-root-cert-file <file>', 'Qlik Sense root certificate file (exported from QMC)', './cert/root.pem')

.addOption(
new Option('--task-type <type...>', 'type of tasks to list')
new Option('--task-type <type...>', 'type of tasks to include')
.choices(['reload', 'ext-program'])
.default(['reload', 'ext-program'])
)
Expand Down Expand Up @@ -788,6 +789,34 @@ const program = new Command();

.option('--dry-run', 'do a dry run, i.e. do not export any apps - just show what would be done');

// Test connection command
program
.command('connection-test')
.description('test connection to Qlik Sense server')
.action(async (options) => {
try {
await sharedParamAssertOptions(options);
testConnection(options);
} catch (err) {
logger.error(`CONNECTION TEST: ${err}`);
}
})
.addOption(
new Option('--log-level <level>', 'log level').choices(['error', 'warn', 'info', 'verbose', 'debug', 'silly']).default('info')
)
.requiredOption('--host <host>', 'Qlik Sense server IP/FQDN')
.option('--port <port>', 'Qlik Sense server engine port', '4242')
.option('--schema-version <string>', 'Qlik Sense engine schema version', '12.612.0')
.requiredOption('--virtual-proxy <prefix>', 'Qlik Sense virtual proxy prefix', '')
.requiredOption('--secure <true|false>', 'connection to Qlik Sense engine is via https', true)
.requiredOption('--auth-user-dir <directory>', 'user directory for user to connect with')
.requiredOption('--auth-user-id <userid>', 'user ID for user to connect with')

.addOption(new Option('-a, --auth-type <type>', 'authentication type').choices(['cert']).default('cert'))
.option('--auth-cert-file <file>', 'Qlik Sense certificate file (exported from QMC)', './cert/client.pem')
.option('--auth-cert-key-file <file>', 'Qlik Sense certificate key file (exported from QMC)', './cert/client_key.pem')
.option('--auth-root-cert-file <file>', 'Qlik Sense root certificate file (exported from QMC)', './cert/root.pem');

// Parse command line params
await program.parseAsync(process.argv);
})();
33 changes: 33 additions & 0 deletions src/lib/cmd/testconnection.js
@@ -0,0 +1,33 @@
const { logger, setLoggingLevel, isPkg, execPath } = require('../../globals');
const { getAboutFromQseow } = require('../util/about');

const testConnection = async (options) => {
try {
// Set log level
setLoggingLevel(options.logLevel);

logger.verbose(`Ctrl-Q was started as a stand-alone binary: ${isPkg}`);
logger.verbose(`Ctrl-Q was started from ${execPath}`);

logger.info(`Testing connection to Qlik Sense server ${options.host} on port ${options.port}`);
logger.debug(`Options: ${JSON.stringify(options, null, 2)}`);

const aboutInfo = await getAboutFromQseow(options);

if (!aboutInfo) {
logger.error(`Could not get about info from QSEoW`);
return false;
}

logger.info(`Successfully connected to Qlik Sense server ${options.host} on port ${options.port}`);
logger.info(`Qlik Sense build version: ${aboutInfo.buildVersion}`);
logger.info(`Qlik Sense build date: ${aboutInfo.buildDate}`);
return true;
} catch (err) {
logger.error(`EXPORT APP: ${err.stack}`);
}
};

module.exports = {
testConnection,
};
47 changes: 47 additions & 0 deletions src/lib/util/about.js
@@ -0,0 +1,47 @@
const axios = require('axios');
const path = require('path');

const { logger, execPath } = require('../../globals');
const { setupQRSConnection } = require('./qrs');

function getAboutFromQseow(options) {
return new Promise((resolve, reject) => {
logger.verbose(`Getting about info from QSEoW...`);

// Make sure certificates exist
const fileCert = path.resolve(execPath, options.authCertFile);
const fileCertKey = path.resolve(execPath, options.authCertKeyFile);

const axiosConfig = setupQRSConnection(options, {
method: 'get',
fileCert,
fileCertKey,
path: '/qrs/about',
// headers: {
// 'Accept': 'application/json',
// 'Content-Type': 'application/json; charset=utf-8',
// },
});

logger.debug(`About to get about info from QSEoW`);

axios
.request(axiosConfig)
.then((result) => {
if (result.status === 200) {
const response = JSON.parse(result.data);
logger.debug(`Successfully retrieved about info from QSEoW`);
// Yes, the tag exists
resolve(response);
}
resolve(false);
})
.catch((err) => {
logger.error(`GET ABOUT INFO: ${err}`);
});
});
}

module.exports = {
getAboutFromQseow,
};

0 comments on commit 328886e

Please sign in to comment.