Add a simple license validation argument to the C++ processes (elastic/elasticsearch#339)

NOT the controller process, as this cannot take arguments when
started as a daemon by Elasticsearch

Closes elastic/elasticsearch#253

Original commit: elastic/x-pack-elasticsearch@14ea155caa
This commit is contained in:
David Roberts 2016-11-21 11:26:10 +00:00 committed by GitHub
parent b11f238791
commit f9dde66678
2 changed files with 41 additions and 10 deletions

View File

@ -6,11 +6,13 @@
package org.elasticsearch.xpack.prelert.job.process;
import org.apache.logging.log4j.Logger;
import org.elasticsearch.common.Randomness;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.settings.Setting;
import org.elasticsearch.common.settings.Setting.Property;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.env.Environment;
import org.elasticsearch.monitor.jvm.JvmInfo;
import org.elasticsearch.xpack.prelert.PrelertPlugin;
import org.elasticsearch.xpack.prelert.job.AnalysisConfig;
import org.elasticsearch.xpack.prelert.job.DataDescription;
@ -60,14 +62,16 @@ public class ProcessCtrl {
public static final Setting<Integer> MAX_ANOMALY_RECORDS_SETTING = Setting.intSetting("max.anomaly.records", DEFAULT_MAX_NUM_RECORDS,
Property.NodeScope);
// TODO: remove once the C++ logger no longer needs it
static final String LOG_ID_ARG = "--logid=";
/**
* This must match the value defined in CLicenseValidator::validate() in the C++ code
*/
static final long VALIDATION_NUMBER = 926213;
/*
* General arguments
*/
static final String JOB_ID_ARG = "--jobid=";
static final String LICENSE_VALIDATION_ARG = "--licenseValidation=";
/*
* Arguments used by both prelert_autodetect and prelert_normalize
@ -156,9 +160,7 @@ public class ProcessCtrl {
String jobId = JOB_ID_ARG + job.getId();
command.add(jobId);
// the logging id is the job id
String logId = LOG_ID_ARG + job.getId();
command.add(logId);
command.add(makeLicenseArg());
AnalysisConfig analysisConfig = job.getAnalysisConfig();
if (analysisConfig != null) {
@ -256,13 +258,13 @@ public class ProcessCtrl {
/**
* Build the command to start the normalizer process.
*/
public static List<String> buildNormaliserCommand(Environment env, String jobId, String quantilesState, Integer bucketSpan,
public static List<String> buildNormaliserCommand(Environment env, String jobId, String quantilesState, Integer bucketSpan,
boolean perPartitionNormalization, Logger logger) throws IOException {
List<String> command = new ArrayList<>();
command.add(NORMALIZE_PATH);
addIfNotNull(bucketSpan, BUCKET_SPAN_ARG, command);
command.add(LOG_ID_ARG + jobId);
command.add(makeLicenseArg());
command.add(LENGTH_ENCODED_INPUT_ARG);
if (perPartitionNormalization) {
command.add(PER_PARTITION_NORMALIZATION);
@ -301,4 +303,14 @@ public class ProcessCtrl {
return stateFile;
}
/**
* The number must be equal to the JVM PID modulo a magic number.
*/
private static String makeLicenseArg() {
// Get a random int rather than long so we don't overflow when multiplying by VALIDATION_NUMBER
long rand = Randomness.get().nextInt();
long val = JvmInfo.jvmInfo().pid() + (((rand < 0) ? -rand : rand) + 1) * VALIDATION_NUMBER;
return LICENSE_VALIDATION_ARG + val;
}
}

View File

@ -8,6 +8,7 @@ package org.elasticsearch.xpack.prelert.job.process;
import org.apache.logging.log4j.Logger;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.env.Environment;
import org.elasticsearch.monitor.jvm.JvmInfo;
import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.xpack.prelert.job.AnalysisConfig;
import org.elasticsearch.xpack.prelert.job.DataDescription;
@ -72,7 +73,7 @@ public class ProcessCtrlTests extends ESTestCase {
assertTrue(command.contains(ProcessCtrl.maxAnomalyRecordsArg(settings)));
assertTrue(command.contains(ProcessCtrl.TIME_FIELD_ARG + "tf"));
assertTrue(command.contains(ProcessCtrl.LOG_ID_ARG + "unit-test-job"));
assertTrue(hasValidLicense(command));
assertTrue(command.contains(ProcessCtrl.JOB_ID_ARG + "unit-test-job"));
assertTrue(command.contains(ProcessCtrl.PER_PARTITION_NORMALIZATION));
@ -143,8 +144,26 @@ public class ProcessCtrlTests extends ESTestCase {
assertEquals(5, command.size());
assertTrue(command.contains(ProcessCtrl.NORMALIZE_PATH));
assertTrue(command.contains(ProcessCtrl.BUCKET_SPAN_ARG + "300"));
assertTrue(command.contains(ProcessCtrl.LOG_ID_ARG + jobId));
assertTrue(hasValidLicense(command));
assertTrue(command.contains(ProcessCtrl.LENGTH_ENCODED_INPUT_ARG));
assertTrue(command.contains(ProcessCtrl.PER_PARTITION_NORMALIZATION));
}
private boolean hasValidLicense(List<String> command) throws NumberFormatException {
int matches = 0;
for (String arg : command) {
if (arg.startsWith(ProcessCtrl.LICENSE_VALIDATION_ARG)) {
++matches;
String[] argAndVal = arg.split("=");
if (argAndVal.length != 2) {
return false;
}
long val = Long.parseLong(argAndVal[1]);
if ((val % ProcessCtrl.VALIDATION_NUMBER) != (JvmInfo.jvmInfo().pid() % ProcessCtrl.VALIDATION_NUMBER)) {
return false;
}
}
}
return matches == 1;
}
}