Tests & cleanup:

- transport & service test (remove license functionality)
 - nuked LicenseException class
 - keyPairGenerator tests
 - minor cleanup & restructuring

Original commit: elastic/x-pack-elasticsearch@51acb2f493
This commit is contained in:
Areek Zillur 2014-11-06 19:16:38 -05:00
parent bb929c7470
commit d8d241b4bb
11 changed files with 244 additions and 66 deletions

View File

@ -53,7 +53,6 @@ public class ESLicenseSigner {
try {
return Files.readAllBytes(privateKeyPath);
} catch (IOException e) {
e.printStackTrace();
throw new IllegalStateException(e);
}

View File

@ -28,7 +28,8 @@ import static org.elasticsearch.common.cli.CliToolConfig.config;
public class KeyPairGeneratorTool extends CliTool {
private static final CliToolConfig CONFIG = config("key-pair-generator", KeyPairGeneratorTool.class)
public static final String NAME = "key-pair-generator";
private static final CliToolConfig CONFIG = config(NAME, KeyPairGeneratorTool.class)
.cmds(KeyPairGenerator.CMD)
.build();
@ -41,18 +42,18 @@ public class KeyPairGeneratorTool extends CliTool {
return KeyPairGenerator.parse(terminal, commandLine);
}
private static class KeyPairGenerator extends Command {
public static class KeyPairGenerator extends Command {
public static final String DEFAULT_PASS_PHRASE = "elasticsearch-license";
private static final String NAME = "key-pair-generator";
private static final CliToolConfig.Cmd CMD = cmd(NAME, KeyPairGenerator.class)
.options(
option("pub", "publicKeyPath").required(true).hasArg(true),
option("pri", "privateKeyPath").required(true).hasArg(true)
).build();
private final String publicKeyPath;
private final String privateKeyPath;
public final String publicKeyPath;
public final String privateKeyPath;
protected KeyPairGenerator(Terminal terminal, String publicKeyPath, String privateKeyPath) {
super(terminal);

View File

@ -50,7 +50,6 @@ public class TransportDeleteLicenseAction extends TransportMasterNodeOperationAc
@Override
protected ClusterBlockException checkBlock(DeleteLicenseRequest request, ClusterState state) {
//TODO: do the right checkBlock
return state.blocks().indexBlockedException(ClusterBlockLevel.METADATA, "");
}

View File

@ -37,6 +37,11 @@ public class PutLicenseRequestBuilder extends AcknowledgedRequestBuilder<PutLice
return this;
}
public PutLicenseRequestBuilder setLicense(String licenseSource) {
request.licenses(licenseSource);
return this;
}
@Override
protected void doExecute(ActionListener<PutLicenseResponse> listener) {
client.execute(PutLicenseAction.INSTANCE, request, listener);

View File

@ -1,22 +0,0 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.license.plugin.core;
import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.transport.RemoteTransportException;
public class ElasticsearchLicenseException extends RemoteTransportException {
public ElasticsearchLicenseException(String msg) {
super(msg, null);
}
@Override
public RestStatus status() {
return RestStatus.BAD_REQUEST;
}
}

View File

@ -5,13 +5,14 @@
*/
package org.elasticsearch.license;
import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.license.core.ESLicense;
import org.elasticsearch.license.core.ESLicenses;
import java.util.Collection;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.*;
import static org.hamcrest.core.IsEqual.equalTo;
import static org.junit.Assert.assertThat;
@ -50,4 +51,11 @@ public class TestUtils {
assertThat(license1.issueDate(), equalTo(license2.issueDate()));
assertThat(license1.maxNodes(), equalTo(license2.maxNodes()));
}
public static String dumpLicense(ESLicense license) throws Exception {
XContentBuilder builder = XContentFactory.contentBuilder(XContentType.JSON);
ESLicenses.toXContent(Collections.singletonList(license), builder, ToXContent.EMPTY_PARAMS);
builder.flush();
return builder.string();
}
}

View File

@ -0,0 +1,103 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.license.licensor.tools;
import org.elasticsearch.common.cli.CliToolTestCase;
import org.elasticsearch.common.cli.commons.MissingOptionException;
import org.elasticsearch.common.settings.ImmutableSettings;
import org.elasticsearch.env.Environment;
import org.elasticsearch.license.licensor.tools.KeyPairGeneratorTool.KeyPairGenerator;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import java.io.File;
import java.nio.file.Paths;
import static org.elasticsearch.common.cli.CliTool.Command;
import static org.elasticsearch.common.cli.CliTool.ExitStatus;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.instanceOf;
import static org.hamcrest.core.IsEqual.equalTo;
public class KeyPairGenerationToolTests extends CliToolTestCase {
@Rule
public TemporaryFolder temporaryFolder = new TemporaryFolder();
@Test
public void testParsingMissingPath() throws Exception {
KeyPairGeneratorTool keyPairGeneratorTool = new KeyPairGeneratorTool();
File tempFile = temporaryFolder.newFile();
try {
keyPairGeneratorTool.parse(KeyPairGeneratorTool.NAME, args(
"--privateKeyPath " + tempFile.getAbsolutePath()));
fail("no public key path provided");
} catch (MissingOptionException e) {
assertThat(e.getMessage(), containsString("pub"));
}
try {
keyPairGeneratorTool.parse(KeyPairGeneratorTool.NAME, args(
"--publicKeyPath " + tempFile.getAbsolutePath()));
fail("no private key path provided");
} catch (MissingOptionException e) {
assertThat(e.getMessage(), containsString("pri"));
}
}
@Test
public void testParsingNeverOverrideKey() throws Exception {
KeyPairGeneratorTool keyPairGeneratorTool = new KeyPairGeneratorTool();
File tempFile = temporaryFolder.newFile();
File tempFile2 = temporaryFolder.newFile();
String nonExistentFilePath = tempFile2.getAbsolutePath();
assertThat(tempFile2.delete(), equalTo(true));
Command command = keyPairGeneratorTool.parse(KeyPairGeneratorTool.NAME, args("--privateKeyPath " + tempFile.getAbsolutePath()
+ " --publicKeyPath " + nonExistentFilePath));
assertThat(command, instanceOf(Command.Exit.class));
Command.Exit exitCommand = (Command.Exit) command;
assertThat(exitCommand.status(), equalTo(ExitStatus.USAGE));
command = keyPairGeneratorTool.parse(KeyPairGeneratorTool.NAME, args("--publicKeyPath " + tempFile.getAbsolutePath()
+ " --privateKeyPath " + nonExistentFilePath));
assertThat(command, instanceOf(Command.Exit.class));
exitCommand = (Command.Exit) command;
assertThat(exitCommand.status(), equalTo(ExitStatus.USAGE));
}
@Test
public void testToolSimple() throws Exception {
KeyPairGeneratorTool keyPairGeneratorTool = new KeyPairGeneratorTool();
File tempFile1 = temporaryFolder.newFile();
File tempFile2 = temporaryFolder.newFile();
String publicKeyPath = tempFile1.getAbsolutePath();
String privateKeyPath = tempFile2.getAbsolutePath();
assertThat(tempFile1.delete(), equalTo(true));
assertThat(tempFile2.delete(), equalTo(true));
Command command = keyPairGeneratorTool.parse(KeyPairGeneratorTool.NAME, args("--privateKeyPath " + privateKeyPath
+ " --publicKeyPath " + publicKeyPath));
assertThat(command, instanceOf(KeyPairGenerator.class));
KeyPairGenerator keyPairGenerator = (KeyPairGenerator) command;
assertThat(keyPairGenerator.privateKeyPath, equalTo(privateKeyPath));
assertThat(keyPairGenerator.publicKeyPath, equalTo(publicKeyPath));
assertThat(Paths.get(publicKeyPath).toFile().exists(), equalTo(false));
assertThat(Paths.get(privateKeyPath).toFile().exists(), equalTo(false));
assertThat(keyPairGenerator.execute(ImmutableSettings.EMPTY, new Environment(ImmutableSettings.EMPTY)), equalTo(ExitStatus.OK));
assertThat(Paths.get(publicKeyPath).toFile().exists(), equalTo(true));
assertThat(Paths.get(privateKeyPath).toFile().exists(), equalTo(true));
assertThat(Paths.get(publicKeyPath).toFile().delete(), equalTo(true));
assertThat(Paths.get(privateKeyPath).toFile().delete(), equalTo(true));
}
}

View File

@ -3,7 +3,7 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.license.licensor;
package org.elasticsearch.license.licensor.tools;
import org.apache.commons.io.FileUtils;
import org.elasticsearch.common.cli.CliTool;
@ -52,15 +52,23 @@ public class LicenseGenerationToolTests extends CliToolTestCase {
public void testParsingNonExistentKeyFile() throws Exception {
LicenseSpec inputLicenseSpec = generateRandomLicenseSpec();
LicenseGeneratorTool licenseGeneratorTool = new LicenseGeneratorTool();
boolean invalidPubKeyPath = randomBoolean();
Command command = licenseGeneratorTool.parse(LicenseGeneratorTool.NAME,
args("--license " + generateESLicenseSpecString(Arrays.asList(inputLicenseSpec))
+ " --publicKeyPath " + ((invalidPubKeyPath) ? pubKeyPath.concat("invalid") : pubKeyPath)
+ " --privateKeyPath " + ((!invalidPubKeyPath) ? priKeyPath.concat("invalid") : priKeyPath)));
+ " --publicKeyPath " + pubKeyPath.concat("invalid")
+ " --privateKeyPath " + priKeyPath));
assertThat(command, instanceOf(Command.Exit.class));
Command.Exit exitCommand = (Command.Exit) command;
assertThat(exitCommand.status(), equalTo(ExitStatus.USAGE));
command = licenseGeneratorTool.parse(LicenseGeneratorTool.NAME,
args("--license " + generateESLicenseSpecString(Arrays.asList(inputLicenseSpec))
+ " --privateKeyPath " + priKeyPath.concat("invalid")
+ " --publicKeyPath " + pubKeyPath));
assertThat(command, instanceOf(Command.Exit.class));
exitCommand = (Command.Exit) command;
assertThat(exitCommand.status(), equalTo(ExitStatus.USAGE));
}
@Test

View File

@ -3,17 +3,13 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.license.licensor;
package org.elasticsearch.license.licensor.tools;
import org.apache.commons.io.FileUtils;
import org.elasticsearch.common.cli.CliToolTestCase;
import org.elasticsearch.common.settings.ImmutableSettings;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.env.Environment;
import org.elasticsearch.license.TestUtils;
import org.elasticsearch.license.core.ESLicense;
@ -56,7 +52,7 @@ public class LicenseVerificationToolTests extends CliToolTestCase {
TimeValue.timeValueHours(1));
LicenseVerificationTool licenseVerificationTool = new LicenseVerificationTool();
Command command = licenseVerificationTool.parse(LicenseVerificationTool.NAME,
args("--license " + dumpLicense(inputLicense)));
args("--license " + TestUtils.dumpLicense(inputLicense)));
assertThat(command, instanceOf(LicenseVerifier.class));
LicenseVerifier licenseVerifier = (LicenseVerifier) command;
assertThat(licenseVerifier.licenses.size(), equalTo(1));
@ -93,7 +89,7 @@ public class LicenseVerificationToolTests extends CliToolTestCase {
StringBuilder argsBuilder = new StringBuilder();
for (ESLicense inputLicense : inputLicenses.values()) {
argsBuilder.append(" --license ")
.append(dumpLicense(inputLicense));
.append(TestUtils.dumpLicense(inputLicense));
}
LicenseVerificationTool licenseVerificationTool = new LicenseVerificationTool();
Command command = licenseVerificationTool.parse(LicenseVerificationTool.NAME, args(argsBuilder.toString()));
@ -144,19 +140,10 @@ public class LicenseVerificationToolTests extends CliToolTestCase {
private String dumpLicenseAsFile(ESLicense license) throws Exception {
File tempFile = temporaryFolder.newFile();
FileUtils.write(tempFile, dumpLicense(license));
FileUtils.write(tempFile, TestUtils.dumpLicense(license));
return tempFile.getAbsolutePath();
}
private String dumpLicense(ESLicense license) throws Exception {
XContentBuilder builder = XContentFactory.contentBuilder(XContentType.JSON);
ESLicenses.toXContent(Collections.singletonList(license), builder, ToXContent.EMPTY_PARAMS);
builder.flush();
return builder.string();
}
private String runLicenseVerificationTool(Set<ESLicense> licenses, ExitStatus expectedExitStatus) throws Exception {
CaptureOutputTerminal outputTerminal = new CaptureOutputTerminal();
LicenseVerifier licenseVerifier = new LicenseVerifier(outputTerminal, licenses);

View File

@ -11,10 +11,7 @@ import org.elasticsearch.license.core.ESLicense;
import org.junit.BeforeClass;
import org.junit.Test;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.*;
import static com.carrotsearch.randomizedtesting.RandomizedTest.randomIntBetween;
import static org.hamcrest.core.IsEqual.equalTo;

View File

@ -6,9 +6,14 @@
package org.elasticsearch.license.plugin;
import org.elasticsearch.action.ActionFuture;
import org.elasticsearch.common.collect.Sets;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.license.TestUtils;
import org.elasticsearch.license.core.ESLicense;
import org.elasticsearch.license.core.ESLicenses;
import org.elasticsearch.license.plugin.action.delete.DeleteLicenseRequest;
import org.elasticsearch.license.plugin.action.delete.DeleteLicenseRequestBuilder;
import org.elasticsearch.license.plugin.action.delete.DeleteLicenseResponse;
import org.elasticsearch.license.plugin.action.get.GetLicenseRequestBuilder;
import org.elasticsearch.license.plugin.action.get.GetLicenseResponse;
import org.elasticsearch.license.plugin.action.put.PutLicenseRequestBuilder;
@ -49,16 +54,38 @@ public class LicenseTransportTests extends AbstractLicensesIntegrationTests {
// put license
PutLicenseRequestBuilder putLicenseRequestBuilder = new PutLicenseRequestBuilder(client().admin().cluster())
.setLicense(actualLicenses);
PutLicenseResponse putLicenseResponse = putLicenseRequestBuilder.execute().get();
PutLicenseResponse putLicenseResponse = putLicenseRequestBuilder.get();
assertThat(putLicenseResponse.isAcknowledged(), equalTo(true));
assertThat(putLicenseResponse.status(), equalTo(LicensesStatus.VALID));
// get license
GetLicenseResponse getLicenseResponse = new GetLicenseRequestBuilder(client().admin().cluster()).get();
assertThat(getLicenseResponse.licenses(), notNullValue());
assertThat(getLicenseResponse.licenses().size(), equalTo(1));
// check license
TestUtils.isSame(actualLicenses, getLicenseResponse.licenses());
TestUtils.isSame(signedLicense, getLicenseResponse.licenses().get(0));
}
@Test
public void testPutLicenseFromString() throws Exception {
ESLicense signedLicense = generateSignedLicense("shield", TimeValue.timeValueMinutes(2));
String licenseString = TestUtils.dumpLicense(signedLicense);
// put license source
PutLicenseRequestBuilder putLicenseRequestBuilder = new PutLicenseRequestBuilder(client().admin().cluster())
.setLicense(licenseString);
PutLicenseResponse putLicenseResponse = putLicenseRequestBuilder.get();
assertThat(putLicenseResponse.isAcknowledged(), equalTo(true));
assertThat(putLicenseResponse.status(), equalTo(LicensesStatus.VALID));
// get license
GetLicenseResponse getLicenseResponse = new GetLicenseRequestBuilder(client().admin().cluster()).get();
assertThat(getLicenseResponse.licenses(), notNullValue());
assertThat(getLicenseResponse.licenses().size(), equalTo(1));
// check license
TestUtils.isSame(signedLicense, getLicenseResponse.licenses().get(0));
}
@Test
@ -76,10 +103,9 @@ public class LicenseTransportTests extends AbstractLicensesIntegrationTests {
builder.setLicense(Collections.singletonList(tamperedLicense));
// try to put license (should be invalid)
final PutLicenseResponse putLicenseResponse = builder.execute().get();
final PutLicenseResponse putLicenseResponse = builder.get();
assertThat(putLicenseResponse.status(), equalTo(LicensesStatus.INVALID));
// try to get invalid license
GetLicenseResponse getLicenseResponse = new GetLicenseRequestBuilder(client().admin().cluster()).get();
assertThat(getLicenseResponse.licenses().size(), equalTo(0));
@ -94,16 +120,17 @@ public class LicenseTransportTests extends AbstractLicensesIntegrationTests {
// put license
PutLicenseRequestBuilder putLicenseRequestBuilder = new PutLicenseRequestBuilder(client().admin().cluster())
.setLicense(actualLicenses);
PutLicenseResponse putLicenseResponse = putLicenseRequestBuilder.execute().get();
PutLicenseResponse putLicenseResponse = putLicenseRequestBuilder.get();
assertThat(putLicenseResponse.isAcknowledged(), equalTo(true));
assertThat(putLicenseResponse.status(), equalTo(LicensesStatus.VALID));
// get should return only one license (with longer expiry date)
GetLicenseResponse getLicenseResponse = new GetLicenseRequestBuilder(client().admin().cluster()).get();
assertThat(getLicenseResponse.licenses(), notNullValue());
assertThat(getLicenseResponse.licenses().size(), equalTo(1));
// check license
TestUtils.isSame(Collections.singletonList(longerSignedLicense), getLicenseResponse.licenses());
TestUtils.isSame(longerSignedLicense, getLicenseResponse.licenses().get(0));
}
@Test
@ -115,7 +142,7 @@ public class LicenseTransportTests extends AbstractLicensesIntegrationTests {
// put license
PutLicenseRequestBuilder putLicenseRequestBuilder = new PutLicenseRequestBuilder(client().admin().cluster())
.setLicense(actualLicenses);
PutLicenseResponse putLicenseResponse = putLicenseRequestBuilder.execute().get();
PutLicenseResponse putLicenseResponse = putLicenseRequestBuilder.get();
assertThat(putLicenseResponse.isAcknowledged(), equalTo(true));
assertThat(putLicenseResponse.status(), equalTo(LicensesStatus.VALID));
@ -137,16 +164,82 @@ public class LicenseTransportTests extends AbstractLicensesIntegrationTests {
// put license
PutLicenseRequestBuilder putLicenseRequestBuilder = new PutLicenseRequestBuilder(client().admin().cluster())
.setLicense(actualLicenses);
PutLicenseResponse putLicenseResponse = putLicenseRequestBuilder.execute().get();
PutLicenseResponse putLicenseResponse = putLicenseRequestBuilder.get();
assertThat(putLicenseResponse.isAcknowledged(), equalTo(true));
assertThat(putLicenseResponse.status(), equalTo(LicensesStatus.VALID));
// get should return both the licenses
GetLicenseResponse getLicenseResponse = new GetLicenseRequestBuilder(client().admin().cluster()).get();
assertThat(getLicenseResponse.licenses(), notNullValue());
assertThat(getLicenseResponse.licenses().size(), equalTo(2));
// check license (should get the longest expiry time for all unique features)
TestUtils.isSame(Arrays.asList(marvelLicense, longerSignedLicense), getLicenseResponse.licenses());
}
@Test
public void testRemoveLicenseSimple() throws Exception {
ESLicense shieldLicense = generateSignedLicense("shield", TimeValue.timeValueMinutes(2));
ESLicense marvelLicense = generateSignedLicense("marvel", TimeValue.timeValueMinutes(5));
List<ESLicense> actualLicenses = Arrays.asList(marvelLicense, shieldLicense);
// put two licenses
PutLicenseRequestBuilder putLicenseRequestBuilder = new PutLicenseRequestBuilder(client().admin().cluster())
.setLicense(actualLicenses);
PutLicenseResponse putLicenseResponse = putLicenseRequestBuilder.get();
assertThat(putLicenseResponse.isAcknowledged(), equalTo(true));
assertThat(putLicenseResponse.status(), equalTo(LicensesStatus.VALID));
// get and check licenses
GetLicenseResponse getLicenseResponse = new GetLicenseRequestBuilder(client().admin().cluster()).get();
assertThat(getLicenseResponse.licenses(), notNullValue());
assertThat(getLicenseResponse.licenses().size(), equalTo(2));
// delete all licenses
DeleteLicenseRequestBuilder deleteLicenseRequestBuilder = new DeleteLicenseRequestBuilder(client().admin().cluster())
.setFeatures(Sets.newHashSet("shield", "marvel"));
DeleteLicenseResponse deleteLicenseResponse = deleteLicenseRequestBuilder.get();
assertThat(deleteLicenseResponse.isAcknowledged(), equalTo(true));
// get licenses (expected no licenses)
getLicenseResponse = new GetLicenseRequestBuilder(client().admin().cluster()).get();
assertThat(getLicenseResponse.licenses(), notNullValue());
assertThat(getLicenseResponse.licenses().size(), equalTo(0));
}
@Test
public void testRemoveLicenses() throws Exception {
ESLicense shieldLicense = generateSignedLicense("shield", TimeValue.timeValueMinutes(2));
ESLicense marvelLicense = generateSignedLicense("marvel", TimeValue.timeValueMinutes(5));
List<ESLicense> actualLicenses = Arrays.asList(marvelLicense, shieldLicense);
// put two licenses
PutLicenseRequestBuilder putLicenseRequestBuilder = new PutLicenseRequestBuilder(client().admin().cluster())
.setLicense(actualLicenses);
PutLicenseResponse putLicenseResponse = putLicenseRequestBuilder.get();
assertThat(putLicenseResponse.isAcknowledged(), equalTo(true));
assertThat(putLicenseResponse.status(), equalTo(LicensesStatus.VALID));
// delete one license
DeleteLicenseRequestBuilder deleteLicenseRequestBuilder = new DeleteLicenseRequestBuilder(client().admin().cluster())
.setFeatures(Sets.newHashSet("shield"));
DeleteLicenseResponse deleteLicenseResponse = deleteLicenseRequestBuilder.get();
assertThat(deleteLicenseResponse.isAcknowledged(), equalTo(true));
// check other license
GetLicenseResponse getLicenseResponse = new GetLicenseRequestBuilder(client().admin().cluster()).get();
assertThat(getLicenseResponse.licenses(), notNullValue());
assertThat(getLicenseResponse.licenses().size(), equalTo(1));
// delete another license
deleteLicenseRequestBuilder = new DeleteLicenseRequestBuilder(client().admin().cluster())
.setFeatures(Sets.newHashSet("marvel"));
deleteLicenseResponse = deleteLicenseRequestBuilder.get();
assertThat(deleteLicenseResponse.isAcknowledged(), equalTo(true));
// check no license
getLicenseResponse = new GetLicenseRequestBuilder(client().admin().cluster()).get();
assertThat(getLicenseResponse.licenses(), notNullValue());
assertThat(getLicenseResponse.licenses().size(), equalTo(0));
}
}