You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by sw...@apache.org on 2014/07/31 01:46:25 UTC
git commit: Views : Admin - LDAP Support.
Repository: ambari
Updated Branches:
refs/heads/trunk ce4020028 -> 15b54439a
Views : Admin - LDAP Support.
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/15b54439
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/15b54439
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/15b54439
Branch: refs/heads/trunk
Commit: 15b54439af4b95386fe678b97a1d88a062dc9309
Parents: ce40200
Author: Siddharth Wagle <sw...@hortonworks.com>
Authored: Wed Jul 30 16:40:48 2014 -0700
Committer: Siddharth Wagle <sw...@hortonworks.com>
Committed: Wed Jul 30 16:40:48 2014 -0700
----------------------------------------------------------------------
.../resources/ControllerResourceDefinition.java | 60 +++
.../resources/ResourceInstanceFactoryImpl.java | 8 +-
.../server/api/services/ControllerService.java | 98 +++++
.../server/configuration/Configuration.java | 52 ++-
.../controller/AmbariManagementController.java | 36 +-
.../AmbariManagementControllerImpl.java | 70 +++-
.../ambari/server/controller/AmbariServer.java | 3 +
.../server/controller/ControllerRequest.java | 41 ++
.../server/controller/ControllerResponse.java | 33 ++
.../AbstractControllerResourceProvider.java | 2 +
.../internal/ControllerResourceProvider.java | 243 +++++++++++
.../controller/internal/ControllerType.java | 65 +++
.../ambari/server/controller/spi/Resource.java | 4 +-
.../apache/ambari/server/orm/dao/GroupDAO.java | 1 -
.../AmbariLdapAuthenticationProvider.java | 2 +-
.../authorization/AmbariLdapDataPopulator.java | 419 +++++++++++++++++++
.../authorization/LdapServerProperties.java | 38 +-
.../server/security/authorization/Member.java | 53 ---
.../server/security/authorization/User.java | 15 +-
.../server/security/authorization/Users.java | 32 ++
.../src/main/resources/key_properties.json | 3 +
.../src/main/resources/properties.json | 9 +
22 files changed, 1170 insertions(+), 117 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/15b54439/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ControllerResourceDefinition.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ControllerResourceDefinition.java b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ControllerResourceDefinition.java
new file mode 100644
index 0000000..55e6502
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ControllerResourceDefinition.java
@@ -0,0 +1,60 @@
+/**
+ * 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.api.resources;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.ambari.server.controller.internal.ControllerType;
+import org.apache.ambari.server.controller.spi.Resource;
+
+/**
+ * Controller Resource Definition
+ */
+public class ControllerResourceDefinition extends BaseResourceDefinition {
+
+ private final ControllerType type;
+
+ public ControllerResourceDefinition(ControllerType type) {
+ super(Resource.Type.Controller);
+ this.type = type;
+ }
+
+ @Override
+ public String getPluralName() {
+ return "controllers";
+ }
+
+ @Override
+ public String getSingularName() {
+ return "controller";
+ }
+
+ @Override
+ public Set<SubResourceDefinition> getSubResourceDefinitions() {
+ final Set<SubResourceDefinition> subResourceDefinitions = new HashSet<SubResourceDefinition>();
+ if (type != null) {
+ switch (type) {
+ case LDAP:
+ break;
+ }
+ }
+ return subResourceDefinitions;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/15b54439/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ResourceInstanceFactoryImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ResourceInstanceFactoryImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ResourceInstanceFactoryImpl.java
index 3d198d6..bc2e634 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ResourceInstanceFactoryImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ResourceInstanceFactoryImpl.java
@@ -24,6 +24,7 @@ import java.util.Map;
import java.util.Set;
import org.apache.ambari.server.api.query.QueryImpl;
+import org.apache.ambari.server.controller.internal.ControllerType;
import org.apache.ambari.server.controller.spi.Resource;
import org.apache.ambari.server.controller.utilities.ClusterControllerHelper;
import org.apache.ambari.server.view.ViewRegistry;
@@ -241,7 +242,7 @@ public class ResourceInstanceFactoryImpl implements ResourceInstanceFactory {
case Permission:
resourceDefinition = new PermissionResourceDefinition();
break;
-
+
case AlertDefinition:
resourceDefinition = new AlertDefResourceDefinition();
break;
@@ -262,6 +263,11 @@ public class ResourceInstanceFactoryImpl implements ResourceInstanceFactory {
resourceDefinition = new ViewPermissionResourceDefinition();
break;
+ case Controller:
+ resourceDefinition = new ControllerResourceDefinition(
+ ControllerType.getByName(mapIds.get(Resource.Type.Controller)));
+ break;
+
default:
throw new IllegalArgumentException("Unsupported resource type: " + type);
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/15b54439/ambari-server/src/main/java/org/apache/ambari/server/api/services/ControllerService.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/ControllerService.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/ControllerService.java
new file mode 100644
index 0000000..6d20a93
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/ControllerService.java
@@ -0,0 +1,98 @@
+/**
+ * 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.api.services;
+
+import java.util.Collections;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+
+import org.apache.ambari.server.api.resources.ResourceInstance;
+import org.apache.ambari.server.controller.spi.Resource;
+
+/**
+ * Service responsible for controllers.
+ */
+@Path("/controllers/")
+public class ControllerService extends BaseService {
+ /**
+ * Handles: GET /controllers
+ * Get all controllers.
+ *
+ * @param headers http headers
+ * @param ui uri info
+ * @return controller collection resource representation
+ */
+ @GET
+ @Produces("text/plain")
+ public Response getControllers(@Context HttpHeaders headers, @Context UriInfo ui) {
+ return handleRequest(headers, null, ui, Request.Type.GET, createControllerResource(null));
+ }
+
+ /**
+ * Handles: GET /controllers/{controllerName}
+ * Get single controller.
+ *
+ * @param headers http headers
+ * @param ui uri info
+ * @return controller resource representation
+ */
+ @GET
+ @Path("{controllerName}")
+ @Produces("text/plain")
+ public Response getController(@Context HttpHeaders headers, @Context UriInfo ui,
+ @PathParam("controllerName") String controllerName) {
+ return handleRequest(headers, null, ui, Request.Type.GET, createControllerResource(controllerName));
+ }
+
+ /**
+ * Handles: PUT /controllers/{controllerName}
+ * Update data of a single controller.
+ *
+ * @param headers http headers
+ * @param ui uri info
+ * @return controller resource representation
+ */
+ @PUT
+ @Path("{controllerName}")
+ @Produces("text/plain")
+ public Response updateController(String body, @Context HttpHeaders headers, @Context UriInfo ui,
+ @PathParam("controllerName") String controllerName) {
+ return handleRequest(headers, body, ui, Request.Type.PUT, createControllerResource(controllerName));
+ }
+
+ /**
+ * Create a controller resource instance.
+ *
+ * @param controllerName controller name
+ *
+ * @return a cluster resource instance
+ */
+ ResourceInstance createControllerResource(String controllerName) {
+ return createResource(Resource.Type.Controller,
+ Collections.singletonMap(Resource.Type.Controller, controllerName));
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/15b54439/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java b/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java
index 68df120..65cf668 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/configuration/Configuration.java
@@ -132,6 +132,10 @@ public class Configuration {
"authentication.ldap.managerPassword";
public static final String LDAP_USERNAME_ATTRIBUTE_KEY =
"authentication.ldap.usernameAttribute";
+ public static final String LDAP_USER_BASE_KEY =
+ "authentication.ldap.userBase";
+ public static final String LDAP_USER_OBJECT_CLASS_KEY =
+ "authentication.ldap.userObjectClass";
public static final String LDAP_GROUP_BASE_KEY =
"authorization.ldap.groupBase";
public static final String LDAP_GROUP_OBJECT_CLASS_KEY =
@@ -268,6 +272,9 @@ public class Configuration {
private static final String LDAP_PRIMARY_URL_DEFAULT = "localhost:33389";
private static final String LDAP_BASE_DN_DEFAULT = "dc=ambari,dc=apache,dc=org";
private static final String LDAP_USERNAME_ATTRIBUTE_DEFAULT = "uid";
+ private static final String LDAP_USER_BASE_DEFAULT =
+ "ou=people,dc=ambari,dc=apache,dc=org";
+ private static final String LDAP_USER_OBJECT_CLASS_DEFAULT = "person";
private static final String LDAP_GROUP_BASE_DEFAULT =
"ou=groups,dc=ambari,dc=apache,dc=org";
private static final String LDAP_GROUP_OBJECT_CLASS_DEFAULT = "group";
@@ -280,23 +287,23 @@ public class Configuration {
private static final String SERVER_PERSISTENCE_TYPE_DEFAULT = "local";
private static final String SERVER_CONNECTION_MAX_IDLE_TIME =
"server.connection.max.idle.millis";
-
+
private static final String UBUNTU_OS = "debian12";
-
+
/**
* Default for repo validation suffixes.
*/
private static final String REPO_SUFFIX_DEFAULT = "/repodata/repomd.xml";
private static final String REPO_SUFFIX_UBUNTU = "/dists/%s/Release.gpg,/dists/%s/Release";
-
+
private static final String PARALLEL_STAGE_EXECUTION_DEFAULT = "true";
-
+
private static final String CLIENT_THREADPOOL_SIZE_KEY = "client.threadpool.size.max";
private static final int CLIENT_THREADPOOL_SIZE_DEFAULT = 25;
private static final String AGENT_THREADPOOL_SIZE_KEY = "agent.threadpool.size.max";
private static final int AGENT_THREADPOOL_SIZE_DEFAULT = 25;
-
-
+
+
private static final Logger LOG = LoggerFactory.getLogger(
Configuration.class);
private Properties properties;
@@ -776,6 +783,9 @@ public class Configuration {
ldapServerProperties.setUsernameAttribute(properties.
getProperty(LDAP_USERNAME_ATTRIBUTE_KEY, LDAP_USERNAME_ATTRIBUTE_DEFAULT));
+ ldapServerProperties.setUserBase(properties.getProperty(LDAP_USER_BASE_KEY, LDAP_USER_BASE_DEFAULT));
+ ldapServerProperties.setUserObjectClass(properties.getProperty(LDAP_USER_OBJECT_CLASS_KEY, LDAP_USER_OBJECT_CLASS_DEFAULT));
+
ldapServerProperties.setGroupBase(properties.
getProperty(LDAP_GROUP_BASE_KEY, LDAP_GROUP_BASE_DEFAULT));
ldapServerProperties.setGroupObjectClass(properties.
@@ -832,11 +842,11 @@ public class Configuration {
public String getServerDBName() {
return properties.getProperty(SERVER_DB_NAME_KEY, SERVER_DB_NAME_DEFAULT);
}
-
+
public String getMySQLJarName() {
return properties.getProperty(MYSQL_JAR_NAME_KEY, MYSQL_JAR_NAME_DEFAULT);
}
-
+
public JPATableGenerationStrategy getJPATableGenerationStrategy() {
return JPATableGenerationStrategy.fromString(System.getProperty(SERVER_JDBC_GENERATE_TABLES_KEY));
}
@@ -881,9 +891,9 @@ public class Configuration {
if (null != customDbProperties) {
return customDbProperties;
}
-
+
customDbProperties = new HashMap<String, String>();
-
+
for (Entry<Object, Object> entry : properties.entrySet()) {
String key = entry.getKey().toString();
String val = entry.getValue().toString();
@@ -891,15 +901,15 @@ public class Configuration {
customDbProperties.put(key.substring(SERVER_JDBC_PROPERTIES_PREFIX.length()), val);
}
}
-
+
return customDbProperties;
}
public Map<String, String> getAmbariProperties() {
-
+
Properties properties = readConfigFile();
Map<String, String> ambariPropertiesMap = new HashMap<String, String>();
-
+
for(String key : properties.stringPropertyNames()) {
ambariPropertiesMap.put(key, properties.getProperty(key));
}
@@ -921,7 +931,7 @@ public class Configuration {
}
/**
- * @return whether staleConfig's flag is cached.
+ * @return whether staleConfig's flag is cached.
*/
public boolean isStaleConfigCacheEnabled() {
String stringValue =
@@ -929,21 +939,21 @@ public class Configuration {
SERVER_STALE_CONFIG_CACHE_ENABLED_DEFAULT);
return "true".equalsIgnoreCase(stringValue);
}
-
+
/**
* @return a string array of suffixes used to validate repo URLs.
*/
public String[] getRepoValidationSuffixes(String osFamily) {
String repoSuffixes;
-
+
if(osFamily.equals(UBUNTU_OS)) {
- repoSuffixes = properties.getProperty(REPO_SUFFIX_KEY_UBUNTU,
+ repoSuffixes = properties.getProperty(REPO_SUFFIX_KEY_UBUNTU,
REPO_SUFFIX_UBUNTU);
} else {
- repoSuffixes = properties.getProperty(REPO_SUFFIX_KEY_DEFAULT,
+ repoSuffixes = properties.getProperty(REPO_SUFFIX_KEY_DEFAULT,
REPO_SUFFIX_DEFAULT);
}
-
+
return repoSuffixes.split(",");
}
@@ -1014,12 +1024,12 @@ public class Configuration {
return Integer.parseInt(properties.getProperty(
CLIENT_THREADPOOL_SIZE_KEY, String.valueOf(CLIENT_THREADPOOL_SIZE_DEFAULT)));
}
-
+
/**
* @return max thread pool size for agents, default 25
*/
public int getAgentThreadPoolSize() {
return Integer.parseInt(properties.getProperty(
AGENT_THREADPOOL_SIZE_KEY, String.valueOf(AGENT_THREADPOOL_SIZE_DEFAULT)));
- }
+ }
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/15b54439/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementController.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementController.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementController.java
index ab03b30..4c41d90 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementController.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementController.java
@@ -36,7 +36,6 @@ import org.apache.ambari.server.state.ServiceFactory;
import org.apache.ambari.server.state.State;
import org.apache.ambari.server.state.configgroup.ConfigGroupFactory;
import org.apache.ambari.server.state.scheduler.RequestExecutionFactory;
-
import java.util.Collection;
import java.util.List;
import java.util.Map;
@@ -666,8 +665,43 @@ public interface AmbariManagementController {
throws AmbariException;
/**
+<<<<<<< HEAD
* Get Role Command Order
*/
public RoleCommandOrder getRoleCommandOrder(Cluster cluster);
+
+ /**
+=======
+>>>>>>> a96596eb4c0e9551156585a67181b64df75e335a
+ * Performs a test if LDAP server is reachable.
+ *
+ * @return true if connection to LDAP was established
+ */
+ public boolean checkLdapConfigured();
+
+ /**
+ * Retrieves users from external LDAP.
+ *
+ * @return key-value pairs UserName-Synced
+ * @throws AmbariException if LDAP is configured incorrectly
+ */
+ public Map<String, Boolean> getLdapUsersSyncInfo() throws AmbariException;
+
+ /**
+ * Retrieves groups from external LDAP.
+ *
+ * @return key-value pairs GroupName-Synced
+ * @throws AmbariException if LDAP is configured incorrectly
+ */
+ public Map<String, Boolean> getLdapGroupsSyncInfo() throws AmbariException;
+
+ /**
+ * Synchronizes local users and groups with given data.
+ *
+ * @param users users to be synchronized
+ * @param groups groups to be synchronized
+ * @throws AmbariException if synchronization data was invalid
+ */
+ public void synchronizeLdapUsersAndGroups(Set<String> users, Set<String> groups) throws AmbariException;
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/15b54439/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java
index ef031e6..7f53ded 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java
@@ -18,6 +18,29 @@
package org.apache.ambari.server.controller;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.AMBARI_DB_RCA_DRIVER;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.AMBARI_DB_RCA_PASSWORD;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.AMBARI_DB_RCA_URL;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.AMBARI_DB_RCA_USERNAME;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.COMMAND_TIMEOUT;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.DB_DRIVER_FILENAME;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.DB_NAME;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.HOOKS_FOLDER;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.JAVA_HOME;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.JCE_NAME;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.JDK_LOCATION;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.JDK_NAME;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.MYSQL_JDBC_URL;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.ORACLE_JDBC_URL;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.PACKAGE_LIST;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.REPO_INFO;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.SCRIPT;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.SCRIPT_TYPE;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.SERVICE_PACKAGE_FOLDER;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.SERVICE_REPO_INFO;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.STACK_NAME;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.STACK_VERSION;
+
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.gson.Gson;
@@ -55,29 +78,6 @@ import org.apache.ambari.server.actionmanager.Stage;
import org.apache.ambari.server.actionmanager.StageFactory;
import org.apache.ambari.server.agent.ExecutionCommand;
-import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.AMBARI_DB_RCA_DRIVER;
-import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.AMBARI_DB_RCA_PASSWORD;
-import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.AMBARI_DB_RCA_URL;
-import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.AMBARI_DB_RCA_USERNAME;
-import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.COMMAND_TIMEOUT;
-import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.DB_DRIVER_FILENAME;
-import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.DB_NAME;
-import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.HOOKS_FOLDER;
-import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.JAVA_HOME;
-import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.JCE_NAME;
-import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.JDK_LOCATION;
-import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.JDK_NAME;
-import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.MYSQL_JDBC_URL;
-import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.ORACLE_JDBC_URL;
-import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.PACKAGE_LIST;
-import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.REPO_INFO;
-import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.SCRIPT;
-import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.SCRIPT_TYPE;
-import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.SERVICE_PACKAGE_FOLDER;
-import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.SERVICE_REPO_INFO;
-import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.STACK_NAME;
-import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.STACK_VERSION;
-
import org.apache.ambari.server.api.services.AmbariMetaInfo;
import org.apache.ambari.server.configuration.Configuration;
import org.apache.ambari.server.controller.internal.RequestOperationLevel;
@@ -88,6 +88,7 @@ import org.apache.ambari.server.customactions.ActionDefinition;
import org.apache.ambari.server.metadata.ActionMetadata;
import org.apache.ambari.server.metadata.RoleCommandOrder;
import org.apache.ambari.server.scheduler.ExecutionScheduleManager;
+import org.apache.ambari.server.security.authorization.AmbariLdapDataPopulator;
import org.apache.ambari.server.security.authorization.AuthorizationHelper;
import org.apache.ambari.server.security.authorization.Group;
import org.apache.ambari.server.security.authorization.User;
@@ -189,6 +190,8 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
private RequestExecutionFactory requestExecutionFactory;
@Inject
private ExecutionScheduleManager executionScheduleManager;
+ @Inject
+ private AmbariLdapDataPopulator ldapDataPopulator;
private MaintenanceStateHelper maintenanceStateHelper;
@@ -3482,4 +3485,25 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
return rcaParameters;
}
+ @Override
+ public boolean checkLdapConfigured() {
+ return ldapDataPopulator.isLdapEnabled();
+ }
+
+ @Override
+ public Map<String, Boolean> getLdapUsersSyncInfo() throws AmbariException {
+ return ldapDataPopulator.getLdapUsersSyncInfo();
+ }
+
+ @Override
+ public Map<String, Boolean> getLdapGroupsSyncInfo() throws AmbariException {
+ return ldapDataPopulator.getLdapGroupsSyncInfo();
+ }
+
+ @Override
+ public synchronized void synchronizeLdapUsersAndGroups(Set<String> users,
+ Set<String> groups) throws AmbariException {
+ ldapDataPopulator.synchronizeLdapUsersAndGroups(users, groups);
+ }
+
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/15b54439/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
index eb34a77..77d2a77 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
@@ -78,6 +78,7 @@ import org.apache.ambari.server.scheduler.ExecutionScheduleManager;
import org.apache.ambari.server.security.CertificateManager;
import org.apache.ambari.server.security.SecurityFilter;
import org.apache.ambari.server.security.authorization.AmbariLdapAuthenticationProvider;
+import org.apache.ambari.server.security.authorization.AmbariLdapDataPopulator;
import org.apache.ambari.server.security.authorization.AmbariLocalUserDetailsService;
import org.apache.ambari.server.security.authorization.Users;
import org.apache.ambari.server.security.authorization.internal.AmbariInternalAuthenticationProvider;
@@ -181,6 +182,8 @@ public class AmbariServer {
injector.getInstance(AmbariLocalUserDetailsService.class));
factory.registerSingleton("ambariLdapAuthenticationProvider",
injector.getInstance(AmbariLdapAuthenticationProvider.class));
+ factory.registerSingleton("ambariLdapDataPopulator",
+ injector.getInstance(AmbariLdapDataPopulator.class));
factory.registerSingleton("internalTokenAuthenticationFilter",
injector.getInstance(InternalTokenAuthenticationFilter.class));
factory.registerSingleton("ambariInternalAuthenticationProvider",
http://git-wip-us.apache.org/repos/asf/ambari/blob/15b54439/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerRequest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerRequest.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerRequest.java
new file mode 100644
index 0000000..49121d3
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerRequest.java
@@ -0,0 +1,41 @@
+/**
+ * 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.controller;
+
+import java.util.Map;
+
+/**
+ * Represents a controller maintenance request.
+ */
+public class ControllerRequest {
+ private final String name;
+ private final Map<String, Object> propertyMap;
+
+ public ControllerRequest(String name, Map<String, Object> propertyMap) {
+ this.name = name;
+ this.propertyMap = propertyMap;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public Map<String, Object> getPropertyMap() {
+ return propertyMap;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/15b54439/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerResponse.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerResponse.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerResponse.java
new file mode 100644
index 0000000..c75e153
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerResponse.java
@@ -0,0 +1,33 @@
+/**
+ * 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.controller;
+
+/**
+ * Represents a controller maintenance response.
+ */
+public class ControllerResponse {
+ private final String name;
+
+ public ControllerResponse(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/15b54439/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractControllerResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractControllerResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractControllerResourceProvider.java
index 7224d7a..6c33bdf 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractControllerResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractControllerResourceProvider.java
@@ -150,6 +150,8 @@ public abstract class AbstractControllerResourceProvider extends AbstractResourc
return new RecommendationResourceProvider(propertyIds, keyPropertyIds, managementController);
case AlertDefinition:
return new AlertDefinitionResourceProvider(propertyIds, keyPropertyIds, managementController);
+ case Controller:
+ return new ControllerResourceProvider(propertyIds, keyPropertyIds, managementController);
default:
throw new IllegalArgumentException("Unknown type " + type);
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/15b54439/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ControllerResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ControllerResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ControllerResourceProvider.java
new file mode 100644
index 0000000..9434026
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ControllerResourceProvider.java
@@ -0,0 +1,243 @@
+/**
+ * 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.controller.internal;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.controller.AmbariManagementController;
+import org.apache.ambari.server.controller.ControllerRequest;
+import org.apache.ambari.server.controller.ControllerResponse;
+import org.apache.ambari.server.controller.spi.NoSuchParentResourceException;
+import org.apache.ambari.server.controller.spi.NoSuchResourceException;
+import org.apache.ambari.server.controller.spi.Predicate;
+import org.apache.ambari.server.controller.spi.Request;
+import org.apache.ambari.server.controller.spi.RequestStatus;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.controller.spi.ResourceAlreadyExistsException;
+import org.apache.ambari.server.controller.spi.SystemException;
+import org.apache.ambari.server.controller.spi.UnsupportedPropertyException;
+import org.apache.ambari.server.controller.utilities.PropertyHelper;
+import org.apache.commons.lang.StringUtils;
+
+/**
+ * Resource provider for controller resource.
+ */
+class ControllerResourceProvider extends AbstractControllerResourceProvider {
+
+ // ----- Property ID constants ---------------------------------------------
+
+ protected static final String CONTROLLER_NAME_PROPERTY_ID = PropertyHelper.getPropertyId("Controllers", "name");
+ protected static final String CONTROLLER_LDAP_CONFIGURED_PROPERTY_ID = PropertyHelper.getPropertyId("LDAP", "configured");
+ protected static final String CONTROLLER_LDAP_USERS_PROPERTY_ID = PropertyHelper.getPropertyId("LDAP", "users");
+ protected static final String CONTROLLER_LDAP_GROUPS_PROPERTY_ID = PropertyHelper.getPropertyId("LDAP", "groups");
+ protected static final String CONTROLLER_LDAP_SYNCED_USERS_PROPERTY_ID = PropertyHelper.getPropertyId("LDAP", "synced_users");
+ protected static final String CONTROLLER_LDAP_SYNCED_GROUPS_PROPERTY_ID = PropertyHelper.getPropertyId("LDAP", "synced_groups");
+
+ private static Set<String> pkPropertyIds = new HashSet<String>(
+ Arrays.asList(new String[] { CONTROLLER_NAME_PROPERTY_ID }));
+
+ private static Map<String, ControllerResponse> controllers = new HashMap<String, ControllerResponse>() {
+ {
+ for (ControllerType type: ControllerType.values()) {
+ put(type.getName(), new ControllerResponse(type.getName()));
+ }
+ }
+ };
+
+ /**
+ * Create a new resource provider for the given management controller.
+ *
+ * @param propertyIds the property ids
+ * @param keyPropertyIds the key property ids
+ * @param managementController the management controller
+ */
+ ControllerResourceProvider(Set<String> propertyIds,
+ Map<Resource.Type, String> keyPropertyIds,
+ AmbariManagementController managementController) {
+ super(propertyIds, keyPropertyIds, managementController);
+ }
+
+ @Override
+ public RequestStatus createResources(Request request)
+ throws SystemException,
+ UnsupportedPropertyException,
+ ResourceAlreadyExistsException,
+ NoSuchParentResourceException {
+ // controllers can't be dynamically created
+ return getRequestStatus(null);
+ }
+
+ @Override
+ public Set<Resource> getResources(Request request, Predicate predicate)
+ throws SystemException, UnsupportedPropertyException, NoSuchResourceException, NoSuchParentResourceException {
+
+ final Set<ControllerRequest> requests = new HashSet<ControllerRequest>();
+
+ if (predicate == null) {
+ requests.add(getRequest(null));
+ } else {
+ for (Map<String, Object> propertyMap : getPropertyMaps(predicate)) {
+ requests.add(getRequest(propertyMap));
+ }
+ }
+
+ Set<ControllerResponse> responses = getResources(new Command<Set<ControllerResponse>>() {
+ @Override
+ public Set<ControllerResponse> invoke() throws AmbariException {
+ final Set<ControllerResponse> responses = new HashSet<ControllerResponse>();
+ for (ControllerRequest request: requests) {
+ if (request.getName() == null) {
+ responses.addAll(controllers.values());
+ } else {
+ if (controllers.containsKey(request.getName())) {
+ responses.add(controllers.get(request.getName()));
+ }
+ }
+ }
+ return responses;
+ }
+ });
+
+ Set<String> requestedIds = getRequestPropertyIds(request, predicate);
+ Set<Resource> resources = new HashSet<Resource>();
+
+ for (ControllerResponse controllerResponse : responses) {
+ ResourceImpl resource = new ResourceImpl(Resource.Type.Controller);
+
+ setResourceProperty(resource, CONTROLLER_NAME_PROPERTY_ID,
+ controllerResponse.getName(), requestedIds);
+
+ switch (ControllerType.getByName(controllerResponse.getName())) {
+ case LDAP:
+ final boolean ldapConfigured = getManagementController().checkLdapConfigured();
+ setResourceProperty(resource, CONTROLLER_LDAP_CONFIGURED_PROPERTY_ID,
+ ldapConfigured, requestedIds);
+ if (ldapConfigured) {
+ try {
+ final List<String> allUsers = new ArrayList<String>();
+ final List<String> syncedUsers = new ArrayList<String>();
+ for (Entry<String, Boolean> user : getManagementController().getLdapUsersSyncInfo().entrySet()) {
+ allUsers.add(user.getKey());
+ if (user.getValue()) {
+ syncedUsers.add(user.getKey());
+ }
+ }
+ setResourceProperty(resource, CONTROLLER_LDAP_USERS_PROPERTY_ID,
+ allUsers, requestedIds);
+ setResourceProperty(resource, CONTROLLER_LDAP_SYNCED_USERS_PROPERTY_ID,
+ syncedUsers, requestedIds);
+ final List<String> allGroups = new ArrayList<String>();
+ final List<String> syncedGroups = new ArrayList<String>();
+ for (Entry<String, Boolean> group : getManagementController().getLdapGroupsSyncInfo().entrySet()) {
+ allGroups.add(group.getKey());
+ if (group.getValue()) {
+ syncedGroups.add(group.getKey());
+ }
+ }
+ setResourceProperty(resource, CONTROLLER_LDAP_GROUPS_PROPERTY_ID,
+ allGroups, requestedIds);
+ setResourceProperty(resource, CONTROLLER_LDAP_SYNCED_GROUPS_PROPERTY_ID,
+ syncedGroups, requestedIds);
+ } catch (AmbariException ex) {
+ throw new SystemException("Can't retrieve data from external LDAP server", ex);
+ }
+ }
+ break;
+ }
+
+ resources.add(resource);
+ }
+
+ return resources;
+ }
+
+ @Override
+ public RequestStatus updateResources(Request request, Predicate predicate)
+ throws SystemException, UnsupportedPropertyException, NoSuchResourceException, NoSuchParentResourceException {
+
+ final Set<ControllerRequest> requests = new HashSet<ControllerRequest>();
+
+ for (Map<String, Object> propertyMap : getPropertyMaps(request.getProperties().iterator().next(), predicate)) {
+ final ControllerRequest req = getRequest(propertyMap);
+ requests.add(req);
+ }
+
+ // one request per each controller
+ for (final ControllerRequest controllerRequest: requests) {
+ modifyResources(new Command<Void>() {
+ @Override
+ public Void invoke() throws AmbariException {
+ switch (ControllerType.getByName(controllerRequest.getName())) {
+ case LDAP:
+ Set<String> users = new HashSet<String>();
+ if (controllerRequest.getPropertyMap().containsKey(CONTROLLER_LDAP_SYNCED_USERS_PROPERTY_ID)) {
+ final String userCsv = (String) controllerRequest.getPropertyMap().get(CONTROLLER_LDAP_SYNCED_USERS_PROPERTY_ID);
+ for (String user: userCsv.split(",")) {
+ if (StringUtils.isNotEmpty(user)) {
+ users.add(user.toLowerCase());
+ }
+ }
+ }
+ Set<String> groups = new HashSet<String>();
+ if (controllerRequest.getPropertyMap().containsKey(CONTROLLER_LDAP_SYNCED_GROUPS_PROPERTY_ID)) {
+ final String groupCsv = (String) controllerRequest.getPropertyMap().get(CONTROLLER_LDAP_SYNCED_GROUPS_PROPERTY_ID);
+ for (String group: groupCsv.split(",")) {
+ if (StringUtils.isNotEmpty(group)) {
+ groups.add(group.toLowerCase());
+ }
+ }
+ }
+ getManagementController().synchronizeLdapUsersAndGroups(users, groups);
+ break;
+ }
+ return null;
+ }
+ });
+ }
+
+ return getRequestStatus(null);
+ }
+
+ @Override
+ public RequestStatus deleteResources(Predicate predicate)
+ throws SystemException, UnsupportedPropertyException, NoSuchResourceException, NoSuchParentResourceException {
+ // controllers can't be removed
+ return getRequestStatus(null);
+ }
+
+ @Override
+ protected Set<String> getPKPropertyIds() {
+ return pkPropertyIds;
+ }
+
+ private ControllerRequest getRequest(Map<String, Object> properties) {
+ if (properties == null) {
+ return new ControllerRequest(null, properties);
+ }
+ final ControllerRequest request = new ControllerRequest((String) properties.get(CONTROLLER_NAME_PROPERTY_ID), properties);
+ return request;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/15b54439/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ControllerType.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ControllerType.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ControllerType.java
new file mode 100644
index 0000000..82b6eac
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ControllerType.java
@@ -0,0 +1,65 @@
+/**
+ * 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.controller.internal;
+
+import org.apache.commons.lang.StringUtils;
+
+/**
+ * Enumeration of internal controllers used via API.
+ */
+public enum ControllerType {
+ LDAP("ldap");
+
+ /**
+ * Controller name.
+ */
+ private String name;
+
+ /**
+ * Constructor.
+ *
+ * @param name controller name
+ */
+ private ControllerType(String name) {
+ this.name = name;
+ }
+
+ /**
+ * Getter.
+ *
+ * @return controller name
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Returns corresponding controller type to given name.
+ *
+ * @param name controller name
+ * @return null if controller type was not found
+ */
+ public static ControllerType getByName(String name) {
+ for (ControllerType type : ControllerType.values()) {
+ if (StringUtils.equals(type.getName(), name)) {
+ return type;
+ }
+ }
+ return null;
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/15b54439/ambari-server/src/main/java/org/apache/ambari/server/controller/spi/Resource.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/spi/Resource.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/spi/Resource.java
index 51a3086..41b38fa 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/spi/Resource.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/spi/Resource.java
@@ -117,7 +117,8 @@ public interface Resource {
AmbariPrivilege,
ClusterPrivilege,
ViewPrivilege,
- ViewPermission;
+ ViewPermission,
+ Controller;
/**
* Get the {@link Type} that corresponds to this InternalType.
@@ -196,6 +197,7 @@ public interface Resource {
public static final Type ClusterPrivilege = InternalType.ClusterPrivilege.getType();
public static final Type ViewPrivilege = InternalType.ViewPrivilege.getType();
public static final Type ViewPermission = InternalType.ViewPermission.getType();
+ public static final Type Controller = InternalType.Controller.getType();
/**
* The type name.
http://git-wip-us.apache.org/repos/asf/ambari/blob/15b54439/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/GroupDAO.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/GroupDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/GroupDAO.java
index bedf24a..b918454 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/GroupDAO.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/GroupDAO.java
@@ -26,7 +26,6 @@ import javax.persistence.TypedQuery;
import org.apache.ambari.server.orm.RequiresSession;
import org.apache.ambari.server.orm.entities.GroupEntity;
-
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;
http://git-wip-us.apache.org/repos/asf/ambari/blob/15b54439/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/AmbariLdapAuthenticationProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/AmbariLdapAuthenticationProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/AmbariLdapAuthenticationProvider.java
index 20cf2fd..3818e37 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/AmbariLdapAuthenticationProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/AmbariLdapAuthenticationProvider.java
@@ -110,7 +110,7 @@ public class AmbariLdapAuthenticationProvider implements AuthenticationProvider
}
//TODO change properties
- String userSearchBase = ldapServerProperties.get().getUserSearchBase();
+ String userSearchBase = ldapServerProperties.get().getUserBase();
String userSearchFilter = ldapServerProperties.get().getUserSearchFilter();
FilterBasedLdapUserSearch userSearch = new FilterBasedLdapUserSearch(userSearchBase, userSearchFilter, springSecurityContextSource);
http://git-wip-us.apache.org/repos/asf/ambari/blob/15b54439/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/AmbariLdapDataPopulator.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/AmbariLdapDataPopulator.java b/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/AmbariLdapDataPopulator.java
new file mode 100644
index 0000000..c4a6eaa
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/AmbariLdapDataPopulator.java
@@ -0,0 +1,419 @@
+/**
+ * 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.security.authorization;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import javax.naming.NamingException;
+import javax.naming.directory.Attributes;
+
+import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.configuration.Configuration;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.ldap.core.AttributesMapper;
+import org.springframework.ldap.core.ContextMapper;
+import org.springframework.ldap.core.DirContextAdapter;
+import org.springframework.ldap.core.LdapTemplate;
+import org.springframework.ldap.core.support.LdapContextSource;
+import org.springframework.ldap.filter.AndFilter;
+import org.springframework.ldap.filter.EqualsFilter;
+import org.springframework.security.core.userdetails.UsernameNotFoundException;
+
+import com.google.inject.Inject;
+
+/**
+ * Provides users, groups and membership population from LDAP catalog.
+ */
+public class AmbariLdapDataPopulator {
+ /**
+ * Log.
+ */
+ private static final Log LOG = LogFactory.getLog(AmbariLdapDataPopulator.class);
+
+ /**
+ * Ambari configuration.
+ */
+ private Configuration configuration;
+
+ /**
+ * Highlevel facade for management of users and groups.
+ */
+ private Users users;
+
+ /**
+ * LDAP specific properties.
+ */
+ private LdapServerProperties ldapServerProperties;
+
+ /**
+ * LDAP template for making search queries.
+ */
+ private LdapTemplate ldapTemplate;
+
+ @Inject
+ public AmbariLdapDataPopulator(Configuration configuration, Users users) {
+ this.configuration = configuration;
+ this.users = users;
+ }
+
+ /**
+ * Check if LDAP is enabled in server properties.
+ *
+ * @return true if enabled
+ */
+ public boolean isLdapEnabled() {
+ try {
+ final LdapTemplate ldapTemplate = loadLdapTemplate();
+ ldapTemplate.search(ldapServerProperties.getBaseDN(),
+ "(objectclass=person)", new AttributesMapper() {
+
+ public Object mapFromAttributes(Attributes attributes)
+ throws NamingException {
+ return attributes.get("uid").get();
+ }
+ });
+ return true;
+ } catch (Exception ex) {
+ LOG.error("Could not connect to LDAP server", ex);
+ return false;
+ }
+ }
+
+ /**
+ * Retrieves a key-value map of all LDAP groups.
+ *
+ * @return map of GroupName-Synced pairs
+ */
+ public Map<String, Boolean> getLdapGroupsSyncInfo() {
+ final Map<String, Boolean> ldapGroups = new HashMap<String, Boolean>();
+ final Map<String, Group> internalGroupsMap = getInternalGroups();
+ final Set<String> externalGroups = getExternalLdapGroupNames();
+ for (String externalGroup : externalGroups) {
+ if (internalGroupsMap.containsKey(externalGroup)
+ && internalGroupsMap.get(externalGroup).isLdapGroup()) {
+ ldapGroups.put(externalGroup, true);
+ } else {
+ ldapGroups.put(externalGroup, false);
+ }
+ }
+
+ return ldapGroups;
+ }
+
+ /**
+ * Retrieves a key-value map of all LDAP users.
+ *
+ * @return map of UserName-Synced pairs.
+ */
+ public Map<String, Boolean> getLdapUsersSyncInfo() {
+ final Map<String, Boolean> ldapUsers = new HashMap<String, Boolean>();
+ final List<User> internalUsers = users.getAllUsers();
+ final Map<String, User> internalUsersMap = new HashMap<String, User>();
+ for (User user : internalUsers) {
+ internalUsersMap.put(user.getUserName(), user);
+ }
+ final Set<String> externalUsers = getExternalLdapUserNames();
+ for (String externalUser : externalUsers) {
+ if (internalUsersMap.containsKey(externalUser)
+ && internalUsersMap.get(externalUser).isLdapUser()) {
+ ldapUsers.put(externalUser, true);
+ } else {
+ ldapUsers.put(externalUser, false);
+ }
+ }
+
+ return ldapUsers;
+ }
+
+ /**
+ * Performs synchronization of given sets of usernames and groupnames.
+ *
+ * @param users set of users to synchronize
+ * @param groups set of groups to synchronize
+ * @throws AmbariException if synchronization failed for any reason
+ */
+ public void synchronizeLdapUsersAndGroups(Set<String> users,
+ Set<String> groups) throws AmbariException {
+ // validate request
+ final Set<String> externalUsers = getExternalLdapUserNames();
+ for (String user : users) {
+ if (!externalUsers.contains(user)) {
+ throw new AmbariException("Couldn't sync LDAP user " + user
+ + ", it doesn't exist");
+ }
+ }
+ final Set<String> externalGroups = getExternalLdapGroupNames();
+ for (String group : groups) {
+ if (!externalGroups.contains(group)) {
+ throw new AmbariException("Couldn't sync LDAP group " + group
+ + ", it doesn't exist");
+ }
+ }
+
+ // processing groups
+ final Map<String, Group> internalGroupsMap = getInternalGroups();
+ for (String groupName : groups) {
+ if (internalGroupsMap.containsKey(groupName)) {
+ final Group group = internalGroupsMap.get(groupName);
+ if (!group.isLdapGroup()) {
+ this.users.setGroupLdap(groupName);
+ }
+ } else {
+ this.users.createGroup(groupName);
+ this.users.setGroupLdap(groupName);
+ }
+ refreshGroupMembers(groupName);
+ internalGroupsMap.remove(groupName);
+ }
+ for (Entry<String, Group> internalGroup : internalGroupsMap.entrySet()) {
+ if (internalGroup.getValue().isLdapGroup()) {
+ this.users.removeGroup(internalGroup.getValue());
+ }
+ }
+
+ cleanUpLdapUsersWithoutGroup();
+
+ // processing users
+ final Map<String, User> internalUsersMap = getInternalUsers();
+ for (String userName : users) {
+ if (internalUsersMap.containsKey(userName)) {
+ final User user = internalUsersMap.get(userName);
+ if (!user.isLdapUser()) {
+ this.users.setUserLdap(userName);
+ }
+ } else {
+ this.users.createUser(userName, "");
+ this.users.setUserLdap(userName);
+ }
+ }
+
+ }
+
+ /**
+ * Check group members of the synced group: add missing ones and remove the ones absent in external LDAP.
+ *
+ * @param groupName group name
+ * @throws AmbariException if group refresh failed
+ */
+ private void refreshGroupMembers(String groupName) throws AmbariException {
+ final Set<String> externalMembers = getExternalLdapGroupMembers(groupName);
+ final Map<String, User> internalUsers = getInternalUsers();
+ final Map<String, User> internalMembers = getInternalMembers(groupName);
+ for (String externalMember: externalMembers) {
+ if (internalUsers.containsKey(externalMember)) {
+ final User user = internalUsers.get(externalMember);
+ if (!user.isLdapUser()) {
+ users.setUserLdap(externalMember);
+ }
+ internalUsers.remove(externalMember);
+ internalMembers.remove(externalMember);
+ } else {
+ users.createUser(externalMember, "");
+ users.setUserLdap(externalMember);
+ }
+ users.addMemberToGroup(groupName, externalMember);
+ }
+ for (Entry<String, User> userToBeUnsynced: internalMembers.entrySet()) {
+ final User user = userToBeUnsynced.getValue();
+ users.removeMemberFromGroup(groupName, user.getUserName());
+ }
+ }
+
+ /**
+ * Removes synced users which are not present in any of group.
+ *
+ * @throws AmbariException
+ */
+ private void cleanUpLdapUsersWithoutGroup() throws AmbariException {
+ final List<User> allUsers = users.getAllUsers();
+ for (User user: allUsers) {
+ if (user.isLdapUser() && user.getGroups().isEmpty()) {
+ users.removeUser(user);
+ }
+ }
+ }
+
+ // Utility methods
+
+ /**
+ * Retrieves groups from external LDAP server.
+ *
+ * @return set of user names
+ */
+ private Set<String> getExternalLdapGroupNames() {
+ final Set<String> groups = new HashSet<String>();
+ final LdapTemplate ldapTemplate = loadLdapTemplate();
+ final EqualsFilter equalsFilter = new EqualsFilter("objectClass",
+ ldapServerProperties.getGroupObjectClass());
+ String baseDn = ldapServerProperties.getGroupBase();
+ if (baseDn == null) {
+ baseDn = ldapServerProperties.getBaseDN();
+ }
+ ldapTemplate.search(baseDn, equalsFilter.encode(), new AttributesMapper() {
+
+ public Object mapFromAttributes(Attributes attributes)
+ throws NamingException {
+ groups.add(attributes.get(ldapServerProperties.getGroupNamingAttr())
+ .get().toString().toLowerCase());
+ return null;
+ }
+ });
+ return groups;
+ }
+
+ /**
+ * Retrieves users from external LDAP server.
+ *
+ * @return set of user names
+ */
+ private Set<String> getExternalLdapUserNames() {
+ final Set<String> users = new HashSet<String>();
+ final LdapTemplate ldapTemplate = loadLdapTemplate();
+ final EqualsFilter equalsFilter = new EqualsFilter("objectClass",
+ ldapServerProperties.getUserObjectClass());
+ String baseDn = ldapServerProperties.getUserBase();
+ if (baseDn == null) {
+ baseDn = ldapServerProperties.getBaseDN();
+ }
+ ldapTemplate.search(baseDn, equalsFilter.encode(), new AttributesMapper() {
+
+ public Object mapFromAttributes(Attributes attributes)
+ throws NamingException {
+ users.add(attributes.get(ldapServerProperties.getUsernameAttribute())
+ .get().toString().toLowerCase());
+ return null;
+ }
+ });
+ return users;
+ }
+
+ /**
+ * Retrieves members of the specified group from external LDAP server.
+ *
+ * @param groupName group name
+ * @return set of group names
+ */
+ private Set<String> getExternalLdapGroupMembers(String groupName) {
+ final Set<String> members = new HashSet<String>();
+ final LdapTemplate ldapTemplate = loadLdapTemplate();
+ final AndFilter andFilter = new AndFilter();
+ andFilter.and(new EqualsFilter("objectClass", ldapServerProperties.getGroupObjectClass()));
+ andFilter.and(new EqualsFilter(ldapServerProperties.getGroupNamingAttr(), groupName));
+ String baseDn = ldapServerProperties.getGroupBase();
+ if (baseDn == null) {
+ baseDn = ldapServerProperties.getBaseDN();
+ }
+ ldapTemplate.search(baseDn, andFilter.encode(), new ContextMapper() {
+
+ public Object mapFromContext(Object ctx) {
+ final DirContextAdapter adapter = (DirContextAdapter) ctx;
+ for (String uniqueMember: adapter.getStringAttributes(ldapServerProperties.getGroupMembershipAttr())) {
+ final DirContextAdapter userAdapter = (DirContextAdapter) ldapTemplate.lookup(uniqueMember);
+ members.add(userAdapter.getStringAttribute(ldapServerProperties.getUsernameAttribute().toLowerCase()));
+ }
+ return null;
+ }
+ });
+ return members;
+ }
+
+ /**
+ * Creates a map of internal groups.
+ *
+ * @return map of GroupName-Group pairs
+ */
+ private Map<String, Group> getInternalGroups() {
+ final List<Group> internalGroups = users.getAllGroups();
+ final Map<String, Group> internalGroupsMap = new HashMap<String, Group>();
+ for (Group group : internalGroups) {
+ internalGroupsMap.put(group.getGroupName(), group);
+ }
+ return internalGroupsMap;
+ }
+
+ /**
+ * Creates a map of internal users.
+ *
+ * @return map of UserName-User pairs
+ */
+ private Map<String, User> getInternalUsers() {
+ final List<User> internalUsers = users.getAllUsers();
+ final Map<String, User> internalUsersMap = new HashMap<String, User>();
+ for (User user : internalUsers) {
+ internalUsersMap.put(user.getUserName(), user);
+ }
+ return internalUsersMap;
+ }
+
+ /**
+ * Creates a map of internal users present in specified group.
+ *
+ * @param groupName group name
+ * @return map of UserName-User pairs
+ */
+ private Map<String, User> getInternalMembers(String groupName) {
+ final Collection<User> internalMembers = users.getGroupMembers(groupName);
+ final Map<String, User> internalMembersMap = new HashMap<String, User>();
+ for (User user : internalMembers) {
+ internalMembersMap.put(user.getUserName(), user);
+ }
+ return internalMembersMap;
+ }
+
+ /**
+ * Checks LDAP configuration for changes and reloads LDAP template if they occured.
+ *
+ * @return LdapTemplate instance
+ */
+ private LdapTemplate loadLdapTemplate() {
+ final LdapServerProperties properties = configuration
+ .getLdapServerProperties();
+ if (ldapTemplate == null || !properties.equals(ldapServerProperties)) {
+ LOG.info("Reloading properties");
+ ldapServerProperties = properties;
+
+ final LdapContextSource ldapContextSource = new LdapContextSource();
+ final List<String> ldapUrls = ldapServerProperties.getLdapUrls();
+ ldapContextSource.setUrls(ldapUrls.toArray(new String[ldapUrls.size()]));
+
+ if (!ldapServerProperties.isAnonymousBind()) {
+ ldapContextSource.setUserDn(ldapServerProperties.getManagerDn());
+ ldapContextSource
+ .setPassword(ldapServerProperties.getManagerPassword());
+ }
+
+ try {
+ ldapContextSource.afterPropertiesSet();
+ } catch (Exception e) {
+ LOG.error("LDAP Context Source not loaded ", e);
+ throw new UsernameNotFoundException("LDAP Context Source not loaded", e);
+ }
+
+ ldapTemplate = new LdapTemplate(ldapContextSource);
+ }
+ return ldapTemplate;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/15b54439/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/LdapServerProperties.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/LdapServerProperties.java b/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/LdapServerProperties.java
index 8f9eb81..e13f131 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/LdapServerProperties.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/LdapServerProperties.java
@@ -35,8 +35,6 @@ public class LdapServerProperties {
private String managerDn;
private String managerPassword;
private String baseDN;
- private String userSearchBase = "";
- private String usernameAttribute;
//LDAP group properties
private String groupBase;
@@ -46,6 +44,11 @@ public class LdapServerProperties {
private String adminGroupMappingRules;
private boolean groupMappingEnabled;
+ //LDAP user properties
+ private String userBase;
+ private String userObjectClass;
+ private String usernameAttribute;
+
private String groupSearchFilter;
private static final String userSearchFilter = "({attribute}={0})";
@@ -120,14 +123,6 @@ public class LdapServerProperties {
this.baseDN = baseDN;
}
- public String getUserSearchBase() {
- return userSearchBase;
- }
-
- public void setUserSearchBase(String userSearchBase) {
- this.userSearchBase = userSearchBase;
- }
-
public String getUserSearchFilter() {
return userSearchFilter.replace("{attribute}", usernameAttribute);
}
@@ -196,6 +191,22 @@ public class LdapServerProperties {
this.groupMappingEnabled = groupMappingEnabled;
}
+ public void setUserBase(String userBase) {
+ this.userBase = userBase;
+ }
+
+ public void setUserObjectClass(String userObjectClass) {
+ this.userObjectClass = userObjectClass;
+ }
+
+ public String getUserBase() {
+ return userBase;
+ }
+
+ public String getUserObjectClass() {
+ return userObjectClass;
+ }
+
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
@@ -211,7 +222,9 @@ public class LdapServerProperties {
if (managerPassword != null ? !managerPassword.equals(that.managerPassword) : that.managerPassword != null)
return false;
if (baseDN != null ? !baseDN.equals(that.baseDN) : that.baseDN != null) return false;
- if (userSearchBase != null ? !userSearchBase.equals(that.userSearchBase) : that.userSearchBase != null)
+ if (userBase != null ? !userBase.equals(that.userBase) : that.userBase != null)
+ return false;
+ if (userObjectClass != null ? !userObjectClass.equals(that.userObjectClass) : that.userObjectClass != null)
return false;
if (usernameAttribute != null ? !usernameAttribute.equals(that.usernameAttribute) : that.usernameAttribute != null)
return false;
@@ -240,7 +253,8 @@ public class LdapServerProperties {
result = 31 * result + (managerDn != null ? managerDn.hashCode() : 0);
result = 31 * result + (managerPassword != null ? managerPassword.hashCode() : 0);
result = 31 * result + (baseDN != null ? baseDN.hashCode() : 0);
- result = 31 * result + (userSearchBase != null ? userSearchBase.hashCode() : 0);
+ result = 31 * result + (userBase != null ? userBase.hashCode() : 0);
+ result = 31 * result + (userObjectClass != null ? userObjectClass.hashCode() : 0);
result = 31 * result + (usernameAttribute != null ? usernameAttribute.hashCode() : 0);
result = 31 * result + (groupBase != null ? groupBase.hashCode() : 0);
result = 31 * result + (groupObjectClass != null ? groupObjectClass.hashCode() : 0);
http://git-wip-us.apache.org/repos/asf/ambari/blob/15b54439/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/Member.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/Member.java b/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/Member.java
deleted file mode 100644
index da4732a..0000000
--- a/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/Member.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * 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.security.authorization;
-
-import org.apache.ambari.server.orm.entities.GroupEntity;
-
-/**
- * Describes group of users of web-service.
- */
-public class Member {
- private final int groupId;
- private final String groupName;
- private final boolean ldapGroup;
-
- Member(GroupEntity groupEntity) {
- this.groupId = groupEntity.getGroupId();
- this.groupName = groupEntity.getGroupName();
- this.ldapGroup = groupEntity.getLdapGroup();
- }
-
- public int getGroupId() {
- return groupId;
- }
-
- public String getGroupName() {
- return groupName;
- }
-
- public boolean isLdapGroup() {
- return ldapGroup;
- }
-
- @Override
- public String toString() {
- return "Group [groupId=" + groupId + ", groupName=" + groupName
- + ", ldapGroup=" + ldapGroup + "]";
- }
-}
http://git-wip-us.apache.org/repos/asf/ambari/blob/15b54439/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/User.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/User.java b/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/User.java
index f9f8e21..e0e84c2 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/User.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/User.java
@@ -17,13 +17,14 @@
*/
package org.apache.ambari.server.security.authorization;
-import org.apache.ambari.server.orm.entities.RoleEntity;
-import org.apache.ambari.server.orm.entities.UserEntity;
-
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
+import org.apache.ambari.server.orm.entities.MemberEntity;
+import org.apache.ambari.server.orm.entities.RoleEntity;
+import org.apache.ambari.server.orm.entities.UserEntity;
+
/**
* Describes user of web-services
*/
@@ -34,6 +35,7 @@ public class User {
final Date createTime;
final boolean active;
final Collection<String> roles = new ArrayList<String>();
+ final Collection<String> groups = new ArrayList<String>();
User(UserEntity userEntity) {
userId = userEntity.getUserId();
@@ -44,6 +46,9 @@ public class User {
for (RoleEntity roleEntity : userEntity.getRoleEntities()) {
roles.add(roleEntity.getRoleName());
}
+ for (MemberEntity memberEntity : userEntity.getMemberEntities()) {
+ groups.add(memberEntity.getGroup().getGroupName());
+ }
}
public int getUserId() {
@@ -70,6 +75,10 @@ public class User {
return roles;
}
+ public Collection<String> getGroups() {
+ return groups;
+ }
+
@Override
public String toString() {
return (ldapUser ? "[LDAP]" : "[LOCAL]") + userName;
http://git-wip-us.apache.org/repos/asf/ambari/blob/15b54439/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/Users.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/Users.java b/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/Users.java
index f3050ce..cbafb16 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/Users.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/Users.java
@@ -185,6 +185,38 @@ public class Users {
}
/**
+ * Converts user to LDAP user.
+ *
+ * @param userName user name
+ * @throws AmbariException if user does not exist
+ */
+ public synchronized void setUserLdap(String userName) throws AmbariException {
+ UserEntity userEntity = userDAO.findLocalUserByName(userName);
+ if (userEntity != null) {
+ userEntity.setLdapUser(true);
+ userDAO.merge(userEntity);
+ } else {
+ throw new AmbariException("User " + userName + " doesn't exist or is already an LDAP user");
+ }
+ }
+
+ /**
+ * Converts group to LDAP group.
+ *
+ * @param groupName group name
+ * @throws AmbariException if group does not exist
+ */
+ public synchronized void setGroupLdap(String groupName) throws AmbariException {
+ GroupEntity groupEntity = groupDAO.findGroupByName(groupName);
+ if (groupEntity != null) {
+ groupEntity.setLdapGroup(true);
+ groupDAO.merge(groupEntity);
+ } else {
+ throw new AmbariException("Group " + groupName + " doesn't exist");
+ }
+ }
+
+ /**
* Creates new local user with provided userName and password
*/
@Transactional
http://git-wip-us.apache.org/repos/asf/ambari/blob/15b54439/ambari-server/src/main/resources/key_properties.json
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/key_properties.json b/ambari-server/src/main/resources/key_properties.json
index 3c63ccb..b693dec 100644
--- a/ambari-server/src/main/resources/key_properties.json
+++ b/ambari-server/src/main/resources/key_properties.json
@@ -143,5 +143,8 @@
"AlertDefinition": {
"Cluster": "AlertDefinition/cluster_name",
"AlertDefinition": "AlertDefinition/id"
+ },
+ "Controller": {
+ "Controller": "Controllers/name"
}
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/15b54439/ambari-server/src/main/resources/properties.json
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/properties.json b/ambari-server/src/main/resources/properties.json
index 697a44c..1716973 100644
--- a/ambari-server/src/main/resources/properties.json
+++ b/ambari-server/src/main/resources/properties.json
@@ -397,5 +397,14 @@
"AlertDefinition/enabled",
"AlertDefinition/scope",
"AlertDefinition/source"
+ ],
+ "Controller":[
+ "Controllers/name",
+ "LDAP/configured",
+ "LDAP/users",
+ "LDAP/groups",
+ "LDAP/synced_users",
+ "LDAP/synced_groups",
+ "_"
]
}