You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by rl...@apache.org on 2017/11/02 16:37:46 UTC
[2/3] ambari git commit: AMBARI-22293. Improve KDC integration
(rlevas)
http://git-wip-us.apache.org/repos/asf/ambari/blob/f844e5f3/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/MITKerberosOperationHandler.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/MITKerberosOperationHandler.java b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/MITKerberosOperationHandler.java
index 0997f65..bbcd6e8 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/MITKerberosOperationHandler.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/MITKerberosOperationHandler.java
@@ -18,21 +18,17 @@
package org.apache.ambari.server.serveraction.kerberos;
-import java.text.NumberFormat;
-import java.text.ParseException;
import java.util.ArrayList;
-import java.util.LinkedList;
import java.util.List;
import java.util.Map;
-import java.util.Queue;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
+import java.util.Set;
import org.apache.ambari.server.configuration.Configuration;
import org.apache.ambari.server.security.credential.PrincipalKeyCredential;
import org.apache.ambari.server.utils.ShellCommandUtil;
-import org.apache.commons.lang.ArrayUtils;
+import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
+import org.apache.directory.shared.kerberos.codec.types.EncryptionType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -45,37 +41,24 @@ import com.google.inject.Inject;
* It is assumed that a MIT Kerberos client is installed and that the kdamin shell command is
* available
*/
-public class MITKerberosOperationHandler extends KerberosOperationHandler {
+public class MITKerberosOperationHandler extends KDCKerberosOperationHandler {
+
+ private final static Logger LOG = LoggerFactory.getLogger(MITKerberosOperationHandler.class);
@Inject
private Configuration configuration;
/**
- * A regular expression pattern to use to parse the key number from the text captured from the
- * get_principal kadmin command
- */
- private final static Pattern PATTERN_GET_KEY_NUMBER = Pattern.compile("^.*?Key: vno (\\d+).*$", Pattern.DOTALL);
-
- private final static Logger LOG = LoggerFactory.getLogger(MITKerberosOperationHandler.class);
-
- /**
* A String containing user-specified attributes used when creating principals
*/
private String createAttributes = null;
- private String adminServerHost = null;
-
/**
* A String containing the resolved path to the kdamin executable
*/
private String executableKadmin = null;
/**
- * A String containing the resolved path to the kdamin.local executable
- */
- private String executableKadminLocal = null;
-
- /**
* Prepares and creates resources to be used by this KerberosOperationHandler
* <p/>
* It is expected that this KerberosOperationHandler will not be used before this call.
@@ -92,39 +75,25 @@ public class MITKerberosOperationHandler extends KerberosOperationHandler {
* @throws KerberosOperationException if an unexpected error occurred
*/
@Override
- public void open(PrincipalKeyCredential administratorCredentials, String realm,
- Map<String, String> kerberosConfiguration)
+ public void open(PrincipalKeyCredential administratorCredentials, String realm, Map<String, String> kerberosConfiguration)
throws KerberosOperationException {
- setAdministratorCredential(administratorCredentials);
- setDefaultRealm(realm);
-
if (kerberosConfiguration != null) {
- setKeyEncryptionTypes(translateEncryptionTypes(kerberosConfiguration.get(KERBEROS_ENV_ENCRYPTION_TYPES), "\\s+"));
- setAdminServerHost(kerberosConfiguration.get(KERBEROS_ENV_ADMIN_SERVER_HOST));
- setExecutableSearchPaths(kerberosConfiguration.get(KERBEROS_ENV_EXECUTABLE_SEARCH_PATHS));
- setCreateAttributes(kerberosConfiguration.get(KERBEROS_ENV_KDC_CREATE_ATTRIBUTES));
- } else {
- setKeyEncryptionTypes(null);
- setAdminServerHost(null);
- setExecutableSearchPaths((String) null);
- setCreateAttributes(null);
+ createAttributes = kerberosConfiguration.get(KERBEROS_ENV_KDC_CREATE_ATTRIBUTES);
}
// Pre-determine the paths to relevant Kerberos executables
executableKadmin = getExecutable("kadmin");
- executableKadminLocal = getExecutable("kadmin.local");
- setOpen(true);
+ super.open(administratorCredentials, realm, kerberosConfiguration);
}
@Override
public void close() throws KerberosOperationException {
- // There is nothing to do here.
- setOpen(false);
-
+ createAttributes = null;
executableKadmin = null;
- executableKadminLocal = null;
+
+ super.close();
}
/**
@@ -134,6 +103,7 @@ public class MITKerberosOperationHandler extends KerberosOperationHandler {
* the result from STDOUT to determine if the presence of the specified principal.
*
* @param principal a String containing the principal to test
+ * @param service a boolean value indicating whether the principal is for a service or not
* @return true if the principal exists; false otherwise
* @throws KerberosKDCConnectionException if a connection to the KDC cannot be made
* @throws KerberosAdminAuthenticationException if the administrator credentials fail to authenticate
@@ -141,26 +111,25 @@ public class MITKerberosOperationHandler extends KerberosOperationHandler {
* @throws KerberosOperationException if an unexpected error occurred
*/
@Override
- public boolean principalExists(String principal)
+ public boolean principalExists(String principal, boolean service)
throws KerberosOperationException {
if (!isOpen()) {
throw new KerberosOperationException("This operation handler has not been opened");
}
- if (principal == null) {
- return false;
- } else {
+ if (!StringUtils.isEmpty(principal)) {
// Create the KAdmin query to execute:
- ShellCommandUtil.Result result = invokeKAdmin(String.format("get_principal %s", principal), null);
+ ShellCommandUtil.Result result = invokeKAdmin(String.format("get_principal %s", principal));
// If there is data from STDOUT, see if the following string exists:
// Principal: <principal>
String stdOut = result.getStdout();
return (stdOut != null) && stdOut.contains(String.format("Principal: %s", principal));
}
- }
+ return false;
+ }
/**
* Creates a new principal in a previously configured MIT KDC
@@ -188,72 +157,25 @@ public class MITKerberosOperationHandler extends KerberosOperationHandler {
if (StringUtils.isEmpty(principal)) {
throw new KerberosOperationException("Failed to create new principal - no principal specified");
- } else if (StringUtils.isEmpty(password)) {
- throw new KerberosOperationException("Failed to create new principal - no password specified");
- } else {
- String createAttributes = getCreateAttributes();
- // Create the kdamin query: add_principal <-randkey|-pw <password>> [<options>] <principal>
- ShellCommandUtil.Result result = invokeKAdmin(String.format("add_principal %s %s",
- (createAttributes == null) ? "" : createAttributes, principal), password);
-
- // If there is data from STDOUT, see if the following string exists:
- // Principal "<principal>" created
- String stdOut = result.getStdout();
- String stdErr = result.getStderr();
- if ((stdOut != null) && stdOut.contains(String.format("Principal \"%s\" created", principal))) {
- return getKeyNumber(principal);
- } else if ((stdErr != null) && stdErr.contains(String.format("Principal or policy already exists while creating \"%s\"", principal))) {
- throw new KerberosPrincipalAlreadyExistsException(principal);
- } else {
- LOG.error("Failed to execute kadmin query: add_principal -pw \"********\" {} {}\nSTDOUT: {}\nSTDERR: {}",
- (createAttributes == null) ? "" : createAttributes, principal, stdOut, result.getStderr());
- throw new KerberosOperationException(String.format("Failed to create service principal for %s\nSTDOUT: %s\nSTDERR: %s",
- principal, stdOut, result.getStderr()));
- }
- }
- }
-
- /**
- * Updates the password for an existing principal in a previously configured MIT KDC
- * <p/>
- * This implementation creates a query to send to the kadmin shell command and then interrogates
- * the exit code to determine if the operation executed successfully.
- *
- * @param principal a String containing the principal to update
- * @param password a String containing the password to set
- * @return an Integer declaring the new key number
- * @throws KerberosKDCConnectionException if a connection to the KDC cannot be made
- * @throws KerberosAdminAuthenticationException if the administrator credentials fail to authenticate
- * @throws KerberosRealmException if the realm does not map to a KDC
- * @throws KerberosPrincipalDoesNotExistException if the principal does not exist
- * @throws KerberosOperationException if an unexpected error occurred
- */
- @Override
- public Integer setPrincipalPassword(String principal, String password) throws KerberosOperationException {
- if (!isOpen()) {
- throw new KerberosOperationException("This operation handler has not been opened");
}
- if (StringUtils.isEmpty(principal)) {
- throw new KerberosOperationException("Failed to set password - no principal specified");
- } else if (StringUtils.isEmpty(password)) {
- throw new KerberosOperationException("Failed to set password - no password specified");
+ // Create the kdamin query: add_principal <-randkey|-pw <password>> [<options>] <principal>
+ ShellCommandUtil.Result result = invokeKAdmin(String.format("add_principal -randkey %s %s",
+ (createAttributes == null) ? "" : createAttributes, principal));
+
+ // If there is data from STDOUT, see if the following string exists:
+ // Principal "<principal>" created
+ String stdOut = result.getStdout();
+ String stdErr = result.getStderr();
+ if ((stdOut != null) && stdOut.contains(String.format("Principal \"%s\" created", principal))) {
+ return 0;
+ } else if ((stdErr != null) && stdErr.contains(String.format("Principal or policy already exists while creating \"%s\"", principal))) {
+ throw new KerberosPrincipalAlreadyExistsException(principal);
} else {
- // Create the kdamin query: change_password <-randkey|-pw <password>> <principal>
- ShellCommandUtil.Result result = invokeKAdmin(String.format("change_password %s", principal), password);
-
- String stdOut = result.getStdout();
- String stdErr = result.getStderr();
- if ((stdOut != null) && stdOut.contains(String.format("Password for \"%s\" changed", principal))) {
- return getKeyNumber(principal);
- } else if ((stdErr != null) && stdErr.contains("Principal does not exist")) {
- throw new KerberosPrincipalDoesNotExistException(principal);
- } else {
- LOG.error("Failed to execute kadmin query: change_password -pw \"********\" {} \nSTDOUT: {}\nSTDERR: {}",
- principal, stdOut, result.getStderr());
- throw new KerberosOperationException(String.format("Failed to update password for %s\nSTDOUT: %s\nSTDERR: %s",
- principal, stdOut, result.getStderr()));
- }
+ LOG.error("Failed to execute kadmin query: add_principal -pw \"********\" {} {}\nSTDOUT: {}\nSTDERR: {}",
+ (createAttributes == null) ? "" : createAttributes, principal, stdOut, result.getStderr());
+ throw new KerberosOperationException(String.format("Failed to create service principal for %s\nSTDOUT: %s\nSTDERR: %s",
+ principal, stdOut, result.getStderr()));
}
}
@@ -263,6 +185,7 @@ public class MITKerberosOperationHandler extends KerberosOperationHandler {
* The implementation is specific to a particular type of KDC.
*
* @param principal a String containing the principal to remove
+ * @param service a boolean value indicating whether the principal is for a service or not
* @return true if the principal was successfully removed; otherwise false
* @throws KerberosKDCConnectionException if a connection to the KDC cannot be made
* @throws KerberosAdminAuthenticationException if the administrator credentials fail to authenticate
@@ -270,181 +193,63 @@ public class MITKerberosOperationHandler extends KerberosOperationHandler {
* @throws KerberosOperationException if an unexpected error occurred
*/
@Override
- public boolean removePrincipal(String principal) throws KerberosOperationException {
+ public boolean removePrincipal(String principal, boolean service) throws KerberosOperationException {
if (!isOpen()) {
throw new KerberosOperationException("This operation handler has not been opened");
}
if (StringUtils.isEmpty(principal)) {
- throw new KerberosOperationException("Failed to remove new principal - no principal specified");
- } else {
- ShellCommandUtil.Result result = invokeKAdmin(String.format("delete_principal -force %s", principal), null);
-
- // If there is data from STDOUT, see if the following string exists:
- // Principal "<principal>" created
- String stdOut = result.getStdout();
- return (stdOut != null) && !stdOut.contains("Principal does not exist");
+ throw new KerberosOperationException("Failed to remove principal - no principal specified");
}
- }
- /**
- * Sets the KDC administrator server host address
- *
- * @param adminServerHost the ip address or FQDN of the KDC administrator server
- */
- public void setAdminServerHost(String adminServerHost) {
- this.adminServerHost = adminServerHost;
- }
+ ShellCommandUtil.Result result = invokeKAdmin(String.format("delete_principal -force %s", principal));
- /**
- * Gets the IP address or FQDN of the KDC administrator server
- *
- * @return the IP address or FQDN of the KDC administrator server
- */
- public String getAdminServerHost() {
- return this.adminServerHost;
- }
-
- /**
- * Sets the (additional) principal creation attributes
- *
- * @param createAttributes the additional principal creations attributes
- */
- public void setCreateAttributes(String createAttributes) {
- this.createAttributes = createAttributes;
- }
-
- /**
- * Gets the (additional) principal creation attributes
- *
- * @return the additional principal creations attributes or null
- */
- public String getCreateAttributes() {
- return createAttributes;
- }
-
- /**
- * Retrieves the current key number assigned to the identity identified by the specified principal
- *
- * @param principal a String declaring the principal to look up
- * @return an Integer declaring the current key number
- * @throws KerberosKDCConnectionException if a connection to the KDC cannot be made
- * @throws KerberosAdminAuthenticationException if the administrator credentials fail to authenticate
- * @throws KerberosRealmException if the realm does not map to a KDC
- * @throws KerberosOperationException if an unexpected error occurred
- */
- private Integer getKeyNumber(String principal) throws KerberosOperationException {
- if (!isOpen()) {
- throw new KerberosOperationException("This operation handler has not been opened");
- }
-
- if (StringUtils.isEmpty(principal)) {
- throw new KerberosOperationException("Failed to get key number for principal - no principal specified");
- } else {
- // Create the kdamin query: get_principal <principal>
- ShellCommandUtil.Result result = invokeKAdmin(String.format("get_principal %s", principal), null);
-
- String stdOut = result.getStdout();
- if (stdOut == null) {
- String message = String.format("Failed to get key number for %s:\n\tExitCode: %s\n\tSTDOUT: NULL\n\tSTDERR: %s",
- principal, result.getExitCode(), result.getStderr());
- LOG.warn(message);
- throw new KerberosOperationException(message);
- }
-
- Matcher matcher = PATTERN_GET_KEY_NUMBER.matcher(stdOut);
- if (matcher.matches()) {
- NumberFormat numberFormat = NumberFormat.getIntegerInstance();
- String keyNumber = matcher.group(1);
-
- numberFormat.setGroupingUsed(false);
- try {
- Number number = numberFormat.parse(keyNumber);
- return (number == null) ? 0 : number.intValue();
- } catch (ParseException e) {
- String message = String.format("Failed to get key number for %s - invalid key number value (%s):\n\tExitCode: %s\n\tSTDOUT: NULL\n\tSTDERR: %s",
- principal, keyNumber, result.getExitCode(), result.getStderr());
- LOG.warn(message);
- throw new KerberosOperationException(message);
- }
- } else {
- String message = String.format("Failed to get key number for %s - unexpected STDOUT data:\n\tExitCode: %s\n\tSTDOUT: NULL\n\tSTDERR: %s",
- principal, result.getExitCode(), result.getStderr());
- LOG.warn(message);
- throw new KerberosOperationException(message);
- }
- }
+ // If there is data from STDOUT, see if the following string exists:
+ // Principal "<principal>" created
+ String stdOut = result.getStdout();
+ return (stdOut != null) && !stdOut.contains("Principal does not exist");
}
/**
* Invokes the kadmin shell command to issue queries
*
- * @param query a String containing the query to send to the kdamin command
- * @param userPassword a String containing the user's password to set or update if necessary,
- * null if not needed
+ * @param query a String containing the query to send to the kdamin command
* @return a ShellCommandUtil.Result containing the result of the operation
* @throws KerberosKDCConnectionException if a connection to the KDC cannot be made
* @throws KerberosAdminAuthenticationException if the administrator credentials fail to authenticate
* @throws KerberosRealmException if the realm does not map to a KDC
* @throws KerberosOperationException if an unexpected error occurred
*/
- protected ShellCommandUtil.Result invokeKAdmin(String query, String userPassword)
+ protected ShellCommandUtil.Result invokeKAdmin(String query)
throws KerberosOperationException {
if (StringUtils.isEmpty(query)) {
throw new KerberosOperationException("Missing kadmin query");
}
- ShellCommandUtil.Result result = null;
- PrincipalKeyCredential administratorCredential = getAdministratorCredential();
- String defaultRealm = getDefaultRealm();
+ if (StringUtils.isEmpty(executableKadmin)) {
+ throw new KerberosOperationException("No path for kadmin is available - this KerberosOperationHandler may not have been opened.");
+ }
List<String> command = new ArrayList<>();
+ command.add(executableKadmin);
- String adminPrincipal = (administratorCredential == null)
- ? null
- : administratorCredential.getPrincipal();
-
- ShellCommandUtil.InteractiveHandler interactiveHandler = null;
-
- if (StringUtils.isEmpty(adminPrincipal)) {
- // Set the kdamin interface to be kadmin.local
- if (StringUtils.isEmpty(executableKadminLocal)) {
- throw new KerberosOperationException("No path for kadmin.local is available - this KerberosOperationHandler may not have been opened.");
- }
-
- command.add(executableKadminLocal);
-
- if (userPassword != null) {
- interactiveHandler = new InteractivePasswordHandler(null, userPassword);
- }
- } else {
- if (StringUtils.isEmpty(executableKadmin)) {
- throw new KerberosOperationException("No path for kadmin is available - this KerberosOperationHandler may not have been opened.");
- }
- char[] adminPassword = administratorCredential.getKey();
-
- // Set the kdamin interface to be kadmin
- command.add(executableKadmin);
-
- // Add explicit KDC admin host, if available
- if (!StringUtils.isEmpty(getAdminServerHost())) {
- command.add("-s");
- command.add(getAdminServerHost());
- }
-
- // Add the administrative principal
- command.add("-p");
- command.add(adminPrincipal);
+ // Add the credential cache, if available
+ String credentialCacheFilePath = getCredentialCacheFilePath();
+ if (!StringUtils.isEmpty(credentialCacheFilePath)) {
+ command.add("-c");
+ command.add(credentialCacheFilePath);
+ }
- if (!ArrayUtils.isEmpty(adminPassword)) {
- interactiveHandler = new InteractivePasswordHandler(String.valueOf(adminPassword), userPassword);
- } else if (userPassword != null) {
- interactiveHandler = new InteractivePasswordHandler(null, userPassword);
- }
+ // Add explicit KDC admin host, if available
+ String adminSeverHost = getAdminServerHost();
+ if (!StringUtils.isEmpty(adminSeverHost)) {
+ command.add("-s");
+ command.add(adminSeverHost);
}
+ // Add default realm clause, if available
+ String defaultRealm = getDefaultRealm();
if (!StringUtils.isEmpty(defaultRealm)) {
- // Add default realm clause
command.add("-r");
command.add(defaultRealm);
}
@@ -457,12 +262,13 @@ public class MITKerberosOperationHandler extends KerberosOperationHandler {
LOG.debug("Executing: {}", command);
}
+ ShellCommandUtil.Result result = null;
int retryCount = configuration.getKerberosOperationRetries();
int tries = 0;
while (tries <= retryCount) {
try {
- result = executeCommand(command.toArray(new String[command.size()]), null, interactiveHandler);
+ result = executeCommand(command.toArray(new String[command.size()]));
} catch (KerberosOperationException exception) {
if (tries == retryCount) {
throw exception;
@@ -486,13 +292,16 @@ public class MITKerberosOperationHandler extends KerberosOperationHandler {
}
- if (!result.isSuccessful()) {
+ if ((result == null) || !result.isSuccessful()) {
+ int exitCode = (result == null) ? -999 : result.getExitCode();
+ String stdOut = (result == null) ? "" : result.getStdout();
+ String stdErr = (result == null) ? "" : result.getStderr();
+
String message = String.format("Failed to execute kadmin:\n\tCommand: %s\n\tExitCode: %s\n\tSTDOUT: %s\n\tSTDERR: %s",
- command, result.getExitCode(), result.getStdout(), result.getStderr());
+ command, exitCode, stdOut, stdErr);
LOG.warn(message);
// Test STDERR to see of any "expected" error conditions were encountered...
- String stdErr = result.getStderr();
// Did admin credentials fail?
if (stdErr.contains("Client not found in Kerberos database")) {
throw new KerberosAdminAuthenticationException(stdErr);
@@ -513,57 +322,56 @@ public class MITKerberosOperationHandler extends KerberosOperationHandler {
} else {
throw new KerberosOperationException(String.format("Unexpected error condition executing the kadmin command. STDERR: %s", stdErr));
}
+ } else {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Executed the following command:\n{}\nSTDOUT: {}\nSTDERR: {}",
+ StringUtils.join(command, " "), result.getStdout(), result.getStderr());
+ }
}
return result;
}
- /**
- * InteractivePasswordHandler is a {@link org.apache.ambari.server.utils.ShellCommandUtil.InteractiveHandler}
- * implementation that answers queries from kadmin or kdamin.local command for the admin and/or user
- * passwords.
- */
- protected static class InteractivePasswordHandler implements ShellCommandUtil.InteractiveHandler {
- /**
- * The queue of responses to return
- */
- private LinkedList<String> responses;
- private Queue<String> currentResponses;
-
- /**
- * Constructor.
- *
- * @param adminPassword the KDC administrator's password (optional)
- * @param userPassword the user's password (optional)
- */
- public InteractivePasswordHandler(String adminPassword, String userPassword) {
- responses = new LinkedList<>();
-
- if (adminPassword != null) {
- responses.offer(adminPassword);
- }
+ @Override
+ protected String[] getKinitCommand(String executableKinit, PrincipalKeyCredential credentials, String credentialsCache) {
+ // kinit -c <path> -S kadmin/`hostname -f` <principal>
+ return new String[]{
+ executableKinit,
+ "-c",
+ credentialsCache,
+ "-S",
+ String.format("kadmin/%s", getAdminServerHost()),
+ credentials.getPrincipal()
+ };
+ }
- if (userPassword != null) {
- responses.offer(userPassword);
- responses.offer(userPassword); // Add a 2nd time for the password "confirmation" request
+ @Override
+ protected void exportKeytabFile(String principal, String keytabFileDestinationPath, Set<EncryptionType> keyEncryptionTypes) throws KerberosOperationException {
+ String encryptionTypeSpec = null;
+ if (!CollectionUtils.isEmpty(keyEncryptionTypes)) {
+ StringBuilder encryptionTypeSpecBuilder = new StringBuilder();
+ for (EncryptionType encryptionType : keyEncryptionTypes) {
+ if (encryptionTypeSpecBuilder.length() > 0) {
+ encryptionTypeSpecBuilder.append(',');
+ }
+ encryptionTypeSpecBuilder.append(encryptionType.getName());
+ encryptionTypeSpecBuilder.append(":normal");
}
- currentResponses = new LinkedList<>(responses);
+ encryptionTypeSpec = encryptionTypeSpecBuilder.toString();
}
- @Override
- public boolean done() {
- return currentResponses.size() == 0;
- }
+ String query = (StringUtils.isEmpty(encryptionTypeSpec))
+ ? String.format("xst -k \"%s\" %s", keytabFileDestinationPath, principal)
+ : String.format("xst -k \"%s\" -e %s %s", keytabFileDestinationPath, encryptionTypeSpec, principal);
- @Override
- public String getResponse(String query) {
- return currentResponses.poll();
- }
+ ShellCommandUtil.Result result = invokeKAdmin(query);
- @Override
- public void start() {
- currentResponses = new LinkedList<>(responses);
+ if (!result.isSuccessful()) {
+ String message = String.format("Failed to export the keytab file for %s:\n\tExitCode: %s\n\tSTDOUT: %s\n\tSTDERR: %s",
+ principal, result.getExitCode(), result.getStdout(), result.getStderr());
+ LOG.warn(message);
+ throw new KerberosOperationException(message);
}
}
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/f844e5f3/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog300.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog300.java b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog300.java
index bfe2a13..d3e924e 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog300.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog300.java
@@ -45,6 +45,7 @@ import org.apache.ambari.server.state.Cluster;
import org.apache.ambari.server.state.Clusters;
import org.apache.ambari.server.state.Config;
import org.apache.ambari.server.state.ConfigHelper;
+import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -149,6 +150,7 @@ public class UpgradeCatalog300 extends AbstractUpgradeCatalog {
showHcatDeletedUserMessage();
setStatusOfStagesAndRequests();
updateLogSearchConfigs();
+ updateKerberosConfigurations();
}
protected void showHcatDeletedUserMessage() {
@@ -265,7 +267,7 @@ public class UpgradeCatalog300 extends AbstractUpgradeCatalog {
"logsearch-common-properties", Collections.emptyMap(), "ambari-upgrade",
String.format("Updated logsearch-common-properties during Ambari Upgrade from %s to %s",
getSourceVersion(), getTargetVersion()));
-
+
String defaultLogLevels = logSearchProperties.getProperties().get("logsearch.logfeeder.include.default.level");
Set<String> removeProperties = Sets.newHashSet("logsearch.logfeeder.include.default.level");
@@ -324,7 +326,7 @@ public class UpgradeCatalog300 extends AbstractUpgradeCatalog {
updateConfigurationPropertiesForCluster(cluster, "logsearch-audit_logs-solrconfig", Collections.singletonMap("content", content), true, true);
}
}
-
+
Config logFeederOutputConfig = cluster.getDesiredConfigByType("logfeeder-output-config");
if (logFeederOutputConfig != null) {
String content = logFeederOutputConfig.getProperties().get("content");
@@ -346,4 +348,28 @@ public class UpgradeCatalog300 extends AbstractUpgradeCatalog {
}
}
}
+
+ protected void updateKerberosConfigurations() throws AmbariException {
+ AmbariManagementController ambariManagementController = injector.getInstance(AmbariManagementController.class);
+ Clusters clusters = ambariManagementController.getClusters();
+ if (clusters != null) {
+ Map<String, Cluster> clusterMap = clusters.getClusters();
+
+ if (!MapUtils.isEmpty(clusterMap)) {
+ for (Cluster cluster : clusterMap.values()) {
+ Config config = cluster.getDesiredConfigByType("kerberos-env");
+
+ if (config != null) {
+ Map<String, String> properties = config.getProperties();
+ if (properties.containsKey("group")) {
+ // Covert kerberos-env/group to kerberos-env/ipa_user_group
+ updateConfigurationPropertiesForCluster(cluster, "kerberos-env",
+ Collections.singletonMap("ipa_user_group", properties.get("group")), Collections.singleton("group"),
+ true, false);
+ }
+ }
+ }
+ }
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/f844e5f3/ambari-server/src/main/resources/common-services/KERBEROS/1.10.3-10/configuration/kerberos-env.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/KERBEROS/1.10.3-10/configuration/kerberos-env.xml b/ambari-server/src/main/resources/common-services/KERBEROS/1.10.3-10/configuration/kerberos-env.xml
index 0a08121..293bcf8 100644
--- a/ambari-server/src/main/resources/common-services/KERBEROS/1.10.3-10/configuration/kerberos-env.xml
+++ b/ambari-server/src/main/resources/common-services/KERBEROS/1.10.3-10/configuration/kerberos-env.xml
@@ -349,8 +349,8 @@
<on-ambari-upgrade add="true"/>
</property>
<property>
- <name>group</name>
- <display-name>IPA Group</display-name>
+ <name>ipa_user_group</name>
+ <display-name>IPA User Group</display-name>
<description>
The group in IPA user principals should be member of
</description>
@@ -362,38 +362,6 @@
<on-ambari-upgrade add="true"/>
</property>
<property>
- <name>set_password_expiry</name>
- <display-name>Set IPA principal password expiry</display-name>
- <description>
- Indicates whether Ambari should set the password expiry for the principals it creates. By default
- IPA does not allow this. It requires write permission of the admin principal to the krbPasswordExpiry
- attribute. If set IPA principal password expiry is not true it is assumed that a suitable password
- policy is in place for the IPA Group principals are added to.
- </description>
- <value>false</value>
- <value-attributes>
- <type>boolean</type>
- <overridable>false</overridable>
- <visible>false</visible>
- </value-attributes>
- <on-ambari-upgrade add="true"/>
- </property>
- <property>
- <name>password_chat_timeout</name>
- <display-name>Set IPA kinit password chat timeout</display-name>
- <description>
- Indicates the timeout in seconds that Ambari should wait for a response during a password chat. This is
- because it can take some time due to lookups before a response is there.
- </description>
- <value>5</value>
- <value-attributes>
- <visible>false</visible>
- <type>int</type>
- <overridable>false</overridable>
- </value-attributes>
- <on-ambari-upgrade add="true"/>
- </property>
- <property>
<name>preconfigure_services</name>
<display-name>Pre-configure services</display-name>
<description>
http://git-wip-us.apache.org/repos/asf/ambari/blob/f844e5f3/ambari-server/src/main/resources/common-services/KERBEROS/1.10.3-30/configuration/kerberos-env.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/KERBEROS/1.10.3-30/configuration/kerberos-env.xml b/ambari-server/src/main/resources/common-services/KERBEROS/1.10.3-30/configuration/kerberos-env.xml
index 0a08121..293bcf8 100644
--- a/ambari-server/src/main/resources/common-services/KERBEROS/1.10.3-30/configuration/kerberos-env.xml
+++ b/ambari-server/src/main/resources/common-services/KERBEROS/1.10.3-30/configuration/kerberos-env.xml
@@ -349,8 +349,8 @@
<on-ambari-upgrade add="true"/>
</property>
<property>
- <name>group</name>
- <display-name>IPA Group</display-name>
+ <name>ipa_user_group</name>
+ <display-name>IPA User Group</display-name>
<description>
The group in IPA user principals should be member of
</description>
@@ -362,38 +362,6 @@
<on-ambari-upgrade add="true"/>
</property>
<property>
- <name>set_password_expiry</name>
- <display-name>Set IPA principal password expiry</display-name>
- <description>
- Indicates whether Ambari should set the password expiry for the principals it creates. By default
- IPA does not allow this. It requires write permission of the admin principal to the krbPasswordExpiry
- attribute. If set IPA principal password expiry is not true it is assumed that a suitable password
- policy is in place for the IPA Group principals are added to.
- </description>
- <value>false</value>
- <value-attributes>
- <type>boolean</type>
- <overridable>false</overridable>
- <visible>false</visible>
- </value-attributes>
- <on-ambari-upgrade add="true"/>
- </property>
- <property>
- <name>password_chat_timeout</name>
- <display-name>Set IPA kinit password chat timeout</display-name>
- <description>
- Indicates the timeout in seconds that Ambari should wait for a response during a password chat. This is
- because it can take some time due to lookups before a response is there.
- </description>
- <value>5</value>
- <value-attributes>
- <visible>false</visible>
- <type>int</type>
- <overridable>false</overridable>
- </value-attributes>
- <on-ambari-upgrade add="true"/>
- </property>
- <property>
<name>preconfigure_services</name>
<display-name>Pre-configure services</display-name>
<description>
http://git-wip-us.apache.org/repos/asf/ambari/blob/f844e5f3/ambari-server/src/main/resources/stacks/PERF/1.0/services/KERBEROS/configuration/kerberos-env.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/PERF/1.0/services/KERBEROS/configuration/kerberos-env.xml b/ambari-server/src/main/resources/stacks/PERF/1.0/services/KERBEROS/configuration/kerberos-env.xml
index 66e81db..a66a7a6 100644
--- a/ambari-server/src/main/resources/stacks/PERF/1.0/services/KERBEROS/configuration/kerberos-env.xml
+++ b/ambari-server/src/main/resources/stacks/PERF/1.0/services/KERBEROS/configuration/kerberos-env.xml
@@ -348,8 +348,8 @@
<on-ambari-upgrade add="true"/>
</property>
<property>
- <name>group</name>
- <display-name>IPA Group</display-name>
+ <name>ipa_user_group</name>
+ <display-name>IPA User Group</display-name>
<description>
The group in IPA user principals should be member of
</description>
@@ -360,36 +360,4 @@
</value-attributes>
<on-ambari-upgrade add="true"/>
</property>
- <property>
- <name>set_password_expiry</name>
- <display-name>Set IPA principal password expiry</display-name>
- <description>
- Indicates whether Ambari should set the password expiry for the principals it creates. By default
- IPA does not allow this. It requires write permission of the admin principal to the krbPasswordExpiry
- attribute. If set IPA principal password expiry is not true it is assumed that a suitable password
- policy is in place for the IPA Group principals are added to.
- </description>
- <value>false</value>
- <value-attributes>
- <type>boolean</type>
- <overridable>false</overridable>
- <visible>false</visible>
- </value-attributes>
- <on-ambari-upgrade add="true"/>
- </property>
- <property>
- <name>password_chat_timeout</name>
- <display-name>Set IPA kinit password chat timeout</display-name>
- <description>
- Indicates the timeout in seconds that Ambari should wait for a response during a password chat. This is
- because it can take some time due to lookups before a response is there.
- </description>
- <value>5</value>
- <value-attributes>
- <visible>false</visible>
- <type>int</type>
- <overridable>false</overridable>
- </value-attributes>
- <on-ambari-upgrade add="true"/>
- </property>
</configuration>
http://git-wip-us.apache.org/repos/asf/ambari/blob/f844e5f3/ambari-server/src/test/java/org/apache/ambari/server/controller/KerberosHelperTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/KerberosHelperTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/KerberosHelperTest.java
index a3074ae..ee87d24 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/KerberosHelperTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/KerberosHelperTest.java
@@ -188,7 +188,7 @@ public class KerberosHelperTest extends EasyMockSupport {
}
@Override
- public boolean principalExists(String principal) throws KerberosOperationException {
+ public boolean principalExists(String principal, boolean service) throws KerberosOperationException {
return "principal".equals(principal);
}
@@ -198,12 +198,12 @@ public class KerberosHelperTest extends EasyMockSupport {
}
@Override
- public Integer setPrincipalPassword(String principal, String password) throws KerberosOperationException {
+ public Integer setPrincipalPassword(String principal, String password, boolean service) throws KerberosOperationException {
return null;
}
@Override
- public boolean removePrincipal(String principal) throws KerberosOperationException {
+ public boolean removePrincipal(String principal, boolean service) throws KerberosOperationException {
return false;
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/f844e5f3/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/ADKerberosOperationHandlerTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/ADKerberosOperationHandlerTest.java b/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/ADKerberosOperationHandlerTest.java
index 483cc0a..8b3c19a 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/ADKerberosOperationHandlerTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/ADKerberosOperationHandlerTest.java
@@ -19,11 +19,15 @@
package org.apache.ambari.server.serveraction.kerberos;
import static org.easymock.EasyMock.anyObject;
+import static org.easymock.EasyMock.anyString;
import static org.easymock.EasyMock.capture;
import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.expectLastCall;
+import static org.easymock.EasyMock.isNull;
import static org.easymock.EasyMock.newCapture;
import static org.easymock.EasyMock.replay;
+import java.lang.reflect.Method;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.List;
@@ -50,6 +54,8 @@ import org.apache.ambari.server.state.stack.OsFamily;
import org.easymock.Capture;
import org.easymock.CaptureType;
import org.easymock.IAnswer;
+import org.junit.Before;
+import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
@@ -65,6 +71,36 @@ public class ADKerberosOperationHandlerTest extends KerberosOperationHandlerTest
private static final String DEFAULT_LDAP_URL = "ldaps://10.0.100.4";
private static final String DEFAULT_PRINCIPAL_CONTAINER_DN = "ou=HDP,DC=HDP01,DC=LOCAL";
private static final String DEFAULT_REALM = "HDP01.LOCAL";
+ private static final Map<String, String> KERBEROS_ENV_MAP = new HashMap<String, String>() {
+ {
+ put(ADKerberosOperationHandler.KERBEROS_ENV_PRINCIPAL_CONTAINER_DN, DEFAULT_PRINCIPAL_CONTAINER_DN);
+ put(ADKerberosOperationHandler.KERBEROS_ENV_LDAP_URL, DEFAULT_LDAP_URL);
+ }
+ };
+
+ private static Method methodCreateInitialLdapContext;
+
+ private Injector injector;
+ private LdapContext ldapContext;
+
+ @BeforeClass
+ public static void beforeMITKerberosOperationHandlerTest() throws Exception {
+ methodCreateInitialLdapContext = ADKerberosOperationHandler.class.getDeclaredMethod("createInitialLdapContext", Properties.class, Control[].class);
+ }
+
+ @Before
+ public void setup() {
+ injector = Guice.createInjector(new AbstractModule() {
+ @Override
+ protected void configure() {
+ bind(Clusters.class).toInstance(createNiceMock(Clusters.class));
+ bind(Configuration.class).toInstance(createNiceMock(Configuration.class));
+ bind(OsFamily.class).toInstance(createNiceMock(OsFamily.class));
+ }
+ });
+
+ ldapContext = createMock(LdapContext.class);
+ }
@Test(expected = KerberosKDCConnectionException.class)
public void testOpenExceptionLdapUrlNotProvided() throws Exception {
@@ -95,13 +131,8 @@ public class ADKerberosOperationHandlerTest extends KerberosOperationHandlerTest
@Test(expected = KerberosAdminAuthenticationException.class)
public void testOpenExceptionAdminCredentialsNotProvided() throws Exception {
KerberosOperationHandler handler = new ADKerberosOperationHandler();
- Map<String, String> kerberosEnvMap = new HashMap<String, String>() {
- {
- put(ADKerberosOperationHandler.KERBEROS_ENV_LDAP_URL, DEFAULT_LDAP_URL);
- put(ADKerberosOperationHandler.KERBEROS_ENV_PRINCIPAL_CONTAINER_DN, DEFAULT_PRINCIPAL_CONTAINER_DN);
- }
- };
- handler.open(null, DEFAULT_REALM, kerberosEnvMap);
+
+ handler.open(null, DEFAULT_REALM, getKerberosEnv());
handler.close();
}
@@ -124,13 +155,6 @@ public class ADKerberosOperationHandlerTest extends KerberosOperationHandlerTest
Injector injector = getInjector();
PrincipalKeyCredential kc = new PrincipalKeyCredential(DEFAULT_ADMIN_PRINCIPAL, "wrong");
- Map<String, String> kerberosEnvMap = new HashMap<String, String>() {
- {
- put(ADKerberosOperationHandler.KERBEROS_ENV_LDAP_URL, DEFAULT_LDAP_URL);
- put(ADKerberosOperationHandler.KERBEROS_ENV_PRINCIPAL_CONTAINER_DN, DEFAULT_PRINCIPAL_CONTAINER_DN);
- }
- };
-
ADKerberosOperationHandler handler = createMockBuilder(ADKerberosOperationHandler.class)
.addMockedMethod(ADKerberosOperationHandler.class.getDeclaredMethod("createInitialLdapContext", Properties.class, Control[].class))
.createNiceMock();
@@ -145,7 +169,7 @@ public class ADKerberosOperationHandlerTest extends KerberosOperationHandlerTest
replayAll();
- handler.open(kc, DEFAULT_REALM, kerberosEnvMap);
+ handler.open(kc, DEFAULT_REALM, getKerberosEnv());
handler.testAdministratorCredentials();
handler.close();
}
@@ -155,12 +179,6 @@ public class ADKerberosOperationHandlerTest extends KerberosOperationHandlerTest
Injector injector = getInjector();
PrincipalKeyCredential kc = new PrincipalKeyCredential("wrong", DEFAULT_ADMIN_PASSWORD);
- Map<String, String> kerberosEnvMap = new HashMap<String, String>() {
- {
- put(ADKerberosOperationHandler.KERBEROS_ENV_LDAP_URL, DEFAULT_LDAP_URL);
- put(ADKerberosOperationHandler.KERBEROS_ENV_PRINCIPAL_CONTAINER_DN, DEFAULT_PRINCIPAL_CONTAINER_DN);
- }
- };
ADKerberosOperationHandler handler = createMockBuilder(ADKerberosOperationHandler.class)
.addMockedMethod(ADKerberosOperationHandler.class.getDeclaredMethod("createInitialLdapContext", Properties.class, Control[].class))
@@ -176,7 +194,7 @@ public class ADKerberosOperationHandlerTest extends KerberosOperationHandlerTest
replayAll();
- handler.open(kc, DEFAULT_REALM, kerberosEnvMap);
+ handler.open(kc, DEFAULT_REALM, getKerberosEnv());
handler.testAdministratorCredentials();
handler.close();
}
@@ -184,17 +202,8 @@ public class ADKerberosOperationHandlerTest extends KerberosOperationHandlerTest
@Test(expected = KerberosKDCConnectionException.class)
public void testTestAdministratorCredentialsKDCConnectionException() throws Exception {
PrincipalKeyCredential kc = new PrincipalKeyCredential(DEFAULT_ADMIN_PRINCIPAL, DEFAULT_ADMIN_PASSWORD);
- Map<String, String> kerberosEnvMap = new HashMap<String, String>() {
- {
- put(ADKerberosOperationHandler.KERBEROS_ENV_LDAP_URL, "invalid");
- put(ADKerberosOperationHandler.KERBEROS_ENV_PRINCIPAL_CONTAINER_DN, DEFAULT_PRINCIPAL_CONTAINER_DN);
- }
- };
-
- ADKerberosOperationHandler handler = createMockBuilder(ADKerberosOperationHandler.class)
- .addMockedMethod(ADKerberosOperationHandler.class.getDeclaredMethod("createInitialLdapContext", Properties.class, Control[].class))
- .createNiceMock();
+ ADKerberosOperationHandler handler = createMockedHandler(methodCreateInitialLdapContext);
expect(handler.createInitialLdapContext(anyObject(Properties.class), anyObject(Control[].class))).andAnswer(new IAnswer<LdapContext>() {
@Override
public LdapContext answer() throws Throwable {
@@ -204,7 +213,7 @@ public class ADKerberosOperationHandlerTest extends KerberosOperationHandlerTest
replayAll();
- handler.open(kc, DEFAULT_REALM, kerberosEnvMap);
+ handler.open(kc, DEFAULT_REALM, getKerberosEnv());
handler.testAdministratorCredentials();
handler.close();
}
@@ -212,21 +221,8 @@ public class ADKerberosOperationHandlerTest extends KerberosOperationHandlerTest
@Test
public void testTestAdministratorCredentialsSuccess() throws Exception {
- Injector injector = getInjector();
-
PrincipalKeyCredential kc = new PrincipalKeyCredential(DEFAULT_ADMIN_PRINCIPAL, DEFAULT_ADMIN_PASSWORD);
- Map<String, String> kerberosEnvMap = new HashMap<String, String>() {
- {
- put(ADKerberosOperationHandler.KERBEROS_ENV_LDAP_URL, DEFAULT_LDAP_URL);
- put(ADKerberosOperationHandler.KERBEROS_ENV_PRINCIPAL_CONTAINER_DN, DEFAULT_PRINCIPAL_CONTAINER_DN);
- }
- };
-
- ADKerberosOperationHandler handler = createMockBuilder(ADKerberosOperationHandler.class)
- .addMockedMethod(ADKerberosOperationHandler.class.getDeclaredMethod("createInitialLdapContext", Properties.class, Control[].class))
- .addMockedMethod(ADKerberosOperationHandler.class.getDeclaredMethod("createSearchControls"))
- .createNiceMock();
- injector.injectMembers(handler);
+ ADKerberosOperationHandler handler = createMockedHandler(methodCreateInitialLdapContext);
expect(handler.createInitialLdapContext(anyObject(Properties.class), anyObject(Control[].class)))
.andAnswer(new IAnswer<LdapContext>() {
@@ -245,23 +241,14 @@ public class ADKerberosOperationHandlerTest extends KerberosOperationHandlerTest
}
})
.once();
- replay(ldapContext);
return ldapContext;
}
})
.once();
- expect(handler.createSearchControls()).andAnswer(new IAnswer<SearchControls>() {
- @Override
- public SearchControls answer() throws Throwable {
- SearchControls searchControls = createNiceMock(SearchControls.class);
- replay(searchControls);
- return searchControls;
- }
- }).once();
replayAll();
- handler.open(kc, DEFAULT_REALM, kerberosEnvMap);
+ handler.open(kc, DEFAULT_REALM, getKerberosEnv());
handler.testAdministratorCredentials();
handler.close();
}
@@ -271,12 +258,6 @@ public class ADKerberosOperationHandlerTest extends KerberosOperationHandlerTest
Injector injector = getInjector();
PrincipalKeyCredential kc = new PrincipalKeyCredential(DEFAULT_ADMIN_PRINCIPAL, DEFAULT_ADMIN_PASSWORD);
- Map<String, String> kerberosEnvMap = new HashMap<String, String>() {
- {
- put(ADKerberosOperationHandler.KERBEROS_ENV_LDAP_URL, DEFAULT_LDAP_URL);
- put(ADKerberosOperationHandler.KERBEROS_ENV_PRINCIPAL_CONTAINER_DN, DEFAULT_PRINCIPAL_CONTAINER_DN);
- }
- };
Capture<Name> capturedName = newCapture(CaptureType.ALL);
Capture<Attributes> capturedAttributes = newCapture(CaptureType.ALL);
@@ -315,7 +296,7 @@ public class ADKerberosOperationHandlerTest extends KerberosOperationHandlerTest
replayAll();
- handler.open(kc, DEFAULT_REALM, kerberosEnvMap);
+ handler.open(kc, DEFAULT_REALM, getKerberosEnv());
handler.createPrincipal("nn/c6501.ambari.apache.org", "secret", true);
handler.createPrincipal("hdfs@" + DEFAULT_REALM, "secret", false);
handler.close();
@@ -384,31 +365,26 @@ public class ADKerberosOperationHandlerTest extends KerberosOperationHandlerTest
Injector injector = getInjector();
PrincipalKeyCredential kc = new PrincipalKeyCredential(DEFAULT_ADMIN_PRINCIPAL, DEFAULT_ADMIN_PASSWORD);
- Map<String, String> kerberosEnvMap = new HashMap<String, String>() {
- {
- put(ADKerberosOperationHandler.KERBEROS_ENV_LDAP_URL, DEFAULT_LDAP_URL);
- put(ADKerberosOperationHandler.KERBEROS_ENV_PRINCIPAL_CONTAINER_DN, DEFAULT_PRINCIPAL_CONTAINER_DN);
- put(ADKerberosOperationHandler.KERBEROS_ENV_AD_CREATE_ATTRIBUTES_TEMPLATE, "" +
- "#set( $user = \"${principal_primary}-${principal_digest}\" )" +
- "{" +
- " \"objectClass\": [" +
- " \"top\"," +
- " \"person\"," +
- " \"organizationalPerson\"," +
- " \"user\"" +
- " ]," +
- " \"cn\": \"$user\"," +
- " \"sAMAccountName\": \"$user.substring(0,20)\"," +
- " #if( $is_service )" +
- " \"servicePrincipalName\": \"$principal_name\"," +
- " #end" +
- " \"userPrincipalName\": \"$normalized_principal\"," +
- " \"unicodePwd\": \"$password\"," +
- " \"accountExpires\": \"0\"," +
- " \"userAccountControl\": \"66048\"" +
- "}");
- }
- };
+ Map<String, String> kerberosEnvMap = new HashMap<>(getKerberosEnv());
+ kerberosEnvMap.put(ADKerberosOperationHandler.KERBEROS_ENV_AD_CREATE_ATTRIBUTES_TEMPLATE, "" +
+ "#set( $user = \"${principal_primary}-${principal_digest}\" )" +
+ "{" +
+ " \"objectClass\": [" +
+ " \"top\"," +
+ " \"person\"," +
+ " \"organizationalPerson\"," +
+ " \"user\"" +
+ " ]," +
+ " \"cn\": \"$user\"," +
+ " \"sAMAccountName\": \"$user.substring(0,20)\"," +
+ " #if( $is_service )" +
+ " \"servicePrincipalName\": \"$principal_name\"," +
+ " #end" +
+ " \"userPrincipalName\": \"$normalized_principal\"," +
+ " \"unicodePwd\": \"$password\"," +
+ " \"accountExpires\": \"0\"," +
+ " \"userAccountControl\": \"66048\"" +
+ "}");
Capture<Name> capturedName = newCapture();
Capture<Attributes> capturedAttributes = newCapture();
@@ -491,9 +467,7 @@ public class ADKerberosOperationHandlerTest extends KerberosOperationHandlerTest
Injector injector = getInjector();
PrincipalKeyCredential kc = new PrincipalKeyCredential(DEFAULT_ADMIN_PRINCIPAL, DEFAULT_ADMIN_PASSWORD);
- Map<String, String> kerberosEnvMap = new HashMap<>();
- kerberosEnvMap.put(ADKerberosOperationHandler.KERBEROS_ENV_LDAP_URL, DEFAULT_LDAP_URL);
- kerberosEnvMap.put(ADKerberosOperationHandler.KERBEROS_ENV_PRINCIPAL_CONTAINER_DN, DEFAULT_PRINCIPAL_CONTAINER_DN);
+ Map<String, String> kerberosEnvMap = new HashMap<>(getKerberosEnv());
kerberosEnvMap.put(ADKerberosOperationHandler.KERBEROS_ENV_AD_CREATE_ATTRIBUTES_TEMPLATE, "" +
"{" +
"\"principal_digest\": \"$principal_digest\"," +
@@ -596,7 +570,7 @@ public class ADKerberosOperationHandlerTest extends KerberosOperationHandlerTest
System.out.println("Test Admin Credentials: " + handler.testAdministratorCredentials());
// does the principal already exist?
- System.out.println("Principal exists: " + handler.principalExists("nn/c1508.ambari.apache.org"));
+ System.out.println("Principal exists: " + handler.principalExists("nn/c1508.ambari.apache.org", true));
handler.close();
@@ -605,15 +579,15 @@ public class ADKerberosOperationHandlerTest extends KerberosOperationHandlerTest
String evaluatedPrincipal;
evaluatedPrincipal = "nn/c6501.ambari.apache.org@" + DEFAULT_REALM;
- if (handler.principalExists(evaluatedPrincipal)) {
- handler.setPrincipalPassword(evaluatedPrincipal, "some password");
+ if (handler.principalExists(evaluatedPrincipal, true)) {
+ handler.setPrincipalPassword(evaluatedPrincipal, "some password", true);
} else {
handler.createPrincipal(evaluatedPrincipal, "some password", true);
}
evaluatedPrincipal = "hdfs@" + DEFAULT_REALM;
- if (handler.principalExists(evaluatedPrincipal)) {
- handler.setPrincipalPassword(evaluatedPrincipal, "some password");
+ if (handler.principalExists(evaluatedPrincipal, false)) {
+ handler.setPrincipalPassword(evaluatedPrincipal, "some password", false);
} else {
handler.createPrincipal(evaluatedPrincipal, "some password", true);
}
@@ -644,14 +618,14 @@ public class ADKerberosOperationHandlerTest extends KerberosOperationHandlerTest
handler.open(credentials, realm, kerberosEnvMap);
// remove the principal
- handler.removePrincipal("abcdefg");
- handler.removePrincipal("abcdefg/c1509.ambari.apache.org@" + DEFAULT_REALM);
+ handler.removePrincipal("abcdefg", false);
+ handler.removePrincipal("abcdefg/c1509.ambari.apache.org@" + DEFAULT_REALM, true);
handler.createPrincipal("abcdefg/c1509.ambari.apache.org@" + DEFAULT_REALM, "some password", true);
handler.createPrincipal("abcdefg@" + DEFAULT_REALM, "some password", false);
//update the password
- handler.setPrincipalPassword("abcdefg/c1509.ambari.apache.org@" + DEFAULT_REALM, "some password");
+ handler.setPrincipalPassword("abcdefg/c1509.ambari.apache.org@" + DEFAULT_REALM, "some password", true);
handler.close();
}
@@ -687,11 +661,7 @@ public class ADKerberosOperationHandlerTest extends KerberosOperationHandlerTest
replayAll();
- Map<String, String> kerberosConfiguration = new HashMap<>();
- kerberosConfiguration.put(ADKerberosOperationHandler.KERBEROS_ENV_LDAP_URL, DEFAULT_LDAP_URL);
- kerberosConfiguration.put(ADKerberosOperationHandler.KERBEROS_ENV_PRINCIPAL_CONTAINER_DN, DEFAULT_PRINCIPAL_CONTAINER_DN);
-
- handler.open(new PrincipalKeyCredential("principal", "key"), "EXAMPLE.COM", kerberosConfiguration);
+ handler.open(new PrincipalKeyCredential("principal", "key"), "EXAMPLE.COM", getKerberosEnv());
Properties properties = capturedProperties.getValue();
Assert.assertNotNull(properties);
@@ -705,13 +675,78 @@ public class ADKerberosOperationHandlerTest extends KerberosOperationHandlerTest
}
private Injector getInjector() {
- return Guice.createInjector(new AbstractModule() {
- @Override
- protected void configure() {
- bind(Clusters.class).toInstance(createNiceMock(Clusters.class));
- bind(Configuration.class).toInstance(createNiceMock(Configuration.class));
- bind(OsFamily.class).toInstance(createNiceMock(OsFamily.class));
- }
- });
+ return injector;
+ }
+
+ @Override
+ protected KerberosOperationHandler createMockedHandler() throws KerberosOperationException {
+ return createMockedHandler(methodCreateInitialLdapContext);
+ }
+
+
+ private ADKerberosOperationHandler createMockedHandler(Method... mockedMethods) {
+ ADKerberosOperationHandler handler = createMockBuilder(ADKerberosOperationHandler.class)
+ .addMockedMethods(mockedMethods)
+ .createMock();
+ injector.injectMembers(handler);
+ return handler;
+ }
+
+
+ @Override
+ protected void setupOpenSuccess(KerberosOperationHandler handler) throws Exception {
+
+ ADKerberosOperationHandler adHandler = (ADKerberosOperationHandler) handler;
+
+ expect(adHandler.createInitialLdapContext(anyObject(Properties.class), isNull())).andReturn(ldapContext).anyTimes();
+ }
+
+ @Override
+ protected void setupOpenFailure(KerberosOperationHandler handler) throws Exception {
+ ADKerberosOperationHandler adHandler = (ADKerberosOperationHandler) handler;
+ expect(adHandler.createInitialLdapContext(anyObject(Properties.class), isNull())).andThrow(new AuthenticationException("Bogus error!")).anyTimes();
+ }
+
+ @Override
+ protected void setupPrincipalAlreadyExists(KerberosOperationHandler handler, boolean service) throws Exception {
+ setupPrincipalExists(handler, service);
+ }
+
+ @Override
+ protected void setupPrincipalDoesNotExist(KerberosOperationHandler handler, boolean service) throws Exception {
+ NamingEnumeration<SearchResult> results = createMock(NamingEnumeration.class);
+ results.close();
+ expectLastCall().once();
+ expect(results.hasMore()).andReturn(false).anyTimes();
+
+ expect(ldapContext.search(anyObject(Name.class), anyString(), anyObject(SearchControls.class)))
+ .andReturn(results)
+ .anyTimes();
+ ldapContext.close();
+ expectLastCall().once();
+ }
+
+ @Override
+ protected void setupPrincipalExists(KerberosOperationHandler handler, boolean service) throws Exception {
+ SearchResult result = createMock(SearchResult.class);
+ expect(result.getNameInNamespace()).andReturn("user/service dn").anyTimes();
+
+ NamingEnumeration<SearchResult> results = createMock(NamingEnumeration.class);
+ results.close();
+ expectLastCall().anyTimes();
+ expect(results.hasMore()).andReturn(true).once();
+ expect(results.next()).andReturn(result).once();
+ expect(results.hasMore()).andReturn(false).anyTimes();
+
+ expect(ldapContext.search(anyObject(Name.class), anyString(), anyObject(SearchControls.class)))
+ .andReturn(results)
+ .anyTimes();
+ ldapContext.close();
+ expectLastCall().once();
+ }
+
+ @Override
+ protected Map<String, String> getKerberosEnv() {
+ return KERBEROS_ENV_MAP;
}
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/f844e5f3/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/IPAKerberosOperationHandlerTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/IPAKerberosOperationHandlerTest.java b/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/IPAKerberosOperationHandlerTest.java
index f2a09ba..558ca79 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/IPAKerberosOperationHandlerTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/IPAKerberosOperationHandlerTest.java
@@ -18,36 +18,26 @@
package org.apache.ambari.server.serveraction.kerberos;
+import static org.easymock.EasyMock.anyObject;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay;
+import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
-import org.apache.ambari.server.AmbariException;
import org.apache.ambari.server.configuration.Configuration;
-import org.apache.ambari.server.security.credential.PrincipalKeyCredential;
import org.apache.ambari.server.state.Clusters;
import org.apache.ambari.server.state.stack.OsFamily;
+import org.apache.ambari.server.utils.ShellCommandUtil;
import org.easymock.EasyMock;
import org.junit.BeforeClass;
-import org.junit.Test;
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Injector;
-import junit.framework.Assert;
-
-public class IPAKerberosOperationHandlerTest extends KerberosOperationHandlerTest {
- private static final String DEFAULT_ADMIN_PRINCIPAL = "admin";
- private static final String DEFAULT_ADMIN_PASSWORD = "Hadoop12345";
-
- private static final String DEFAULT_REALM = "IPA01.LOCAL";
-
- private static Injector injector;
-
- private static boolean hasIpa = false;
+public class IPAKerberosOperationHandlerTest extends KDCKerberosOperationHandlerTest {
private static final Map<String, String> KERBEROS_ENV_MAP = new HashMap<String, String>() {
{
@@ -58,8 +48,10 @@ public class IPAKerberosOperationHandlerTest extends KerberosOperationHandlerTes
}
};
+ private static Injector injector;
+
@BeforeClass
- public static void beforeClass() throws AmbariException {
+ public static void beforeIPAKerberosOperationHandlerTest() throws Exception {
injector = Guice.createInjector(new AbstractModule() {
@Override
protected void configure() {
@@ -72,85 +64,74 @@ public class IPAKerberosOperationHandlerTest extends KerberosOperationHandlerTes
bind(OsFamily.class).toInstance(EasyMock.createNiceMock(OsFamily.class));
}
});
- if (System.getenv("HAS_IPA") != null) {
- hasIpa = true;
- }
}
- @Test
- public void testSetPrincipalPasswordExceptions() throws Exception {
- if (!hasIpa) {
- return;
- }
+ @Override
+ protected IPAKerberosOperationHandler createMockedHandler(Method... mockedMethods) {
+ IPAKerberosOperationHandler handler = createMockBuilder(IPAKerberosOperationHandler.class)
+ .addMockedMethods(mockedMethods)
+ .createMock();
+ injector.injectMembers(handler);
+ return handler;
+ }
- IPAKerberosOperationHandler handler = injector.getInstance(IPAKerberosOperationHandler.class);
- handler.open(new PrincipalKeyCredential(DEFAULT_ADMIN_PRINCIPAL, DEFAULT_ADMIN_PASSWORD), DEFAULT_REALM, KERBEROS_ENV_MAP);
- try {
- handler.setPrincipalPassword(DEFAULT_ADMIN_PRINCIPAL, null);
- Assert.fail("KerberosOperationException not thrown for null password");
- } catch (Throwable t) {
- Assert.assertEquals(KerberosOperationException.class, t.getClass());
- }
+ @Override
+ protected Map<String, String> getKerberosEnv() {
+ return KERBEROS_ENV_MAP;
+ }
- try {
- handler.setPrincipalPassword(DEFAULT_ADMIN_PRINCIPAL, "");
- Assert.fail("KerberosOperationException not thrown for empty password");
- handler.createPrincipal("", "1234", false);
- Assert.fail("AmbariException not thrown for empty principal");
- } catch (Throwable t) {
- Assert.assertEquals(KerberosOperationException.class, t.getClass());
+ @Override
+ protected void setupPrincipalAlreadyExists(KerberosOperationHandler handler, boolean service) throws Exception {
+ ShellCommandUtil.Result result = createMock(ShellCommandUtil.Result.class);
+ expect(result.getExitCode()).andReturn(1).anyTimes();
+ expect(result.isSuccessful()).andReturn(false).anyTimes();
+ if(service) {
+ expect(result.getStderr()).andReturn("ipa: ERROR: service with name \"service/host@EXAMPLE.COM\" already exists").anyTimes();
}
-
- try {
- handler.setPrincipalPassword(null, DEFAULT_ADMIN_PASSWORD);
- Assert.fail("KerberosOperationException not thrown for null principal");
- } catch (Throwable t) {
- Assert.assertEquals(KerberosOperationException.class, t.getClass());
+ else {
+ expect(result.getStderr()).andReturn("ipa: ERROR: user with name \"user\" already exists").anyTimes();
}
+ expect(result.getStdout()).andReturn("").anyTimes();
- try {
- handler.setPrincipalPassword("", DEFAULT_ADMIN_PASSWORD);
- Assert.fail("KerberosOperationException not thrown for empty principal");
- } catch (Throwable t) {
- Assert.assertEquals(KerberosOperationException.class, t.getClass());
- }
+ expect(handler.executeCommand(arrayContains(new String[]{"ipa", (service) ? "service-add" : "user-add"}), anyObject(Map.class), anyObject(KDCKerberosOperationHandler.InteractivePasswordHandler.class)))
+ .andReturn(result)
+ .anyTimes();
}
- @Test
- public void testCreateServicePrincipal_Exceptions() throws Exception {
- if (!hasIpa) {
- return;
- }
-
- IPAKerberosOperationHandler handler = new IPAKerberosOperationHandler();
- handler.open(new PrincipalKeyCredential(DEFAULT_ADMIN_PRINCIPAL, DEFAULT_ADMIN_PASSWORD), DEFAULT_REALM, KERBEROS_ENV_MAP);
+ @Override
+ protected void setupPrincipalDoesNotExist(KerberosOperationHandler handler, boolean service) throws Exception {
+ ShellCommandUtil.Result result = createMock(ShellCommandUtil.Result.class);
+ expect(result.getExitCode()).andReturn(2).anyTimes();
+ expect(result.isSuccessful()).andReturn(false).anyTimes();
+ expect(result.getStderr()).andReturn(String.format("ipa: ERROR: %s: user not found", (service) ? "service/host" : "user")).anyTimes();
+ expect(result.getStdout()).andReturn("").anyTimes();
- try {
- handler.createPrincipal(DEFAULT_ADMIN_PRINCIPAL, null, false);
- Assert.fail("KerberosOperationException not thrown for null password");
- } catch (Throwable t) {
- Assert.fail("KerberosOperationException thrown on null password with IPA");
- }
- try {
- handler.createPrincipal(DEFAULT_ADMIN_PRINCIPAL, "", false);
- } catch (Throwable t) {
- Assert.fail("KerberosOperationException thrown for empty password");
- }
-
- try {
- handler.createPrincipal(null, DEFAULT_ADMIN_PASSWORD, false);
- Assert.fail("KerberosOperationException not thrown for null principal");
- } catch (Throwable t) {
- Assert.assertEquals(KerberosOperationException.class, t.getClass());
- }
-
- try {
- handler.createPrincipal("", DEFAULT_ADMIN_PASSWORD, false);
- Assert.fail("KerberosOperationException not thrown for empty principal");
- } catch (Throwable t) {
- Assert.assertEquals(KerberosOperationException.class, t.getClass());
- }
+ expect(handler.executeCommand(arrayContains(new String[]{"ipa", (service) ? "service-show" : "user-show"}), anyObject(Map.class), anyObject(KDCKerberosOperationHandler.InteractivePasswordHandler.class)))
+ .andReturn(result)
+ .anyTimes();
}
+ @Override
+ protected void setupPrincipalExists(KerberosOperationHandler handler, boolean service) throws Exception {
+ ShellCommandUtil.Result result = createMock(ShellCommandUtil.Result.class);
+ expect(result.getExitCode()).andReturn(0).anyTimes();
+ expect(result.isSuccessful()).andReturn(true).anyTimes();
+ expect(result.getStderr()).andReturn("").anyTimes();
+ expect(result.getStdout()).andReturn(String.format(" User login: %s\n" +
+ " Last name: User\n" +
+ " Home directory: /home/user\n" +
+ " Login shell: /bin/bash\n" +
+ " Principal alias: user@EXAMPLE.COM\n" +
+ " UID: 324200000\n" +
+ " GID: 324200000\n" +
+ " Account disabled: False\n" +
+ " Password: True\n" +
+ " Member of groups: users\n" +
+ " Kerberos keys available: True", (service) ? "service/host" : "user")).anyTimes();
+
+ expect(handler.executeCommand(arrayContains(new String[]{"ipa", (service) ? "service-show" : "user-show"}), anyObject(Map.class), anyObject(KDCKerberosOperationHandler.InteractivePasswordHandler.class)))
+ .andReturn(result)
+ .anyTimes();
+ }
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/f844e5f3/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/KDCKerberosOperationHandlerTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/KDCKerberosOperationHandlerTest.java b/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/KDCKerberosOperationHandlerTest.java
new file mode 100644
index 0000000..271c787
--- /dev/null
+++ b/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/KDCKerberosOperationHandlerTest.java
@@ -0,0 +1,152 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.server.serveraction.kerberos;
+
+import static org.easymock.EasyMock.anyObject;
+import static org.easymock.EasyMock.expect;
+
+import java.lang.reflect.Method;
+import java.util.Map;
+
+import org.apache.ambari.server.utils.ShellCommandUtil;
+import org.apache.commons.lang.StringUtils;
+import org.easymock.EasyMock;
+import org.easymock.IArgumentMatcher;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import junit.framework.Assert;
+
+abstract public class KDCKerberosOperationHandlerTest extends KerberosOperationHandlerTest {
+
+ static Method methodExecuteCommand;
+
+ @BeforeClass
+ public static void beforeKDCKerberosOperationHandlerTest() throws Exception {
+ methodExecuteCommand = KDCKerberosOperationHandler.class.getDeclaredMethod("executeCommand", String[].class, Map.class, ShellCommandUtil.InteractiveHandler.class);
+ }
+
+ @Test
+ public void testInteractivePasswordHandler() {
+ KDCKerberosOperationHandler.InteractivePasswordHandler handler = new KDCKerberosOperationHandler.InteractivePasswordHandler("admin_password", "user_password");
+
+ handler.start();
+ Assert.assertEquals("admin_password", handler.getResponse("password"));
+ Assert.assertFalse(handler.done());
+ Assert.assertEquals("user_password", handler.getResponse("password"));
+ Assert.assertFalse(handler.done());
+ Assert.assertEquals("user_password", handler.getResponse("password"));
+ Assert.assertTrue(handler.done());
+
+ // Test restarting
+ handler.start();
+ Assert.assertEquals("admin_password", handler.getResponse("password"));
+ Assert.assertFalse(handler.done());
+ Assert.assertEquals("user_password", handler.getResponse("password"));
+ Assert.assertFalse(handler.done());
+ Assert.assertEquals("user_password", handler.getResponse("password"));
+ Assert.assertTrue(handler.done());
+ }
+
+ @Override
+ protected KerberosOperationHandler createMockedHandler() throws KerberosOperationException {
+ return createMockedHandler(methodExecuteCommand);
+ }
+
+ @Override
+ protected void setupOpenSuccess(KerberosOperationHandler handler) throws Exception {
+ ShellCommandUtil.Result result = createMock(ShellCommandUtil.Result.class);
+ expect(result.isSuccessful()).andReturn(true);
+
+ expect(handler.executeCommand(arrayContains("/usr/bin/kinit"), anyObject(Map.class), anyObject(KDCKerberosOperationHandler.InteractivePasswordHandler.class)))
+ .andReturn(result)
+ .anyTimes();
+ }
+
+ @Override
+ protected void setupOpenFailure(KerberosOperationHandler handler) throws Exception {
+ ShellCommandUtil.Result result = createMock(ShellCommandUtil.Result.class);
+ expect(result.isSuccessful()).andReturn(false).once();
+ expect(result.getExitCode()).andReturn(-1).once();
+ expect(result.getStdout()).andReturn("STDOUT data").once();
+ expect(result.getStderr()).andReturn("STDERR data").once();
+
+ expect(handler.executeCommand(arrayContains("/usr/bin/kinit"), anyObject(Map.class), anyObject(KDCKerberosOperationHandler.InteractivePasswordHandler.class)))
+ .andReturn(result)
+ .anyTimes();
+ }
+
+ protected abstract KDCKerberosOperationHandler createMockedHandler(Method... mockedMethods);
+
+ public static class ArrayContains implements IArgumentMatcher {
+
+ private String[] startItems;
+
+ ArrayContains(String startItem) {
+ this.startItems = new String[]{startItem};
+ }
+
+ ArrayContains(String[] startItems) {
+ this.startItems = startItems;
+ }
+
+ @Override
+ public boolean matches(Object o) {
+ if (o instanceof String[]) {
+ String[] array = (String[]) o;
+
+ for (String item : startItems) {
+ boolean valueContains = false;
+ for (String value : array) {
+ if (value.contains(item)) {
+ valueContains = true;
+ break;
+ }
+ }
+
+ if (!valueContains) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ return false;
+ }
+
+ @Override
+ public void appendTo(StringBuffer stringBuffer) {
+ stringBuffer.append("arrayContains(");
+ stringBuffer.append(StringUtils.join(startItems, ", "));
+ stringBuffer.append("\")");
+ }
+ }
+
+ static String[] arrayContains(String in) {
+ EasyMock.reportMatcher(new ArrayContains(in));
+ return null;
+ }
+
+ static String[] arrayContains(String[] in) {
+ EasyMock.reportMatcher(new ArrayContains(in));
+ return null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/f844e5f3/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/KerberosOperationHandlerTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/KerberosOperationHandlerTest.java b/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/KerberosOperationHandlerTest.java
index 88c841c..9d1e8e0 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/KerberosOperationHandlerTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/KerberosOperationHandlerTest.java
@@ -40,10 +40,128 @@ import junit.framework.Assert;
public abstract class KerberosOperationHandlerTest extends EasyMockSupport {
+ static final String DEFAULT_ADMIN_PRINCIPAL = "admin";
+ static final String DEFAULT_ADMIN_PASSWORD = "hadoop";
+ static final String DEFAULT_REALM = "EXAMPLE.COM";
+ static final PrincipalKeyCredential DEFAULT_ADMIN_CREDENTIALS = new PrincipalKeyCredential(DEFAULT_ADMIN_PRINCIPAL, DEFAULT_ADMIN_PASSWORD);
+
@Rule
public TemporaryFolder folder = new TemporaryFolder();
@Test
+ public void testOpenSucceeded() throws Exception {
+ KerberosOperationHandler handler = createMockedHandler();
+
+ setupOpenSuccess(handler);
+
+ replayAll();
+
+ handler.open(getAdminCredentials(), DEFAULT_REALM, getKerberosEnv());
+
+ verifyAll();
+
+ Assert.assertTrue(handler.isOpen());
+ }
+
+ @Test
+ public void testOpenFailed() throws Exception {
+ KerberosOperationHandler handler = createMockedHandler();
+
+ setupOpenFailure(handler);
+
+ replayAll();
+
+ try {
+ handler.open(getAdminCredentials(), DEFAULT_REALM, getKerberosEnv());
+ Assert.fail("KerberosAdminAuthenticationException expected");
+ } catch (KerberosAdminAuthenticationException e) {
+ // This is expected
+ }
+
+ verifyAll();
+
+ Assert.assertFalse(handler.isOpen());
+ }
+
+ @Test(expected = KerberosPrincipalAlreadyExistsException.class)
+ public void testCreateUserPrincipalPrincipalAlreadyExists() throws Exception {
+ testCreatePrincipalPrincipalAlreadyExists(false);
+ }
+
+ @Test(expected = KerberosPrincipalAlreadyExistsException.class)
+ public void testCreateServicePrincipalPrincipalAlreadyExists() throws Exception {
+ testCreatePrincipalPrincipalAlreadyExists(true);
+ }
+
+ private void testCreatePrincipalPrincipalAlreadyExists(boolean service) throws Exception {
+ KerberosOperationHandler handler = createMockedHandler();
+
+ setupOpenSuccess(handler);
+ setupPrincipalAlreadyExists(handler, service);
+
+ replayAll();
+
+ handler.open(getAdminCredentials(), DEFAULT_REALM, getKerberosEnv());
+ handler.createPrincipal(createPrincipal(service), "password", service);
+ handler.close();
+
+ verifyAll();
+
+ }
+
+
+ @Test
+ public void testUserPrincipalExistsNotFound() throws Exception {
+ testPrincipalExistsNotFound(false);
+ }
+
+ @Test
+ public void testServicePrincipalExistsNotFound() throws Exception {
+ testPrincipalExistsNotFound(true);
+ }
+
+ private void testPrincipalExistsNotFound(boolean service) throws Exception {
+ KerberosOperationHandler handler = createMockedHandler();
+
+ setupOpenSuccess(handler);
+ setupPrincipalDoesNotExist(handler, service);
+
+ replayAll();
+
+ handler.open(getAdminCredentials(), DEFAULT_REALM, getKerberosEnv());
+ Assert.assertFalse(handler.principalExists(createPrincipal(service), service));
+ handler.close();
+
+ verifyAll();
+ }
+
+ @Test
+ public void testUserPrincipalExistsFound() throws Exception {
+ testPrincipalExistsFound(false);
+ }
+
+ @Test
+ public void testServicePrincipalExistsFound() throws Exception {
+ testPrincipalExistsFound(true);
+ }
+
+ private void testPrincipalExistsFound(boolean service) throws Exception {
+ KerberosOperationHandler handler = createMockedHandler();
+
+ setupOpenSuccess(handler);
+ setupPrincipalExists(handler, service);
+
+ replayAll();
+
+ handler.open(getAdminCredentials(), DEFAULT_REALM, getKerberosEnv());
+ Assert.assertTrue(handler.principalExists(createPrincipal(service), service));
+ handler.close();
+
+ verifyAll();
+
+ }
+
+ @Test
public void testCreateKeytabFileOneAtATime() throws Exception {
KerberosOperationHandler handler = createHandler();
File file = folder.newFile();
@@ -285,7 +403,7 @@ public abstract class KerberosOperationHandlerTest extends EasyMockSupport {
public void testAdminCredentialsNullCredential() throws KerberosOperationException {
KerberosOperationHandler handler = createHandler();
- PrincipalKeyCredential credentials = new PrincipalKeyCredential("principal", (char[])null);
+ PrincipalKeyCredential credentials = new PrincipalKeyCredential("principal", (char[]) null);
handler.setAdministratorCredential(credentials);
}
@@ -301,10 +419,10 @@ public abstract class KerberosOperationHandlerTest extends EasyMockSupport {
public void testSetExecutableSearchPaths() throws KerberosOperationException {
KerberosOperationHandler handler = createHandler();
- handler.setExecutableSearchPaths((String)null);
+ handler.setExecutableSearchPaths((String) null);
Assert.assertNull(handler.getExecutableSearchPaths());
- handler.setExecutableSearchPaths((String[])null);
+ handler.setExecutableSearchPaths((String[]) null);
Assert.assertNull(handler.getExecutableSearchPaths());
handler.setExecutableSearchPaths("");
@@ -341,6 +459,24 @@ public abstract class KerberosOperationHandlerTest extends EasyMockSupport {
Assert.assertEquals("path3/", handler.getExecutableSearchPaths()[2]);
}
+ protected abstract KerberosOperationHandler createMockedHandler() throws KerberosOperationException;
+
+ protected abstract void setupOpenSuccess(KerberosOperationHandler handler) throws Exception;
+
+ protected abstract void setupOpenFailure(KerberosOperationHandler handler) throws Exception;
+
+ protected abstract void setupPrincipalAlreadyExists(KerberosOperationHandler handler, boolean service) throws Exception;
+
+ protected abstract void setupPrincipalDoesNotExist(KerberosOperationHandler handler, boolean service) throws Exception;
+
+ protected abstract void setupPrincipalExists(KerberosOperationHandler handler, boolean service) throws Exception;
+
+ protected abstract Map<String, String> getKerberosEnv();
+
+ protected PrincipalKeyCredential getAdminCredentials() {
+ return DEFAULT_ADMIN_CREDENTIALS;
+ }
+
private KerberosOperationHandler createHandler() throws KerberosOperationException {
KerberosOperationHandler handler = new KerberosOperationHandler() {
@@ -357,7 +493,7 @@ public abstract class KerberosOperationHandlerTest extends EasyMockSupport {
}
@Override
- public boolean principalExists(String principal) throws KerberosOperationException {
+ public boolean principalExists(String principal, boolean service) throws KerberosOperationException {
return false;
}
@@ -367,12 +503,12 @@ public abstract class KerberosOperationHandlerTest extends EasyMockSupport {
}
@Override
- public Integer setPrincipalPassword(String principal, String password) throws KerberosOperationException {
+ public Integer setPrincipalPassword(String principal, String password, boolean service) throws KerberosOperationException {
return 0;
}
@Override
- public boolean removePrincipal(String principal) throws KerberosOperationException {
+ public boolean removePrincipal(String principal, boolean service) throws KerberosOperationException {
return false;
}
};
@@ -380,4 +516,8 @@ public abstract class KerberosOperationHandlerTest extends EasyMockSupport {
handler.open(new PrincipalKeyCredential("admin/admin", "hadoop"), "EXAMPLE.COM", null);
return handler;
}
+
+ private String createPrincipal(boolean service) {
+ return String.format("%s@%s", (service) ? "service/host" : "user", DEFAULT_REALM);
+ }
}