Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for using shell env variables in config.json #59

Merged
merged 5 commits into from
Nov 22, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions cloudrun-malware-scanner/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
gnupg \
jq \
gawk \
gettext-base \
clamav-daemon \
clamav-freshclam \
python3-crcmod && \
Expand Down
9 changes: 7 additions & 2 deletions cloudrun-malware-scanner/bootstrap.sh
Original file line number Diff line number Diff line change
Expand Up @@ -64,13 +64,18 @@ done &
service clamav-daemon stop &
service clamav-freshclam stop &

# Get name of CVD Mirror bucket from config file.
# Check and perform shell-varable substitution on config file, copying it to /etc
#
CONFIG_FILE=./config.json
if [[ ! -e "${CONFIG_FILE}" ]] ; then
Log ERROR main "${CONFIG_FILE} does not exist"
exit 1
fi
envsubst < "${CONFIG_FILE}" > /etc/malware-scanner-config.json
CONFIG_FILE=/etc/malware-scanner-config.json

# Get name of CVD Mirror bucket from config file
#
CVD_MIRROR_BUCKET=$(/usr/bin/jq -r '.ClamCvdMirrorBucket' "${CONFIG_FILE}")
if [[ -z "${CVD_MIRROR_BUCKET}" || "${CVD_MIRROR_BUCKET}" = "null" ]] ; then
Log ERROR main "ClamCvdMirrorBucket is not defined in ${CONFIG_FILE}"
Expand Down Expand Up @@ -164,4 +169,4 @@ service clamav-freshclam force-reload &

