You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@slider.apache.org by sm...@apache.org on 2015/03/16 17:48:47 UTC
[14/19] incubator-slider git commit: SLIDER-811 added provider/alias
options to client getcertstore command
SLIDER-811 added provider/alias options to client getcertstore command
Project: http://git-wip-us.apache.org/repos/asf/incubator-slider/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-slider/commit/dd2a70bd
Tree: http://git-wip-us.apache.org/repos/asf/incubator-slider/tree/dd2a70bd
Diff: http://git-wip-us.apache.org/repos/asf/incubator-slider/diff/dd2a70bd
Branch: refs/heads/feature/package_simplification_II
Commit: dd2a70bd63a60178de8a5d67e5ab2a43ac281420
Parents: 148a435
Author: Billie Rinaldi <bi...@gmail.com>
Authored: Fri Mar 13 06:47:24 2015 -0700
Committer: Billie Rinaldi <bi...@gmail.com>
Committed: Fri Mar 13 10:36:46 2015 -0700
----------------------------------------------------------------------
.../org/apache/slider/client/SliderClient.java | 50 +++++--
.../slider/common/params/ActionClientArgs.java | 11 +-
.../apache/slider/common/params/Arguments.java | 1 +
.../AMClientCertStoreRetrievalIT.groovy | 131 ++++++++++++++-----
4 files changed, 148 insertions(+), 45 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/dd2a70bd/slider-core/src/main/java/org/apache/slider/client/SliderClient.java
----------------------------------------------------------------------
diff --git a/slider-core/src/main/java/org/apache/slider/client/SliderClient.java b/slider-core/src/main/java/org/apache/slider/client/SliderClient.java
index 8c1a9b2..df3ba95 100644
--- a/slider-core/src/main/java/org/apache/slider/client/SliderClient.java
+++ b/slider-core/src/main/java/org/apache/slider/client/SliderClient.java
@@ -697,7 +697,7 @@ public class SliderClient extends AbstractSliderLaunchedService implements RunSe
return startCluster(clustername, createArgs);
}
- private void checkForCredentials(Configuration conf,
+ private static void checkForCredentials(Configuration conf,
ConfTree tree) throws IOException {
if (tree.credentials == null || tree.credentials.size()==0) {
log.info("No credentials requested");
@@ -726,9 +726,6 @@ public class SliderClient extends AbstractSliderLaunchedService implements RunSe
br = new BufferedReader(new InputStreamReader(System.in));
}
char[] pass = readPassword(alias, br);
- if (pass == null)
- throw new IOException("Could not read credentials for " + alias +
- " from stdin");
credentialProvider.createCredentialEntry(alias, pass);
credentialProvider.flush();
Arrays.fill(pass, ' ');
@@ -742,9 +739,21 @@ public class SliderClient extends AbstractSliderLaunchedService implements RunSe
}
}
+ private static char[] readOnePassword(String alias) throws IOException {
+ BufferedReader br = null;
+ try {
+ br = new BufferedReader(new InputStreamReader(System.in));
+ return readPassword(alias, br);
+ } finally {
+ if (br != null) {
+ br.close();
+ }
+ }
+ }
+
// using a normal reader instead of a secure one,
// because stdin is not hooked up to the command line
- private char[] readPassword(String alias, BufferedReader br)
+ private static char[] readPassword(String alias, BufferedReader br)
throws IOException {
char[] cred = null;
@@ -763,6 +772,9 @@ public class SliderClient extends AbstractSliderLaunchedService implements RunSe
}
if (newPassword2 != null) Arrays.fill(newPassword2, ' ');
} while (noMatch);
+ if (cred == null)
+ throw new IOException("Could not read credentials for " + alias +
+ " from stdin");
return cred;
}
@@ -944,7 +956,7 @@ public class SliderClient extends AbstractSliderLaunchedService implements RunSe
}
if (clientInfo.name == null) {
- throw new BadCommandArgumentsException("No applicaiton name specified\n"
+ throw new BadCommandArgumentsException("No application name specified\n"
+ CommonArgs.usage(serviceArgs,
ACTION_CLIENT));
}
@@ -975,14 +987,26 @@ public class SliderClient extends AbstractSliderLaunchedService implements RunSe
String password = clientInfo.password;
if (password == null) {
- // get a password
- BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
- try {
- password = String.valueOf(readPassword(type.name(), br));
- } finally {
- if (br != null) {
- br.close();
+ String provider = clientInfo.provider;
+ String alias = clientInfo.alias;
+ if (provider != null && alias != null) {
+ Configuration conf = new Configuration(getConfig());
+ conf.set(CredentialProviderFactory.CREDENTIAL_PROVIDER_PATH, provider);
+ char[] chars = conf.getPassword(alias);
+ if (chars == null) {
+ CredentialProvider credentialProvider =
+ CredentialProviderFactory.getProviders(conf).get(0);
+ chars = readOnePassword(alias);
+ credentialProvider.createCredentialEntry(alias, chars);
+ credentialProvider.flush();
}
+ password = String.valueOf(chars);
+ Arrays.fill(chars, ' ');
+ } else {
+ log.info("No password and no provider/alias pair were provided, " +
+ "prompting for password");
+ // get a password
+ password = String.valueOf(readOnePassword(type.name()));
}
}
http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/dd2a70bd/slider-core/src/main/java/org/apache/slider/common/params/ActionClientArgs.java
----------------------------------------------------------------------
diff --git a/slider-core/src/main/java/org/apache/slider/common/params/ActionClientArgs.java b/slider-core/src/main/java/org/apache/slider/common/params/ActionClientArgs.java
index c7f8c2e..85d39ea 100644
--- a/slider-core/src/main/java/org/apache/slider/common/params/ActionClientArgs.java
+++ b/slider-core/src/main/java/org/apache/slider/common/params/ActionClientArgs.java
@@ -57,8 +57,17 @@ public class ActionClientArgs extends AbstractActionArgs {
description = "The name of the application")
public String name;
+ @Parameter(names = {ARG_PROVIDER},
+ description = "The credential provider in which the password is stored")
+ public String provider;
+
+ @Parameter(names = {ARG_ALIAS},
+ description = "The credential provider alias associated with the password")
+ public String alias;
+
@Parameter(names = {ARG_PASSWORD},
- description = "The certificate store password")
+ description = "The certificate store password (alternative to " +
+ "provider/alias; if password is specified, those will be ignored)")
public String password;
@Parameter(names = {ARG_PACKAGE},
http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/dd2a70bd/slider-core/src/main/java/org/apache/slider/common/params/Arguments.java
----------------------------------------------------------------------
diff --git a/slider-core/src/main/java/org/apache/slider/common/params/Arguments.java b/slider-core/src/main/java/org/apache/slider/common/params/Arguments.java
index 14be81e..9164edc 100644
--- a/slider-core/src/main/java/org/apache/slider/common/params/Arguments.java
+++ b/slider-core/src/main/java/org/apache/slider/common/params/Arguments.java
@@ -27,6 +27,7 @@ package org.apache.slider.common.params;
*/
public interface Arguments {
String ARG_ALL = "--all";
+ String ARG_ALIAS = "--alias";
String ARG_APPLICATION = "--application";
String ARG_APP_HOME = "--apphome";
String ARG_BASE_PATH = "--basepath";
http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/dd2a70bd/slider-funtest/src/test/groovy/org/apache/slider/funtest/lifecycle/AMClientCertStoreRetrievalIT.groovy
----------------------------------------------------------------------
diff --git a/slider-funtest/src/test/groovy/org/apache/slider/funtest/lifecycle/AMClientCertStoreRetrievalIT.groovy b/slider-funtest/src/test/groovy/org/apache/slider/funtest/lifecycle/AMClientCertStoreRetrievalIT.groovy
index ab632d2..3163387 100644
--- a/slider-funtest/src/test/groovy/org/apache/slider/funtest/lifecycle/AMClientCertStoreRetrievalIT.groovy
+++ b/slider-funtest/src/test/groovy/org/apache/slider/funtest/lifecycle/AMClientCertStoreRetrievalIT.groovy
@@ -18,15 +18,14 @@
package org.apache.slider.funtest.lifecycle
-import com.jcraft.jsch.Session
import groovy.transform.CompileStatic
import groovy.util.logging.Slf4j
-import org.apache.bigtop.itest.shell.Shell
-import org.apache.chaos.remote.RemoteServer
-import org.apache.chaos.remote.SshCommands
+import org.apache.hadoop.conf.Configuration
+import org.apache.hadoop.fs.Path
+import org.apache.hadoop.security.ProviderUtils
import org.apache.hadoop.security.UserGroupInformation
-import org.apache.hadoop.yarn.api.records.YarnApplicationState
-import org.apache.hadoop.yarn.conf.YarnConfiguration
+import org.apache.hadoop.security.alias.CredentialProvider
+import org.apache.hadoop.security.alias.CredentialProviderFactory
import org.apache.slider.common.SliderExitCodes
import org.apache.slider.common.params.Arguments
import org.apache.slider.common.params.SliderActions
@@ -35,7 +34,6 @@ import org.apache.slider.funtest.framework.FuntestProperties
import org.apache.slider.funtest.framework.SliderShell
import org.junit.After
import org.junit.Assert
-import org.junit.BeforeClass
import org.junit.Test
import javax.net.ssl.TrustManager
@@ -63,6 +61,21 @@ implements FuntestProperties, Arguments, SliderExitCodes, SliderActions {
cleanup(APPLICATION_NAME)
}
+ private static KeyStore loadKeystoreFromFile(String filename,
+ char[] password) {
+ FileInputStream is = null
+ try {
+ is = new FileInputStream(filename)
+ KeyStore keystore = KeyStore.getInstance("pkcs12")
+ keystore.load(is, password)
+ return keystore
+ } finally {
+ if (is != null) {
+ is.close()
+ }
+ }
+ }
+
@Test
public void testRetrieveCertificateStores() throws Throwable {
cleanup(APPLICATION_NAME)
@@ -105,27 +118,9 @@ implements FuntestProperties, Arguments, SliderExitCodes, SliderActions {
assert new File(filename).exists()
- FileInputStream is = new FileInputStream(filename);
- KeyStore keystore = KeyStore.getInstance("pkcs12");
- keystore.load(is, password.toCharArray());
-
- Certificate certificate = keystore.getCertificate(
- keystore.aliases().nextElement());
- Assert.assertNotNull(certificate);
-
- String hostname = InetAddress.localHost.canonicalHostName;
-
- if (certificate instanceof X509Certificate) {
- X509Certificate x509cert = (X509Certificate) certificate;
-
- // Get subject
- Principal principal = x509cert.getSubjectDN();
- String subjectDn = principal.getName();
- Assert.assertEquals("wrong DN",
- "CN=" + hostname + ", OU=" + APPLICATION_NAME + ", OU=client",
- subjectDn);
+ KeyStore keystore = loadKeystoreFromFile(filename, password.toCharArray())
- }
+ validateKeystore(keystore)
filename = "/tmp/test.truststore"
// ensure file doesn't exist
@@ -142,15 +137,89 @@ implements FuntestProperties, Arguments, SliderExitCodes, SliderActions {
assert new File(filename).exists()
- is = new FileInputStream(filename);
- KeyStore truststore = KeyStore.getInstance("pkcs12");
- truststore.load(is, password.toCharArray());
+ KeyStore truststore = loadKeystoreFromFile(filename, password.toCharArray())
+
+ validateTruststore(keystore, truststore);
+
+ // test retrieving using credential provider to provide password
+ filename = "/tmp/test.keystore"
+ String alias = "alias.for.password"
+ String providerString = "jceks://hdfs/user/" +
+ UserGroupInformation.getCurrentUser().getShortUserName() + "/test-" +
+ APPLICATION_NAME + ".jceks"
+ Path providerPath = ProviderUtils.unnestUri(new URI(providerString))
+
+ Configuration conf = loadSliderConf()
+ conf.set(CredentialProviderFactory.CREDENTIAL_PROVIDER_PATH, providerString)
+ CredentialProvider provider =
+ CredentialProviderFactory.getProviders(conf).get(0)
+ provider.createCredentialEntry(alias, password.toCharArray())
+ provider.flush()
+ assert clusterFS.exists(providerPath), "jks $providerString not created"
+ log.info("Created credential provider $providerString for test")
+
+ // ensure file doesn't exist
+ new File(filename).delete();
+
+ shell = slider(EXIT_SUCCESS,
+ [
+ ACTION_CLIENT,
+ ARG_GETCERTSTORE,
+ ARG_KEYSTORE, filename,
+ ARG_NAME, APPLICATION_NAME,
+ ARG_ALIAS, alias,
+ ARG_PROVIDER, providerString
+ ])
+
+ assert new File(filename).exists()
+
+ keystore = loadKeystoreFromFile(filename, password.toCharArray())
+
+ validateKeystore(keystore)
+
+ filename = "/tmp/test.truststore"
+ // ensure file doesn't exist
+ new File(filename).delete();
+
+ shell = slider(EXIT_SUCCESS,
+ [
+ ACTION_CLIENT,
+ ARG_GETCERTSTORE,
+ ARG_TRUSTSTORE, filename,
+ ARG_NAME, APPLICATION_NAME,
+ ARG_ALIAS, alias,
+ ARG_PROVIDER, providerString
+ ])
+
+ assert new File(filename).exists()
+
+ truststore = loadKeystoreFromFile(filename, password.toCharArray())
validateTruststore(keystore, truststore);
}
- private void validateTruststore(KeyStore keystore, KeyStore truststore)
+ private static void validateKeystore(KeyStore keystore) {
+ Certificate certificate = keystore.getCertificate(
+ keystore.aliases().nextElement());
+ Assert.assertNotNull(certificate);
+
+ String hostname = InetAddress.localHost.canonicalHostName;
+
+ if (certificate instanceof X509Certificate) {
+ X509Certificate x509cert = (X509Certificate) certificate;
+
+ // Get subject
+ Principal principal = x509cert.getSubjectDN();
+ String subjectDn = principal.getName();
+ Assert.assertEquals("wrong DN",
+ "CN=" + hostname + ", OU=" + APPLICATION_NAME + ", OU=client",
+ subjectDn);
+
+ }
+ }
+
+ private static void validateTruststore(KeyStore keystore, KeyStore truststore)
throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException {
// obtain server cert
Certificate certificate = keystore.getCertificate(