This is an automated email from the ASF dual-hosted git repository. smolnar pushed a commit to branch trunk in repository https://gitbox.apache.org/repos/asf/ambari.git
The following commit(s) were added to refs/heads/trunk by this push: new 9419944 AMBARI-24907. Updated service metainfo to declare LDAP integration support (#2621) 9419944 is described below commit 9419944925f3b210ce429ba147e1462478259261 Author: Sandor Molnar <smol...@apache.org> AuthorDate: Fri Nov 16 09:55:36 2018 +0100 AMBARI-24907. Updated service metainfo to declare LDAP integration support (#2621) --- .../server/controller/AddServiceRequest.java | 1 - .../ambari/server/controller/ServiceResponse.java | 24 +++- .../internal/ServiceResourceProvider.java | 14 ++ .../apache/ambari/server/state/ServiceImpl.java | 14 +- .../apache/ambari/server/state/ServiceInfo.java | 43 ++++++ .../ambari/server/state/ServiceLdapInfo.java | 159 +++++++++++++++++++++ .../ambari/server/state/ServiceInfoTest.java | 83 +++++++++++ 7 files changed, 335 insertions(+), 3 deletions(-) diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/AddServiceRequest.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/AddServiceRequest.java index ccf2ecf..61edde3 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/controller/AddServiceRequest.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/AddServiceRequest.java @@ -36,7 +36,6 @@ import java.util.Set; import org.apache.ambari.annotations.ApiIgnore; import org.apache.ambari.server.controller.internal.ProvisionAction; import org.apache.ambari.server.topology.ConfigRecommendationStrategy; -import org.apache.ambari.server.topology.Configurable; import org.apache.ambari.server.topology.ConfigurableHelper; import org.apache.ambari.server.topology.Configuration; 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 a0f8a56..afbf51f 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 @@ -41,13 +41,15 @@ public class ServiceResponse { private final boolean ssoIntegrationEnabled; private final boolean ssoIntegrationRequiresKerberos; private final boolean kerberosEnabled; + private final boolean ldapIntegrationSupported; + private final boolean ldapIntegrationEnabled; 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 kerberosEnabled) { + boolean kerberosEnabled, boolean ldapIntegrationSupported, boolean ldapIntegrationEnabled) { this.clusterId = clusterId; this.clusterName = clusterName; this.serviceName = serviceName; @@ -62,6 +64,8 @@ public class ServiceResponse { this.credentialStoreEnabled = credentialStoreEnabled; this.ssoIntegrationRequiresKerberos = ssoIntegrationRequiresKerberos; this.kerberosEnabled = kerberosEnabled; + this.ldapIntegrationSupported = ldapIntegrationSupported; + this.ldapIntegrationEnabled = ldapIntegrationEnabled; } /** @@ -277,6 +281,24 @@ public class ServiceResponse { public boolean isKerberosEnabled() { return kerberosEnabled; } + + /** + * Indicates if this service supports LDAP integration. + */ + @ApiModelProperty(name = "ldap_integration_supported") + public boolean isLdapIntegrationSupported() { + return ldapIntegrationSupported; + } + + /** + * Indicates whether the service is configured for LDAP integration or not + */ + @ApiModelProperty(name = "ldap_integration_enabled") + public boolean isLdapIntegrationEnabled() { + return ldapIntegrationEnabled; + } + + /** * Interface to help correct Swagger documentation generation 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 6b561e8..a4aaf0b 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 @@ -139,6 +139,12 @@ public class ServiceResourceProvider extends AbstractControllerResourceProvider private static final String KERBEROS_ENABLED_PROPERTY_ID = PropertyHelper.getPropertyId( "ServiceInfo", "kerberos_enabled"); + private static final String LDAP_INTEGRATION_SUPPORTED_PROPERTY_ID = PropertyHelper.getPropertyId( + "ServiceInfo", "ldap_integration_supported"); + + private static final String LDAP_INTEGRATION_ENABLED_PROPERTY_ID = PropertyHelper.getPropertyId( + "ServiceInfo", "ldap_integration_enabled"); + public static final String OPERATION_TYPE = "operation_type"; protected static final String SERVICE_REPOSITORY_STATE = "ServiceInfo/repository_state"; @@ -185,6 +191,10 @@ public class ServiceResourceProvider extends AbstractControllerResourceProvider PROPERTY_IDS.add(SSO_INTEGRATION_DESIRED_PROPERTY_ID); PROPERTY_IDS.add(SSO_INTEGRATION_REQUIRES_KERBEROS_PROPERTY_ID); PROPERTY_IDS.add(KERBEROS_ENABLED_PROPERTY_ID); + + PROPERTY_IDS.add(LDAP_INTEGRATION_SUPPORTED_PROPERTY_ID); + PROPERTY_IDS.add(LDAP_INTEGRATION_ENABLED_PROPERTY_ID); + PROPERTY_IDS.add(OPERATION_TYPE); // keys @@ -326,6 +336,10 @@ public class ServiceResourceProvider extends AbstractControllerResourceProvider setResourceProperty(resource, KERBEROS_ENABLED_PROPERTY_ID, response.isKerberosEnabled(), requestedIds); + setResourceProperty(resource, LDAP_INTEGRATION_SUPPORTED_PROPERTY_ID, response.isLdapIntegrationSupported(), requestedIds); + setResourceProperty(resource, LDAP_INTEGRATION_ENABLED_PROPERTY_ID, response.isLdapIntegrationEnabled(), requestedIds); + + Map<String, Object> serviceSpecificProperties = getServiceSpecificProperties( response.getClusterName(), response.getServiceName(), requestedIds); 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 23f3067..e19b43d 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 @@ -87,6 +87,8 @@ public class ServiceImpl implements Service { private boolean isCredentialStoreRequired; private final boolean ssoIntegrationSupported; private final Predicate ssoEnabledTest; + private final boolean ldapIntegrationSupported; + private final Predicate ldapEnabledTest; private final boolean ssoRequiresKerberos; private final Predicate kerberosEnabledTest; private AmbariMetaInfo ambariMetaInfo; @@ -169,6 +171,9 @@ public class ServiceImpl implements Service { serviceName); } + ldapIntegrationSupported = sInfo.isLdapSupported(); + ldapEnabledTest = StringUtils.isNotBlank(sInfo.getLdapEnabledTest()) ? PredicateUtils.fromJSON(sInfo.getLdapEnabledTest()) : null; + persist(serviceEntity); } @@ -226,6 +231,9 @@ public class ServiceImpl implements Service { "Automated SSO integration will not be allowed for this service.", serviceName); } + + ldapIntegrationSupported = sInfo.isLdapSupported(); + ldapEnabledTest = StringUtils.isNotBlank(sInfo.getLdapEnabledTest()) ? PredicateUtils.fromJSON(sInfo.getLdapEnabledTest()) : null; } @@ -414,7 +422,7 @@ public class ServiceImpl implements Service { getName(), desiredStackId, desiredRespositoryVersion.getVersion(), getRepositoryState(), getDesiredState().toString(), isCredentialStoreSupported(), isCredentialStoreEnabled(), ssoIntegrationSupported, isSsoIntegrationDesired(), isSsoIntegrationEnabled(existingConfigurations), - isKerberosRequiredForSsoIntegration(), isKerberosEnabled(existingConfigurations)); + isKerberosRequiredForSsoIntegration(), isKerberosEnabled(existingConfigurations), ldapIntegrationSupported,isLdapIntegrationEnabeled(existingConfigurations)); r.setDesiredRepositoryVersionId(desiredRespositoryVersion.getId()); @@ -797,4 +805,8 @@ public class ServiceImpl implements Service { private boolean isKerberosRequiredForSsoIntegration() { return ssoRequiresKerberos; } + + private boolean isLdapIntegrationEnabeled(Map<String, Map<String, String>> existingConfigurations) { + return ldapIntegrationSupported && ldapEnabledTest != null && ldapEnabledTest.evaluate(existingConfigurations); + } } 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 a4ce569..fa17dea 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 @@ -167,6 +167,12 @@ public class ServiceInfo implements Validable { @XmlElements(@XmlElement(name = "sso")) private SingleSignOnInfo singleSignOnInfo; + /** + * LDAP support information + */ + @XmlElements(@XmlElement(name = "ldap")) + private ServiceLdapInfo ldapInfo; + public Boolean isRestartRequiredAfterChange() { return restartRequiredAfterChange; } @@ -719,6 +725,38 @@ public class ServiceInfo implements Validable { public boolean isKerberosRequiredForSingleSignOnIntegration() { return singleSignOnInfo != null && singleSignOnInfo.isKerberosRequired(); } + + /** + * Gets a new value for LDAP integration support + */ + public ServiceLdapInfo getLdapInfo() { + return ldapInfo; + } + + /** + * Sets a new value for LDAP integration support + * + * @param ldapInfo + * a {@link ServiceLdapInfo} + */ + public void setLdapInfo(ServiceLdapInfo ldapInfo) { + this.ldapInfo = ldapInfo; + } + + /** + * @return whether this service supports single sign-on integration + */ + public boolean isLdapSupported() { + return (ldapInfo != null) && ldapInfo.isSupported(); + } + + /** + * @return the configuration specification that can be used to determine if LDAP + * has been enabled or not. + */ + public String getLdapEnabledTest() { + return ldapInfo != null ? ldapInfo.getLdapEnabledTest() : null; + } @Override public String toString() { @@ -1332,6 +1370,11 @@ public class ServiceInfo implements Validable { } } } + + if (ldapInfo != null && ldapInfo.isSupported() && StringUtils.isBlank(ldapInfo.getLdapEnabledTest())) { + setValid(false); + addError("LDAP support is indicated for service " + getName() + " but no test configuration has been set by ldapEnabledTest."); + } } public enum Selection { diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceLdapInfo.java b/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceLdapInfo.java new file mode 100644 index 0000000..709b607 --- /dev/null +++ b/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceLdapInfo.java @@ -0,0 +1,159 @@ +/* + * 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.state; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; + +import org.apache.ambari.server.collections.PredicateUtils; +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; +import org.apache.commons.lang.builder.ToStringBuilder; + +/** + * {@link ServiceLdapInfo} encapsulates meta information about a service's + * support LDAP integration + * <p> + * The data is expected to be like + * + * <pre> + * <ldap> + * <supported>true</supported> + * <ldapEnabledTest> + * { + * "equals": [ + * "service-site/ranger.authentication.method", + * "LDAP" + * ] + * } + * </ldapEnabledTest> + * </ldap> + * </pre> + */ +@XmlAccessorType(XmlAccessType.FIELD) +public class ServiceLdapInfo { + + /** + * Indicates whether the relevant service supports LDAP integration + * (<code>true</code>) or not (<code>false</code>). + */ + @XmlElement(name = "supported") + private Boolean supported = Boolean.FALSE; + + /** + * The configuration that can be used to determine if LDAP integration has been + * enabled. + * <p> + * It is expected that this value is in the form of a valid JSON predicate + * ({@link PredicateUtils#fromJSON(String)} + */ + @XmlElement(name = "ldapEnabledTest") + private String ldapEnabledTest = null; + + /** + * Default constructor + */ + public ServiceLdapInfo() { + this(Boolean.FALSE, null); + } + + /** + * Constructor taking in values for supported and the configuration that can be + * used to determine if it is enabled for not. + * + * @param supported + * true if LDAP integration is supported; false otherwise + * @param ldapEnabledTest + * the configuration that can be used to determine if LDAP integration + * has been enabled + */ + public ServiceLdapInfo(Boolean supported, String ldapEnabledTest) { + this.supported = supported; + this.ldapEnabledTest = ldapEnabledTest; + } + + /** + * Gets the value whether if the service supports LDAP integration. + * <p> + * <code>null</code> indicates the value was not set + * + * @return true if LDAP integration is supported; false if LDAP integration is + * not supported; null if not specified + */ + public Boolean getSupported() { + return supported; + } + + /** + * Tests whether the service supports LDAP integration. + * + * @return true if LDAP integration is supported; false otherwise + */ + public boolean isSupported() { + return Boolean.TRUE.equals(supported); + } + + /** + * Sets the value indicating whether the service supports LDAP integration. + * + * @param supported + * true if LDAP integration is supported; false if LDAP integration is + * not supported; null if not specified + */ + public void setSupported(Boolean supported) { + this.supported = supported; + } + + /** + * Gets the configuration specification that can be used to determine if LDAP + * has been enabled or not. + * + * @return a configuration specification (a valid JSON predicate) + */ + public String getLdapEnabledTest() { + return ldapEnabledTest; + } + + /** + * Sets the configuration specification that can be used to determine if LDAP + * has been enabled or not. + * + * @param ldapEnabledTest + * a configuration specification (a valid JSON predicate) + */ + public void setLdapEnabledTest(String ldapEnabledTest) { + this.ldapEnabledTest = ldapEnabledTest; + } + + @Override + public int hashCode() { + return HashCodeBuilder.reflectionHashCode(this); + } + + @Override + public boolean equals(Object obj) { + return EqualsBuilder.reflectionEquals(this, obj); + } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this); + } +} 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 00223c4..df7bc6f 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 @@ -847,6 +847,89 @@ public class ServiceInfoTest { service = serviceInfoMap.get("HDFS"); assertNull(service.getKerberosEnabledTest()); } + + @Test + public void testLdapIntegrationSupport() throws Exception { + // Implicit SSO setting + String serviceInfoXml = + "<metainfo>" + + " <schemaVersion>2.0</schemaVersion>" + + " <services>" + + " <service>" + + " <name>SERVICE</name>" + + " </service>" + + " </services>" + + "</metainfo>"; + Map<String, ServiceInfo> serviceInfoMap = getServiceInfo(serviceInfoXml); + assertFalse(serviceInfoMap.get("SERVICE").isLdapSupported()); + assertTrue(serviceInfoMap.get("SERVICE").isValid()); + + ServiceLdapInfo ldapInfo = serviceInfoMap.get("SERVICE").getLdapInfo(); + assertNull(ldapInfo); + + // Explicit LDAP setting (true) + serviceInfoXml = + "<metainfo>" + + " <schemaVersion>2.0</schemaVersion>" + + " <services>" + + " <service>" + + " <name>SERVICE</name>" + + " <ldap>" + + " <supported>true</supported>" + + " <ldapEnabledTest>{\"equals\": [\"config-type/property_name\", \"true\"]}</ldapEnabledTest>" + + " </ldap>" + + " </service>" + + " </services>" + + "</metainfo>"; + serviceInfoMap = getServiceInfo(serviceInfoXml); + assertTrue(serviceInfoMap.get("SERVICE").isLdapSupported()); + assertTrue(serviceInfoMap.get("SERVICE").isValid()); + + ldapInfo = serviceInfoMap.get("SERVICE").getLdapInfo(); + assertNotNull(ldapInfo); + assertTrue(ldapInfo.isSupported()); + assertEquals("{\"equals\": [\"config-type/property_name\", \"true\"]}", ldapInfo.getLdapEnabledTest()); + + // Explicit LDAP setting (false) + serviceInfoXml = + "<metainfo>" + + " <schemaVersion>2.0</schemaVersion>" + + " <services>" + + " <service>" + + " <name>SERVICE</name>" + + " <ldap>" + + " <supported>false</supported>" + + " </ldap>" + + " </service>" + + " </services>" + + "</metainfo>"; + serviceInfoMap = getServiceInfo(serviceInfoXml); + assertFalse(serviceInfoMap.get("SERVICE").isLdapSupported()); + assertTrue(serviceInfoMap.get("SERVICE").isValid()); + + ldapInfo = serviceInfoMap.get("SERVICE").getLdapInfo(); + assertNotNull(ldapInfo); + assertFalse(ldapInfo.isSupported()); + assertNull(ldapInfo.getLdapEnabledTest()); + + // Explicit SSO setting (invalid) + serviceInfoXml = + "<metainfo>" + + " <schemaVersion>2.0</schemaVersion>" + + " <services>" + + " <service>" + + " <name>SERVICE</name>" + + " <ldap>" + + " <supported>true</supported>" + + " </ldap>" + + " </service>" + + " </services>" + + "</metainfo>"; + serviceInfoMap = getServiceInfo(serviceInfoXml); + assertTrue(serviceInfoMap.get("SERVICE").isLdapSupported()); + assertFalse(serviceInfoMap.get("SERVICE").isValid()); + assertEquals(1, serviceInfoMap.get("SERVICE").getErrors().size()); + } @Test public void testIsRollingRestartSupported() throws JAXBException {