# Run node server process
Log INFO main "Starting malware-scanner service"
npm start
npm start "${CONFIG_FILE}"
3 changes: 3 additions & 0 deletions cloudrun-malware-scanner/config.json.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
"",
"'ClamCvdMirrorBucket' is a GCS bucket used to mirror the clamav database definition files to prevent overloading the Clam servers",
"and being rate limited/blacklisted. Its contents are maintained by the updateCvdMirror.sh script"
"",
"Shell environmental variable substitution is supported in this file.",
"At runtime, it will be copied to /etc"
],
"buckets": [
{
Expand Down
4 changes: 2 additions & 2 deletions cloudrun-malware-scanner/logger.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ const pkgJson = require('./package.json');
const loggingBunyan = new LoggingBunyan({
redirectToStdout: true,
projectId: process.env.PROJECT_ID,
logName: "malware-scanner",
useMessageField: false
logName: 'malware-scanner',
useMessageField: false,
});

exports.logger = bunyan.createLogger({
Expand Down
29 changes: 15 additions & 14 deletions cloudrun-malware-scanner/metrics.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,21 +98,21 @@ function writeScanCompletedMetric_(measure, sourceBucket, destinationBucket,

/**
* Writes metrics when a CVD Mirror Update occurs.
*
*
* @param {boolean} success
* @param {boolean} isUpdated
*/
function writeCvdMirrorUpdatedMetric(success, isUpdated) {
function writeCvdMirrorUpdatedMetric(success, isUpdated) {
const tags = new TagMap();
tags.set(TAGS.cloudRunRevision, {value: process.env.K_REVISION});
tags.set(TAGS.cvdUpdateStatus,
{value: (
tags.set(TAGS.cvdUpdateStatus,
{value: (
success ? (
isUpdated ? "SUCCESS_UPDATED" : "SUCCESS_NO_UPDATES" )
: "FAILURE" )});
isUpdated ? 'SUCCESS_UPDATED' : 'SUCCESS_NO_UPDATES' ) :
'FAILURE' )});
globalStats.record(
[{ measure: METRICS.cvdUpdates, value: 1}],
tags);
[{measure: METRICS.cvdUpdates, value: 1}],
tags);
}

/**
Expand All @@ -134,8 +134,8 @@ async function initMetrics(projectId) {
TAGS.clamVersion,
TAGS.cloudRunRevision,
TAGS.sourceBucket,
TAGS.destinationBucket
]
TAGS.destinationBucket,
];

METRICS.cleanFiles = globalStats.createMeasureInt64(
METRIC_TYPE_ROOT + 'clean-files', MeasureUnit.UNIT,
Expand Down Expand Up @@ -183,7 +183,8 @@ async function initMetrics(projectId) {
'The scan duration in milliseconds');
const scanDurationView = globalStats.createView(
METRICS.scanDuration.name, METRICS.scanDuration,
AggregationType.DISTRIBUTION, fileScanTags, 'Duration spent scanning files',
AggregationType.DISTRIBUTION, fileScanTags,
'Duration spent scanning files',
// Bucket Boundaries in ms
[
0,
Expand All @@ -203,12 +204,12 @@ async function initMetrics(projectId) {
globalStats.registerView(scanDurationView);

METRICS.cvdUpdates = globalStats.createMeasureInt64(
METRIC_TYPE_ROOT + 'cvd-mirror-updates', MeasureUnit.UNIT,
'Number of CVD mirror Update Checks performed');
METRIC_TYPE_ROOT + 'cvd-mirror-updates', MeasureUnit.UNIT,
'Number of CVD mirror Update Checks performed');

const cvdUpdatesView = globalStats.createView(
METRICS.cvdUpdates.name, METRICS.cvdUpdates,
AggregationType.COUNT,
AggregationType.COUNT,
[TAGS.cloudRunRevision, TAGS.cvdUpdateStatus],
'Number of CVD mirror update checks performed with their status');
globalStats.registerView(cvdUpdatesView);
Expand Down
32 changes: 20 additions & 12 deletions cloudrun-malware-scanner/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
const clamd = require('clamdjs');
const express = require('express');
const {Storage} = require('@google-cloud/storage');
const {ApiError} = require('@google-cloud/common');
const {GoogleAuth} = require('google-auth-library');
const {logger} = require('./logger.js');
const pkgJson = require('./package.json');
Expand All @@ -44,12 +43,10 @@ const CLAMD_TIMEOUT = 600000;
// large enough.
const MAX_FILE_SIZE = 500000000; // 500MiB

const CONFIG_FILE = './config.json';

/**
* Configuration object.
*
* Values are read from the CONFIG_FILE
* Values are read from the JSON configuration file.
* See {@link readAndVerifyConfig}.
*
* @type {{
Expand Down Expand Up @@ -321,25 +318,28 @@ async function moveProcessedFile(filename, isClean, config) {
}

/**
* Read configuration from CONFIG_FILE
* Read configuration from JSON configuration file.
* and store in BUCKET_CONFIG global
*
* @async
* @param {string} configFile
*/
async function readAndVerifyConfig() {
async function readAndVerifyConfig(configFile) {
logger.info(`Using configuration file: ${configFile}`);

try {
const config = require(CONFIG_FILE);
const config = require(configFile);
delete config.comments;
Object.assign(BUCKET_CONFIG, config);
} catch (e) {
logger.fatal(
{err: e},
`Unable to read JSON file from ${CONFIG_FILE}`);
throw new Error(`Invalid configuration ${CONFIG_FILE}`);
`Unable to read JSON file from ${configFile}`);
throw new Error(`Invalid configuration ${configFile}`);
}

if (BUCKET_CONFIG.buckets.length === 0) {
logger.fatal(`No buckets configured for scanning in ${CONFIG_FILE}`);
logger.fatal(`No buckets configured for scanning in ${configFile}`);
throw new Error('No buckets configured');
}

Expand All @@ -360,7 +360,7 @@ async function readAndVerifyConfig() {
config.unscanned === config.quarantined ||
config.clean === config.quarantined) {
logger.fatal(
`Error in ${CONFIG_FILE} buckets[${x}]: bucket names are not unique`);
`Error in ${configFile} buckets[${x}]: bucket names are not unique`);
success = false;
}
}
Expand Down Expand Up @@ -440,7 +440,15 @@ async function run() {
projectId = await (new GoogleAuth().getProjectId());
}
await metrics.init(projectId);
await readAndVerifyConfig();

let configFile;
if (process.argv.length >= 3) {
configFile = process.argv[2];
} else {
configFile = './config.json';
}
await readAndVerifyConfig(configFile);

await waitForClamD();

app.listen(PORT, () => {
Expand Down