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 2018/07/30 22:23:37 UTC
[ambari] branch branch-2.7 updated: [AMBARI-24384] Logic and
declaration used to determine if Kerberos is enabled for a service
This is an automated email from the ASF dual-hosted git repository.
rlevas pushed a commit to branch branch-2.7
in repository https://gitbox.apache.org/repos/asf/ambari.git
The following commit(s) were added to refs/heads/branch-2.7 by this push:
new 1372f03 [AMBARI-24384] Logic and declaration used to determine if Kerberos is enabled for a service
1372f03 is described below
commit 1372f03a0b19457467002c8eea5f900b9fbb1e86
Author: Robert Levas <rl...@hortonworks.com>
AuthorDate: Mon Jul 30 16:43:56 2018 -0400
[AMBARI-24384] Logic and declaration used to determine if Kerberos is enabled for a service
---
.../ambari/server/controller/ServiceResponse.java | 21 ++-
.../internal/ServiceResourceProvider.java | 6 +
.../org/apache/ambari/server/state/Service.java | 19 +++
.../apache/ambari/server/state/ServiceImpl.java | 178 +++++++++++++--------
.../apache/ambari/server/state/ServiceInfo.java | 32 ++++
.../ambari/server/state/ServiceInfoTest.java | 57 +++++++
.../apache/ambari/server/state/ServiceTest.java | 56 +++++++
.../stacks/HDP/0.1/services/HDFS/metainfo.xml | 19 +++
8 files changed, 319 insertions(+), 69 deletions(-)
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/ServiceResponse.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/ServiceResponse.java
index 7502f50..a0f8a56 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/ServiceResponse.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/ServiceResponse.java
@@ -40,12 +40,14 @@ public class ServiceResponse {
private final boolean ssoIntegrationDesired;
private final boolean ssoIntegrationEnabled;
private final boolean ssoIntegrationRequiresKerberos;
+ private final boolean kerberosEnabled;
public ServiceResponse(Long clusterId, String clusterName, String serviceName,
StackId desiredStackId, String desiredRepositoryVersion,
RepositoryVersionState repositoryVersionState, String desiredState,
boolean credentialStoreSupported, boolean credentialStoreEnabled, boolean ssoIntegrationSupported,
- boolean ssoIntegrationDesired, boolean ssoIntegrationEnabled, boolean ssoIntegrationRequiresKerberos) {
+ boolean ssoIntegrationDesired, boolean ssoIntegrationEnabled, boolean ssoIntegrationRequiresKerberos,
+ boolean kerberosEnabled) {
this.clusterId = clusterId;
this.clusterName = clusterName;
this.serviceName = serviceName;
@@ -59,10 +61,9 @@ public class ServiceResponse {
this.credentialStoreSupported = credentialStoreSupported;
this.credentialStoreEnabled = credentialStoreEnabled;
this.ssoIntegrationRequiresKerberos = ssoIntegrationRequiresKerberos;
+ this.kerberosEnabled = kerberosEnabled;
}
-
-
/**
* @return the serviceName
*/
@@ -231,7 +232,7 @@ public class ServiceResponse {
@Override
public int hashCode() {
- int result = clusterId != null? clusterId.intValue() : 0;
+ int result = clusterId != null ? clusterId.intValue() : 0;
result = 71 * result + (clusterName != null ? clusterName.hashCode() : 0);
result = 71 * result + (serviceName != null ? serviceName.hashCode() : 0);
return result;
@@ -270,6 +271,14 @@ public class ServiceResponse {
}
/**
+ * Indicates whether the service is configured for Kerberos or not
+ */
+ @ApiModelProperty(name = "kerberos_enabled")
+ public boolean isKerberosEnabled() {
+ return kerberosEnabled;
+ }
+
+ /**
* Interface to help correct Swagger documentation generation
*/
public interface ServiceResponseSwagger extends ApiModel {
@@ -278,14 +287,14 @@ public class ServiceResponse {
}
/**
- * @param id
+ * @param id the desired repository id
*/
public void setDesiredRepositoryVersionId(Long id) {
desiredRepositoryVersionId = id;
}
/**
- * @param id
+ * @return the desired repository id
*/
public Long getDesiredRepositoryVersionId() {
return desiredRepositoryVersionId;
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ServiceResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ServiceResourceProvider.java
index cb9ef00..7302833 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ServiceResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ServiceResourceProvider.java
@@ -133,6 +133,9 @@ public class ServiceResourceProvider extends AbstractControllerResourceProvider
private static final String SSO_INTEGRATION_REQUIRES_KERBEROS_PROPERTY_ID = PropertyHelper.getPropertyId(
"ServiceInfo", "sso_integration_requires_kerberos");
+ private static final String KERBEROS_ENABLED_PROPERTY_ID = PropertyHelper.getPropertyId(
+ "ServiceInfo", "kerberos_enabled");
+
protected static final String SERVICE_REPOSITORY_STATE = "ServiceInfo/repository_state";
//Parameters from the predicate
@@ -176,6 +179,7 @@ public class ServiceResourceProvider extends AbstractControllerResourceProvider
PROPERTY_IDS.add(SSO_INTEGRATION_ENABLED_PROPERTY_ID);
PROPERTY_IDS.add(SSO_INTEGRATION_DESIRED_PROPERTY_ID);
PROPERTY_IDS.add(SSO_INTEGRATION_REQUIRES_KERBEROS_PROPERTY_ID);
+ PROPERTY_IDS.add(KERBEROS_ENABLED_PROPERTY_ID);
// keys
KEY_PROPERTY_IDS.put(Resource.Type.Service, SERVICE_SERVICE_NAME_PROPERTY_ID);
@@ -301,6 +305,8 @@ public class ServiceResourceProvider extends AbstractControllerResourceProvider
response.isSsoIntegrationDesired(), requestedIds);
setResourceProperty(resource, SSO_INTEGRATION_REQUIRES_KERBEROS_PROPERTY_ID,
response.isSsoIntegrationRequiresKerberos(), requestedIds);
+ setResourceProperty(resource, KERBEROS_ENABLED_PROPERTY_ID,
+ response.isKerberosEnabled(), requestedIds);
Map<String, Object> serviceSpecificProperties = getServiceSpecificProperties(
response.getClusterName(), response.getServiceName(), requestedIds);
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/Service.java b/ambari-server/src/main/java/org/apache/ambari/server/state/Service.java
index b6203f9..186c9ec 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/Service.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/Service.java
@@ -90,6 +90,25 @@ public interface Service {
MaintenanceState getMaintenanceState();
/**
+ * Tests to see if Kerberos is enabled for this service using the Kerberos enabled test metadata
+ * and the existing cluster configurations.
+ *
+ * @return <code>true</code>. if it is determined that Kerberos is enabled for this service; <code>false</code>, otherwise
+ * @see #isKerberosEnabled(Map)
+ */
+ boolean isKerberosEnabled();
+
+ /**
+ * Tests to see if Kerberos is enabled for this service using the Kerberos enabled test metadata
+ * and the supplied configurations map.
+ *
+ * @param configurations a map of configurations to use for the test
+ * @return <code>true</code>. if it is determined that Kerberos is enabled for this service; <code>false</code>, otherwise
+ * @see #isKerberosEnabled()
+ */
+ boolean isKerberosEnabled(Map<String, Map<String, String>> configurations);
+
+ /**
* Refresh Service info due to current stack
* @throws AmbariException
*/
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceImpl.java
index 52d4a23..23f3067 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceImpl.java
@@ -20,6 +20,7 @@ package org.apache.ambari.server.state;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@@ -32,7 +33,6 @@ import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import org.apache.ambari.server.AmbariException;
-import org.apache.ambari.server.AmbariRuntimeException;
import org.apache.ambari.server.ObjectNotFoundException;
import org.apache.ambari.server.ServiceComponentNotFoundException;
import org.apache.ambari.server.api.services.AmbariMetaInfo;
@@ -86,8 +86,9 @@ public class ServiceImpl implements Service {
private boolean isCredentialStoreSupported;
private boolean isCredentialStoreRequired;
private final boolean ssoIntegrationSupported;
- private final Predicate ssoEnabledConfiguration;
+ private final Predicate ssoEnabledTest;
private final boolean ssoRequiresKerberos;
+ private final Predicate kerberosEnabledTest;
private AmbariMetaInfo ambariMetaInfo;
private AtomicReference<MaintenanceState> maintenanceState = new AtomicReference<>();
@@ -121,10 +122,10 @@ public class ServiceImpl implements Service {
@AssistedInject
ServiceImpl(@Assisted Cluster cluster, @Assisted String serviceName,
- @Assisted RepositoryVersionEntity desiredRepositoryVersion, ClusterDAO clusterDAO,
- ClusterServiceDAO clusterServiceDAO, ServiceDesiredStateDAO serviceDesiredStateDAO,
- ServiceComponentFactory serviceComponentFactory, AmbariMetaInfo ambariMetaInfo,
- AmbariEventPublisher eventPublisher) throws AmbariException {
+ @Assisted RepositoryVersionEntity desiredRepositoryVersion, ClusterDAO clusterDAO,
+ ClusterServiceDAO clusterServiceDAO, ServiceDesiredStateDAO serviceDesiredStateDAO,
+ ServiceComponentFactory serviceComponentFactory, AmbariMetaInfo ambariMetaInfo,
+ AmbariEventPublisher eventPublisher) throws AmbariException {
this.cluster = cluster;
this.clusterDAO = clusterDAO;
this.clusterServiceDAO = clusterServiceDAO;
@@ -157,32 +158,26 @@ public class ServiceImpl implements Service {
isCredentialStoreSupported = sInfo.isCredentialStoreSupported();
isCredentialStoreRequired = sInfo.isCredentialStoreRequired();
ssoIntegrationSupported = sInfo.isSingleSignOnSupported();
- ssoEnabledConfiguration = compileSsoEnabledPredicate(sInfo);
+ ssoEnabledTest = compileSsoEnabledPredicate(sInfo);
ssoRequiresKerberos = sInfo.isKerberosRequiredForSingleSignOnIntegration();
+ kerberosEnabledTest = compileKerberosEnabledPredicate(sInfo);
- persist(serviceEntity);
- }
-
- private Predicate compileSsoEnabledPredicate(ServiceInfo sInfo) {
- if (StringUtils.isNotBlank(sInfo.getSingleSignOnEnabledTest())) {
- if (StringUtils.isNotBlank(sInfo.getSingleSignOnEnabledConfiguration())) {
- LOG.warn("Both <ssoEnabledTest> and <enabledConfiguration> have been declared within <sso> for {}; using <ssoEnabledTest>", serviceName);
- }
- return PredicateUtils.fromJSON(sInfo.getSingleSignOnEnabledTest());
- } else if (StringUtils.isNotBlank(sInfo.getSingleSignOnEnabledConfiguration())) {
- LOG.warn("Only <enabledConfiguration> have been declared within <sso> for {}; converting its value to an equals predicate", serviceName);
- final String equalsPredicateJson = "{\"equals\": [\"" + sInfo.getSingleSignOnEnabledConfiguration() + "\", \"true\"]}";
- return PredicateUtils.fromJSON(equalsPredicateJson);
+ if (ssoIntegrationSupported && ssoRequiresKerberos && (kerberosEnabledTest == null)) {
+ LOG.warn("The service, {}, requires Kerberos to be enabled for SSO integration support; " +
+ "however, the kerberosEnabledTest specification has not been specified in the metainfo.xml file. " +
+ "Automated SSO integration will not be allowed for this service.",
+ serviceName);
}
- return null;
+
+ persist(serviceEntity);
}
@AssistedInject
ServiceImpl(@Assisted Cluster cluster, @Assisted ClusterServiceEntity serviceEntity,
- ClusterDAO clusterDAO, ClusterServiceDAO clusterServiceDAO,
- ServiceDesiredStateDAO serviceDesiredStateDAO,
- ServiceComponentFactory serviceComponentFactory, AmbariMetaInfo ambariMetaInfo,
- AmbariEventPublisher eventPublisher) throws AmbariException {
+ ClusterDAO clusterDAO, ClusterServiceDAO clusterServiceDAO,
+ ServiceDesiredStateDAO serviceDesiredStateDAO,
+ ServiceComponentFactory serviceComponentFactory, AmbariMetaInfo ambariMetaInfo,
+ AmbariEventPublisher eventPublisher) throws AmbariException {
this.cluster = cluster;
this.clusterDAO = clusterDAO;
this.clusterServiceDAO = clusterServiceDAO;
@@ -200,16 +195,16 @@ public class ServiceImpl implements Service {
for (ServiceComponentDesiredStateEntity serviceComponentDesiredStateEntity
: serviceEntity.getServiceComponentDesiredStateEntities()) {
try {
- components.put(serviceComponentDesiredStateEntity.getComponentName(),
- serviceComponentFactory.createExisting(this,
- serviceComponentDesiredStateEntity));
- } catch(ProvisionException ex) {
- StackId stackId = new StackId(serviceComponentDesiredStateEntity.getDesiredStack());
- LOG.error(String.format("Can not get component info: stackName=%s, stackVersion=%s, serviceName=%s, componentName=%s",
- stackId.getStackName(), stackId.getStackVersion(),
- serviceEntity.getServiceName(),serviceComponentDesiredStateEntity.getComponentName()));
- ex.printStackTrace();
- }
+ components.put(serviceComponentDesiredStateEntity.getComponentName(),
+ serviceComponentFactory.createExisting(this,
+ serviceComponentDesiredStateEntity));
+ } catch (ProvisionException ex) {
+ StackId stackId = new StackId(serviceComponentDesiredStateEntity.getDesiredStack());
+ LOG.error(String.format("Can not get component info: stackName=%s, stackVersion=%s, serviceName=%s, componentName=%s",
+ stackId.getStackName(), stackId.getStackVersion(),
+ serviceEntity.getServiceName(), serviceComponentDesiredStateEntity.getComponentName()));
+ ex.printStackTrace();
+ }
}
}
@@ -221,8 +216,16 @@ public class ServiceImpl implements Service {
isCredentialStoreRequired = sInfo.isCredentialStoreRequired();
displayName = sInfo.getDisplayName();
ssoIntegrationSupported = sInfo.isSingleSignOnSupported();
- ssoEnabledConfiguration = compileSsoEnabledPredicate(sInfo);
+ ssoEnabledTest = compileSsoEnabledPredicate(sInfo);
ssoRequiresKerberos = sInfo.isKerberosRequiredForSingleSignOnIntegration();
+ kerberosEnabledTest = compileKerberosEnabledPredicate(sInfo);
+
+ if (ssoIntegrationSupported && ssoRequiresKerberos && (kerberosEnabledTest == null)) {
+ LOG.warn("The service, {}, requires Kerberos to be enabled for SSO integration support; " +
+ "however, the kerberosEnabledTest specification has not been specified in the metainfo.xml file. " +
+ "Automated SSO integration will not be allowed for this service.",
+ serviceName);
+ }
}
@@ -241,10 +244,10 @@ public class ServiceImpl implements Service {
} catch (ObjectNotFoundException e) {
throw new RuntimeException("Trying to create a ServiceInfo"
- + " not recognized in stack info"
- + ", clusterName=" + cluster.getClusterName()
- + ", serviceName=" + getName()
- + ", stackInfo=" + getDesiredStackId().getStackName());
+ + " not recognized in stack info"
+ + ", clusterName=" + cluster.getClusterName()
+ + ", serviceName=" + getName()
+ + ", stackInfo=" + getDesiredStackId().getStackName());
}
}
@@ -271,7 +274,7 @@ public class ServiceImpl implements Service {
@Override
public Set<String> getServiceHosts() {
Set<String> hostNames = new HashSet<>();
- for (ServiceComponent serviceComponent : getServiceComponents().values()) {
+ for (ServiceComponent serviceComponent : getServiceComponents().values()) {
hostNames.addAll(serviceComponent.getServiceComponentsHosts());
}
return hostNames;
@@ -328,7 +331,7 @@ public class ServiceImpl implements Service {
public void setDesiredState(State state) {
if (LOG.isDebugEnabled()) {
LOG.debug("Setting DesiredState of Service, clusterName={}, clusterId={}, serviceName={}, oldDesiredState={}, newDesiredState={}",
- cluster.getClusterName(), cluster.getClusterId(), getName(), getDesiredState(), state);
+ cluster.getClusterName(), cluster.getClusterId(), getName(), getDesiredState(), state);
}
ServiceDesiredStateEntity serviceDesiredStateEntity = getServiceDesiredStateEntity();
@@ -386,7 +389,7 @@ public class ServiceImpl implements Service {
}
List<RepositoryVersionState> states = new ArrayList<>();
- for( ServiceComponent component : components.values() ){
+ for (ServiceComponent component : components.values()) {
states.add(component.getRepositoryState());
}
@@ -398,10 +401,20 @@ public class ServiceImpl implements Service {
RepositoryVersionEntity desiredRespositoryVersion = getDesiredRepositoryVersion();
StackId desiredStackId = desiredRespositoryVersion.getStackId();
+ Map<String, Map<String, String>> existingConfigurations;
+
+ try {
+ existingConfigurations = configHelper.calculateExistingConfigurations(ambariManagementController, cluster);
+ } catch (AmbariException e) {
+ LOG.warn("Failed to get the existing configurations for the cluster. Predicate calculations may not be correct due to missing data.");
+ existingConfigurations = Collections.emptyMap();
+ }
+
ServiceResponse r = new ServiceResponse(cluster.getClusterId(), cluster.getClusterName(),
getName(), desiredStackId, desiredRespositoryVersion.getVersion(), getRepositoryState(),
getDesiredState().toString(), isCredentialStoreSupported(), isCredentialStoreEnabled(),
- ssoIntegrationSupported, isSsoIntegrationDesired(), isSsoIntegrationEnabled(), isKerberosRequredForSsoIntegration());
+ ssoIntegrationSupported, isSsoIntegrationDesired(), isSsoIntegrationEnabled(existingConfigurations),
+ isKerberosRequiredForSsoIntegration(), isKerberosEnabled(existingConfigurations));
r.setDesiredRepositoryVersionId(desiredRespositoryVersion.getId());
@@ -451,7 +464,7 @@ public class ServiceImpl implements Service {
return desiredStateEntity.isCredentialStoreEnabled();
} else {
LOG.warn("Trying to fetch a member from an entity object that may " +
- "have been previously deleted, serviceName = " + getName());
+ "have been previously deleted, serviceName = " + getName());
}
return false;
}
@@ -467,7 +480,7 @@ public class ServiceImpl implements Service {
public void setCredentialStoreEnabled(boolean credentialStoreEnabled) {
if (LOG.isDebugEnabled()) {
LOG.debug("Setting CredentialStoreEnabled of Service, clusterName={}, clusterId={}, serviceName={}, oldCredentialStoreEnabled={}, newCredentialStoreEnabled={}",
- cluster.getClusterName(), cluster.getClusterId(), getName(), isCredentialStoreEnabled(), credentialStoreEnabled);
+ cluster.getClusterName(), cluster.getClusterId(), getName(), isCredentialStoreEnabled(), credentialStoreEnabled);
}
ServiceDesiredStateEntity desiredStateEntity = getServiceDesiredStateEntity();
@@ -479,7 +492,7 @@ public class ServiceImpl implements Service {
StackId stackId = getDesiredStackId();
serviceCredentialStoreUpdateEvent =
new ServiceCredentialStoreUpdateEvent(getClusterId(), stackId.getStackName(),
- stackId.getStackVersion(), getName());
+ stackId.getStackVersion(), getName());
}
desiredStateEntity.setCredentialStoreEnabled(credentialStoreEnabled);
desiredStateEntity = serviceDesiredStateDAO.merge(desiredStateEntity);
@@ -490,18 +503,18 @@ public class ServiceImpl implements Service {
}
} else {
LOG.warn("Setting a member on an entity object that may have been "
- + "previously deleted, serviceName = " + getName());
+ + "previously deleted, serviceName = " + getName());
}
}
@Override
public void debugDump(StringBuilder sb) {
sb.append("Service={ serviceName=").append(getName())
- .append(", clusterName=").append(cluster.getClusterName())
- .append(", clusterId=").append(cluster.getClusterId())
- .append(", desiredStackVersion=").append(getDesiredStackId())
- .append(", desiredState=").append(getDesiredState())
- .append(", components=[ ");
+ .append(", clusterName=").append(cluster.getClusterName())
+ .append(", clusterId=").append(cluster.getClusterId())
+ .append(", desiredStackVersion=").append(getDesiredStackId())
+ .append(", desiredState=").append(getDesiredState())
+ .append(", components=[ ");
boolean first = true;
for (ServiceComponent sc : components.values()) {
if (!first) {
@@ -578,7 +591,7 @@ public class ServiceImpl implements Service {
LOG.info("Deleting all configuration associations for {} on cluster {}", getName(), cluster.getClusterName());
List<ServiceConfigEntity> serviceConfigEntities =
- serviceConfigDAO.findByService(cluster.getClusterId(), getName());
+ serviceConfigDAO.findByService(cluster.getClusterId(), getName());
for (ServiceConfigEntity serviceConfigEntity : serviceConfigEntities) {
// Only delete the historical version information and not original
@@ -710,6 +723,29 @@ public class ServiceImpl implements Service {
return maintenanceState.get();
}
+ @Override
+ public boolean isKerberosEnabled() {
+ if (kerberosEnabledTest != null) {
+ Map<String, Map<String, String>> existingConfigurations;
+
+ try {
+ existingConfigurations = configHelper.calculateExistingConfigurations(ambariManagementController, cluster);
+ } catch (AmbariException e) {
+ LOG.warn("Failed to get the existing configurations for the cluster. Predicate calculations may not be correct due to missing data.");
+ existingConfigurations = Collections.emptyMap();
+ }
+ return isKerberosEnabled(existingConfigurations);
+ }
+
+ return false;
+ }
+
+ @Override
+ public boolean isKerberosEnabled(Map<String, Map<String, String>> configurations) {
+ return kerberosEnabledTest != null && kerberosEnabledTest.evaluate(configurations);
+ }
+
+
private ClusterServiceEntityPK getServiceEntityPK(ClusterServiceEntity serviceEntity) {
ClusterServiceEntityPK pk = new ClusterServiceEntityPK();
pk.setClusterId(serviceEntity.getClusterId());
@@ -729,20 +765,36 @@ public class ServiceImpl implements Service {
return serviceDesiredStateDAO.findByPK(serviceDesiredStateEntityPK);
}
- public boolean isSsoIntegrationDesired() {
- return ambariServerConfigurationHandler.getSSOEnabledServices().contains(serviceName);
+ private Predicate compileSsoEnabledPredicate(ServiceInfo sInfo) {
+ if (StringUtils.isNotBlank(sInfo.getSingleSignOnEnabledTest())) {
+ if (StringUtils.isNotBlank(sInfo.getSingleSignOnEnabledConfiguration())) {
+ LOG.warn("Both <ssoEnabledTest> and <enabledConfiguration> have been declared within <sso> for {}; using <ssoEnabledTest>", serviceName);
+ }
+ return PredicateUtils.fromJSON(sInfo.getSingleSignOnEnabledTest());
+ } else if (StringUtils.isNotBlank(sInfo.getSingleSignOnEnabledConfiguration())) {
+ LOG.warn("Only <enabledConfiguration> have been declared within <sso> for {}; converting its value to an equals predicate", serviceName);
+ final String equalsPredicateJson = "{\"equals\": [\"" + sInfo.getSingleSignOnEnabledConfiguration() + "\", \"true\"]}";
+ return PredicateUtils.fromJSON(equalsPredicateJson);
+ }
+ return null;
}
- public boolean isSsoIntegrationEnabled() {
- try {
- return ssoIntegrationSupported && ssoEnabledConfiguration != null && ssoEnabledConfiguration.evaluate(configHelper.calculateExistingConfigurations(ambariManagementController, cluster));
- } catch (AmbariException e) {
- throw new AmbariRuntimeException("Error while evaulating if SSO integration is enabled", e);
+ private Predicate compileKerberosEnabledPredicate(ServiceInfo sInfo) {
+ if (StringUtils.isNotBlank(sInfo.getKerberosEnabledTest())) {
+ return PredicateUtils.fromJSON(sInfo.getKerberosEnabledTest());
}
+ return null;
}
- private boolean isKerberosRequredForSsoIntegration() {
- return ssoRequiresKerberos;
+ private boolean isSsoIntegrationDesired() {
+ return ambariServerConfigurationHandler.getSSOEnabledServices().contains(serviceName);
}
+ private boolean isSsoIntegrationEnabled(Map<String, Map<String, String>> existingConfigurations) {
+ return ssoIntegrationSupported && ssoEnabledTest != null && ssoEnabledTest.evaluate(existingConfigurations);
+ }
+
+ private boolean isKerberosRequiredForSsoIntegration() {
+ return ssoRequiresKerberos;
+ }
}
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceInfo.java b/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceInfo.java
index 938f73b..23923e5 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceInfo.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceInfo.java
@@ -41,6 +41,7 @@ import javax.xml.bind.annotation.XmlEnumValue;
import javax.xml.bind.annotation.XmlTransient;
import org.apache.ambari.server.api.services.AmbariMetaInfo;
+import org.apache.ambari.server.collections.PredicateUtils;
import org.apache.ambari.server.stack.StackDirectory;
import org.apache.ambari.server.stack.Validable;
import org.apache.ambari.server.state.stack.MetricDefinition;
@@ -152,6 +153,14 @@ public class ServiceInfo implements Validable {
private CredentialStoreInfo credentialStoreInfo;
/**
+ * The configuration that can be used to determine if Kerberos has been enabled for this service.
+ * <p>
+ * It is expected that this value is in the form of a valid JSON predicate ({@link PredicateUtils#fromJSON(String)}
+ */
+ @XmlElement(name = "kerberosEnabledTest")
+ private String kerberosEnabledTest = null;
+
+ /**
* Single Sign-on support information
*/
@XmlElements(@XmlElement(name = "sso"))
@@ -627,6 +636,27 @@ public class ServiceInfo implements Validable {
}
/**
+ * Gets the JSON predicate ({@link PredicateUtils#fromJSON(String)} that can be used to determine
+ * if Kerberos has been enabled for this service or not.
+ *
+ * @return a valid JSON predicate ({@link PredicateUtils#fromJSON(String)}
+ */
+ public String getKerberosEnabledTest() {
+ return kerberosEnabledTest;
+ }
+
+ /**
+ * Sets the JSON predicate ({@link PredicateUtils#fromJSON(String)} that can be used to determine
+ * if Kerberos has been enabled for this service or not.
+ *
+ * @param kerberosEnabledTest a valid JSON predicate ({@link PredicateUtils#fromJSON(String)}
+ */
+ public void setKerberosEnabledTest(String kerberosEnabledTest) {
+ this.kerberosEnabledTest = kerberosEnabledTest;
+ }
+
+
+ /**
* Gets the value for the SSO integration support
*
* @return the {@link SingleSignOnInfo}
@@ -680,6 +710,8 @@ public class ServiceInfo implements Validable {
sb.append(serviceType);
sb.append("\nversion:");
sb.append(version);
+ sb.append("\nKerberos enabled test:");
+ sb.append(kerberosEnabledTest);
sb.append("\ncomment:");
sb.append(comment);
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/state/ServiceInfoTest.java b/ambari-server/src/test/java/org/apache/ambari/server/state/ServiceInfoTest.java
index 2da5f96..5fc3426 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/state/ServiceInfoTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/state/ServiceInfoTest.java
@@ -790,6 +790,63 @@ public class ServiceInfoTest {
assertNull(singleSignOnInfo.getEnabledConfiguration());
}
+ /**
+ * Tests the presence and absence of the kerberosEnabledTest block.
+ */
+ @Test
+ public void testKerberosEnabledTest() throws Exception {
+ Map<String, ServiceInfo> serviceInfoMap;
+ ServiceInfo service;
+
+ String kerberosEnabledTest =
+ "{\n" +
+ " \"or\": [\n" +
+ " {\n" +
+ " \"equals\": [\n" +
+ " \"core-site/hadoop.security.authentication\",\n" +
+ " \"kerberos\"\n" +
+ " ]\n" +
+ " },\n" +
+ " {\n" +
+ " \"equals\": [\n" +
+ " \"hdfs-site/hadoop.security.authentication\",\n" +
+ " \"kerberos\"\n" +
+ " ]\n" +
+ " }\n" +
+ " ]\n" +
+ "}";
+
+ String serviceInfoXml = "<metainfo>\n" +
+ " <schemaVersion>2.0</schemaVersion>\n" +
+ " <services>\n" +
+ " <service>\n" +
+ " <name>HDFS</name>\n" +
+ " <kerberosEnabledTest>\n" +
+ kerberosEnabledTest +
+ " </kerberosEnabledTest>\n" +
+ " </service>\n" +
+ " </services>\n" +
+ "</metainfo>\n";
+ serviceInfoMap = getServiceInfo(serviceInfoXml);
+ service = serviceInfoMap.get("HDFS");
+ assertEquals(kerberosEnabledTest, service.getKerberosEnabledTest().trim());
+
+ /*
+ * <kerberosEnabledTest> is missing
+ */
+ serviceInfoXml = "<metainfo>\n" +
+ " <schemaVersion>2.0</schemaVersion>\n" +
+ " <services>\n" +
+ " <service>\n" +
+ " <name>HDFS</name>\n" +
+ " </service>\n" +
+ " </services>\n" +
+ "</metainfo>\n";
+ serviceInfoMap = getServiceInfo(serviceInfoXml);
+ service = serviceInfoMap.get("HDFS");
+ assertNull(service.getKerberosEnabledTest());
+ }
+
private static Map<String, ServiceInfo> getServiceInfo(String xml) throws JAXBException {
InputStream configStream = new ByteArrayInputStream(xml.getBytes());
JAXBContext jaxbContext = JAXBContext.newInstance(ServiceMetainfoXml.class);
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/state/ServiceTest.java b/ambari-server/src/test/java/org/apache/ambari/server/state/ServiceTest.java
index 5665179..3d4fbbf 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/state/ServiceTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/state/ServiceTest.java
@@ -22,6 +22,7 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import java.sql.SQLException;
+import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
@@ -291,6 +292,61 @@ public class ServiceTest {
Assert.assertEquals(MaintenanceState.ON, entity.getServiceDesiredStateEntity().getMaintenanceState());
}
+ /**
+ * Tests the kerberosEnabledTest value set in the HDFS metainfo file (stacks/HDP/0.1/services/HDFS/metainfo.xml):
+ * <pre>
+ * {
+ * "or": [
+ * {
+ * "equals": [
+ * "core-site/hadoop.security.authentication",
+ * "kerberos"
+ * ]
+ * },
+ * {
+ * "equals": [
+ * "hdfs-site/hadoop.security.authentication",
+ * "kerberos"
+ * ]
+ * }
+ * ]
+ * }
+ * </pre>
+ */
+ @Test
+ public void testServiceKerberosEnabledTest() throws Exception {
+ String serviceName = "HDFS";
+ Service s = serviceFactory.createNew(cluster, serviceName, repositoryVersion);
+ cluster.addService(s);
+
+ Service service = cluster.getService(serviceName);
+ Assert.assertNotNull(service);
+
+
+ Map<String, Map<String, String>> map = new HashMap<>();
+
+ Assert.assertFalse(service.isKerberosEnabled(null));
+
+ Assert.assertFalse(service.isKerberosEnabled(map));
+
+ map.put("core-site", Collections.singletonMap("hadoop.security.authentication", "none"));
+ map.put("hdfs-site", Collections.singletonMap("hadoop.security.authentication", "none"));
+ Assert.assertFalse(service.isKerberosEnabled(map));
+
+ map.put("core-site", Collections.singletonMap("hadoop.security.authentication", "kerberos"));
+ map.put("hdfs-site", Collections.singletonMap("hadoop.security.authentication", "none"));
+ Assert.assertTrue(service.isKerberosEnabled(map));
+
+ map.put("core-site", Collections.singletonMap("hadoop.security.authentication", "none"));
+ map.put("hdfs-site", Collections.singletonMap("hadoop.security.authentication", "kerberos"));
+ Assert.assertTrue(service.isKerberosEnabled(map));
+
+ map.put("core-site", Collections.singletonMap("hadoop.security.authentication", "kerberos"));
+ map.put("hdfs-site", Collections.singletonMap("hadoop.security.authentication", "kerberos"));
+ Assert.assertTrue(service.isKerberosEnabled(map));
+
+ }
+
private void addHostToCluster(String hostname,
String clusterName) throws AmbariException {
clusters.addHost(hostname);
diff --git a/ambari-server/src/test/resources/stacks/HDP/0.1/services/HDFS/metainfo.xml b/ambari-server/src/test/resources/stacks/HDP/0.1/services/HDFS/metainfo.xml
index 7629552..338b0f6 100644
--- a/ambari-server/src/test/resources/stacks/HDP/0.1/services/HDFS/metainfo.xml
+++ b/ambari-server/src/test/resources/stacks/HDP/0.1/services/HDFS/metainfo.xml
@@ -151,6 +151,25 @@
<config-type>hadoop-policy</config-type>
<config-type>hdfs-log4j</config-type>
</configuration-dependencies>
+
+ <kerberosEnabledTest>
+ {
+ "or": [
+ {
+ "equals": [
+ "core-site/hadoop.security.authentication",
+ "kerberos"
+ ]
+ },
+ {
+ "equals": [
+ "hdfs-site/hadoop.security.authentication",
+ "kerberos"
+ ]
+ }
+ ]
+ }
+ </kerberosEnabledTest>
</service>
</services>
</metainfo>