You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by rn...@apache.org on 2015/10/28 22:58:57 UTC
[3/3] ambari git commit: AMBARI-13431. Blueprints Configuration to
select Kerberos. (Sandor Magyari via rnettleton)
AMBARI-13431. Blueprints Configuration to select Kerberos. (Sandor Magyari via rnettleton)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/2337e539
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/2337e539
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/2337e539
Branch: refs/heads/trunk
Commit: 2337e5390cac806f80db0e1880b8616cfab7e80d
Parents: f2ce9db
Author: Bob Nettleton <rn...@hortonworks.com>
Authored: Wed Oct 28 17:57:30 2015 -0400
Committer: Bob Nettleton <rn...@hortonworks.com>
Committed: Wed Oct 28 17:58:21 2015 -0400
----------------------------------------------------------------------
.../AmbariManagementControllerImpl.java | 107 +++++----
.../ambari/server/controller/AmbariServer.java | 103 +++++----
.../server/controller/ControllerModule.java | 4 +-
.../controller/internal/BaseClusterRequest.java | 21 +-
.../BlueprintConfigurationProcessor.java | 5 +
.../internal/BlueprintResourceProvider.java | 60 +++--
.../internal/ClusterResourceProvider.java | 74 ++++--
.../internal/ExportBlueprintRequest.java | 2 +-
.../KerberosDescriptorResourceProvider.java | 6 +
.../internal/ProvisionClusterRequest.java | 53 ++++-
.../server/orm/entities/BlueprintEntity.java | 34 ++-
.../apache/ambari/server/state/Clusters.java | 18 +-
.../server/state/cluster/ClustersImpl.java | 42 ++--
.../ambari/server/topology/AmbariContext.java | 26 +--
.../ambari/server/topology/Blueprint.java | 2 +
.../server/topology/BlueprintFactory.java | 6 +-
.../ambari/server/topology/BlueprintImpl.java | 33 ++-
.../ambari/server/topology/Credential.java | 71 ++++++
.../server/topology/SecurityConfiguration.java | 67 ++++++
.../topology/SecurityConfigurationFactory.java | 175 ++++++++++++++
.../ambari/server/topology/TopologyManager.java | 226 +++++++++++++++----
.../server/topology/TopologyRequestFactory.java | 3 +-
.../topology/TopologyRequestFactoryImpl.java | 5 +-
.../server/upgrade/UpgradeCatalog213.java | 18 +-
.../main/resources/Ambari-DDL-MySQL-CREATE.sql | 2 +
.../main/resources/Ambari-DDL-Oracle-CREATE.sql | 2 +
.../resources/Ambari-DDL-Postgres-CREATE.sql | 2 +
.../Ambari-DDL-Postgres-EMBEDDED-CREATE.sql | 2 +
.../resources/Ambari-DDL-SQLAnywhere-CREATE.sql | 2 +
.../resources/Ambari-DDL-SQLServer-CREATE.sql | 2 +
.../src/main/resources/properties.json | 1 +
.../internal/AlertResourceProviderTest.java | 54 ++---
.../internal/BlueprintResourceProviderTest.java | 145 ++++++++----
.../internal/ClusterResourceProviderTest.java | 128 ++++++++---
.../internal/ProvisionClusterRequestTest.java | 68 ++++--
.../internal/WidgetResourceProviderTest.java | 6 +-
.../ambari/server/state/UpgradeHelperTest.java | 63 +++---
.../server/state/cluster/ClustersTest.java | 45 ++--
.../server/topology/AmbariContextTest.java | 22 +-
.../server/topology/BlueprintFactoryTest.java | 12 +-
.../server/topology/BlueprintImplTest.java | 16 +-
.../SecurityConfigurationFactoryTest.java | 163 +++++++++++++
.../server/topology/TopologyManagerTest.java | 29 ++-
.../server/upgrade/UpgradeCatalog213Test.java | 15 ++
.../ambari/server/utils/StageUtilsTest.java | 72 +++---
45 files changed, 1531 insertions(+), 481 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/2337e539/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 3a04a90..5f432ef 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,49 +18,16 @@
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.CLIENTS_TO_UPDATE_CONFIGS;
-import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.COMMAND_RETRY_ENABLED;
-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.GROUP_LIST;
-import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.HOOKS_FOLDER;
-import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.MAX_DURATION_OF_RETRIES;
-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.USER_LIST;
-import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.VERSION;
-
-import java.io.File;
-import java.io.FileReader;
-import java.io.IOException;
-import java.lang.reflect.Type;
-import java.net.InetAddress;
-import java.text.MessageFormat;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.EnumMap;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedHashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.TreeMap;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.locks.Lock;
-
+import com.google.common.cache.Cache;
+import com.google.common.cache.CacheBuilder;
+import com.google.common.collect.ArrayListMultimap;
+import com.google.common.collect.Multimap;
+import com.google.gson.Gson;
+import com.google.gson.reflect.TypeToken;
+import com.google.inject.Inject;
+import com.google.inject.Injector;
+import com.google.inject.Singleton;
+import com.google.inject.persist.Transactional;
import org.apache.ambari.server.AmbariException;
import org.apache.ambari.server.ClusterNotFoundException;
import org.apache.ambari.server.DuplicateResourceException;
@@ -172,16 +139,48 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.core.GrantedAuthority;
-import com.google.common.cache.Cache;
-import com.google.common.cache.CacheBuilder;
-import com.google.common.collect.ArrayListMultimap;
-import com.google.common.collect.Multimap;
-import com.google.gson.Gson;
-import com.google.gson.reflect.TypeToken;
-import com.google.inject.Inject;
-import com.google.inject.Injector;
-import com.google.inject.Singleton;
-import com.google.inject.persist.Transactional;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.lang.reflect.Type;
+import java.net.InetAddress;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.EnumMap;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.Lock;
+
+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.CLIENTS_TO_UPDATE_CONFIGS;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.COMMAND_RETRY_ENABLED;
+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.GROUP_LIST;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.HOOKS_FOLDER;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.MAX_DURATION_OF_RETRIES;
+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.USER_LIST;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.VERSION;
@Singleton
public class AmbariManagementControllerImpl implements AmbariManagementController {
@@ -419,7 +418,7 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
throw new HostNotFoundException(invalidHostsStr.toString());
}
- clusters.addCluster(request.getClusterName(), stackId);
+ clusters.addCluster(request.getClusterName(), stackId, request.getSecurityType());
Cluster c = clusters.getCluster(request.getClusterName());
if (request.getHostNames() != null) {
http://git-wip-us.apache.org/repos/asf/ambari/blob/2337e539/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 12373f0..9044e37 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
@@ -7,7 +7,7 @@
* "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
+ * 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,
@@ -19,19 +19,16 @@
package org.apache.ambari.server.controller;
-import java.io.File;
-import java.io.IOException;
-import java.net.Authenticator;
-import java.net.BindException;
-import java.net.PasswordAuthentication;
-import java.net.URL;
-import java.util.EnumSet;
-import java.util.Enumeration;
-import java.util.Map;
-
-import javax.crypto.BadPaddingException;
-import javax.servlet.DispatcherType;
-
+import com.google.common.util.concurrent.ServiceManager;
+import com.google.gson.Gson;
+import com.google.inject.Guice;
+import com.google.inject.Inject;
+import com.google.inject.Injector;
+import com.google.inject.Scopes;
+import com.google.inject.Singleton;
+import com.google.inject.name.Named;
+import com.google.inject.persist.Transactional;
+import com.sun.jersey.spi.container.servlet.ServletContainer;
import org.apache.ambari.eventdb.webservice.WorkflowJsonService;
import org.apache.ambari.server.AmbariException;
import org.apache.ambari.server.StateRecoveryManager;
@@ -98,6 +95,7 @@ import org.apache.ambari.server.security.unsecured.rest.ConnectionInfo;
import org.apache.ambari.server.state.Clusters;
import org.apache.ambari.server.topology.AmbariContext;
import org.apache.ambari.server.topology.BlueprintFactory;
+import org.apache.ambari.server.topology.SecurityConfigurationFactory;
import org.apache.ambari.server.topology.TopologyManager;
import org.apache.ambari.server.topology.TopologyRequestFactoryImpl;
import org.apache.ambari.server.utils.StageUtils;
@@ -112,8 +110,8 @@ import org.eclipse.jetty.server.ssl.SslSelectChannelConnector;
import org.eclipse.jetty.servlet.DefaultServlet;
import org.eclipse.jetty.servlet.FilterHolder;
import org.eclipse.jetty.servlet.ServletContextHandler;
-import org.eclipse.jetty.servlets.GzipFilter;
import org.eclipse.jetty.servlet.ServletHolder;
+import org.eclipse.jetty.servlets.GzipFilter;
import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.eclipse.jetty.util.thread.QueuedThreadPool;
import org.slf4j.Logger;
@@ -127,16 +125,17 @@ import org.springframework.web.context.request.RequestContextListener;
import org.springframework.web.context.support.GenericWebApplicationContext;
import org.springframework.web.filter.DelegatingFilterProxy;
-import com.google.common.util.concurrent.ServiceManager;
-import com.google.gson.Gson;
-import com.google.inject.Guice;
-import com.google.inject.Inject;
-import com.google.inject.Injector;
-import com.google.inject.Scopes;
-import com.google.inject.Singleton;
-import com.google.inject.name.Named;
-import com.google.inject.persist.Transactional;
-import com.sun.jersey.spi.container.servlet.ServletContainer;
+import javax.crypto.BadPaddingException;
+import javax.servlet.DispatcherType;
+import java.io.File;
+import java.io.IOException;
+import java.net.Authenticator;
+import java.net.BindException;
+import java.net.PasswordAuthentication;
+import java.net.URL;
+import java.util.EnumSet;
+import java.util.Enumeration;
+import java.util.Map;
@Singleton
public class AmbariServer {
@@ -153,27 +152,27 @@ public class AmbariServer {
static {
Velocity.setProperty("runtime.log.logsystem.log4j.logger", VELOCITY_LOG_CATEGORY);
}
-
+
private static final String CLASSPATH_CHECK_CLASS = "org/apache/ambari/server/controller/AmbariServer.class";
private static final String CLASSPATH_SANITY_CHECK_FAILURE_MESSAGE = "%s class is found in multiple jar files. Possible reasons include multiple ambari server jar files in the ambari classpath.\n" +
- "Check for additional ambari server jar files and check that /usr/lib/ambari-server/ambari-server*.jar matches only one file.";
-
+ "Check for additional ambari server jar files and check that /usr/lib/ambari-server/ambari-server*.jar matches only one file.";
+
static {
Enumeration<URL> ambariServerClassUrls;
try {
ambariServerClassUrls = AmbariServer.class.getClassLoader().getResources(CLASSPATH_CHECK_CLASS);
-
+
int ambariServerClassUrlsSize = 0;
- while(ambariServerClassUrls.hasMoreElements()){
+ while (ambariServerClassUrls.hasMoreElements()) {
ambariServerClassUrlsSize++;
URL url = ambariServerClassUrls.nextElement();
LOG.info(String.format("Found %s class in %s", CLASSPATH_CHECK_CLASS, url.getPath()));
}
- if(ambariServerClassUrlsSize>1) {
+ if (ambariServerClassUrlsSize > 1) {
throw new RuntimeException(String.format(CLASSPATH_SANITY_CHECK_FAILURE_MESSAGE, CLASSPATH_CHECK_CLASS));
}
} catch (IOException e) {
- e.printStackTrace();
+ e.printStackTrace();
}
}
@@ -331,7 +330,7 @@ public class AmbariServer {
if (configs.getApiAuthentication()) {
root.addFilter(new FilterHolder(springSecurityFilter), "/api/*", DISPATCHER_TYPES);
- // root.addFilter(new FilterHolder(springSecurityFilter), "/proxy/*", DISPATCHER_TYPES);
+ // root.addFilter(new FilterHolder(springSecurityFilter), "/proxy/*", DISPATCHER_TYPES);
}
@@ -441,7 +440,7 @@ public class AmbariServer {
if (configs.csrfProtectionEnabled()) {
sh.setInitParameter("com.sun.jersey.spi.container.ContainerRequestFilters",
- "org.apache.ambari.server.api.AmbariCsrfProtectionFilter");
+ "org.apache.ambari.server.api.AmbariCsrfProtectionFilter");
/* proxy.setInitParameter("com.sun.jersey.spi.container.ContainerRequestFilters",
"org.apache.ambari.server.api.AmbariCsrfProtectionFilter"); */
}
@@ -460,7 +459,7 @@ public class AmbariServer {
if (configs.getApiSSLAuthentication()) {
String httpsKeystore = configsMap.get(Configuration.CLIENT_API_SSL_KSTR_DIR_NAME_KEY) +
- File.separator + configsMap.get(Configuration.CLIENT_API_SSL_KSTR_NAME_KEY);
+ File.separator + configsMap.get(Configuration.CLIENT_API_SSL_KSTR_NAME_KEY);
String httpsTruststore = configsMap.get(Configuration.CLIENT_API_SSL_KSTR_DIR_NAME_KEY) +
File.separator + configsMap.get(Configuration.CLIENT_API_SSL_TSTR_NAME_KEY);
LOG.info("API SSL Authentication is turned on. Keystore - " + httpsKeystore);
@@ -480,8 +479,7 @@ public class AmbariServer {
sapiConnector.setTruststoreType(configsMap.get(Configuration.CLIENT_API_SSL_KSTR_TYPE_KEY));
sapiConnector.setMaxIdleTime(configs.getConnectionMaxIdleTime());
apiConnector = sapiConnector;
- }
- else {
+ } else {
apiConnector = new SelectChannelConnector();
apiConnector.setPort(configs.getClientApiPort());
apiConnector.setMaxIdleTime(configs.getConnectionMaxIdleTime());
@@ -518,13 +516,13 @@ public class AmbariServer {
LOG.info("********* Initializing Scheduled Request Manager **********");
ExecutionScheduleManager executionScheduleManager = injector
- .getInstance(ExecutionScheduleManager.class);
+ .getInstance(ExecutionScheduleManager.class);
clusterController = controller;
StateRecoveryManager recoveryManager = injector.getInstance(
- StateRecoveryManager.class);
+ StateRecoveryManager.class);
recoveryManager.doWork();
/*
@@ -546,11 +544,11 @@ public class AmbariServer {
server.join();
LOG.info("Joined the Server");
- } catch (BadPaddingException bpe){
+ } catch (BadPaddingException bpe) {
LOG.error("Bad keystore or private key password. " +
- "HTTPS certificate re-importing may be required.");
+ "HTTPS certificate re-importing may be required.");
throw bpe;
- } catch(BindException bindException) {
+ } catch (BindException bindException) {
LOG.error("Could not bind to server port - instance may already be running. " +
"Terminating this instance.", bindException);
throw bindException;
@@ -562,12 +560,12 @@ public class AmbariServer {
* at server properties)
*/
private void disableInsecureProtocols(SslContextFactory factory) {
- if (! configs.getSrvrDisabledCiphers().isEmpty()) {
- String [] masks = configs.getSrvrDisabledCiphers().split(DISABLED_ENTRIES_SPLITTER);
+ if (!configs.getSrvrDisabledCiphers().isEmpty()) {
+ String[] masks = configs.getSrvrDisabledCiphers().split(DISABLED_ENTRIES_SPLITTER);
factory.setExcludeCipherSuites(masks);
}
- if (! configs.getSrvrDisabledProtocols().isEmpty()) {
- String [] masks = configs.getSrvrDisabledProtocols().split(DISABLED_ENTRIES_SPLITTER);
+ if (!configs.getSrvrDisabledProtocols().isEmpty()) {
+ String[] masks = configs.getSrvrDisabledProtocols().split(DISABLED_ENTRIES_SPLITTER);
factory.setExcludeProtocols(masks);
}
}
@@ -599,11 +597,11 @@ public class AmbariServer {
FilterHolder gzipFilter = context.addFilter(GzipFilter.class, "/*",
EnumSet.of(DispatcherType.REQUEST));
- gzipFilter.setInitParameter("methods","GET,POST,PUT,DELETE");
+ gzipFilter.setInitParameter("methods", "GET,POST,PUT,DELETE");
gzipFilter.setInitParameter("mimeTypes",
"text/html,text/plain,text/xml,text/css,application/x-javascript," +
- "application/xml,application/x-www-form-urlencoded," +
- "application/javascript,application/json");
+ "application/xml,application/x-www-form-urlencoded," +
+ "application/javascript,application/json");
gzipFilter.setInitParameter("minGzipSize", configs.getApiGzipMinSize());
}
}
@@ -681,15 +679,16 @@ public class AmbariServer {
StageUtils.setGson(injector.getInstance(Gson.class));
StageUtils.setTopologyManager(injector.getInstance(TopologyManager.class));
WorkflowJsonService.setDBProperties(
- injector.getInstance(Configuration.class));
+ injector.getInstance(Configuration.class));
SecurityFilter.init(injector.getInstance(Configuration.class));
StackDefinedPropertyProvider.init(injector);
AbstractControllerResourceProvider.init(injector.getInstance(ResourceProviderFactory.class));
BlueprintResourceProvider.init(injector.getInstance(BlueprintFactory.class),
- injector.getInstance(BlueprintDAO.class), injector.getInstance(Gson.class));
+ injector.getInstance(BlueprintDAO.class), injector.getInstance(SecurityConfigurationFactory.class), injector.getInstance(Gson.class));
StackDependencyResourceProvider.init(ambariMetaInfo);
ClusterResourceProvider.init(injector.getInstance(TopologyManager.class),
- injector.getInstance(TopologyRequestFactoryImpl.class));
+ injector.getInstance(TopologyRequestFactoryImpl.class), injector.getInstance(SecurityConfigurationFactory
+ .class), injector.getInstance(Gson.class));
HostResourceProvider.setTopologyManager(injector.getInstance(TopologyManager.class));
BlueprintFactory.init(injector.getInstance(BlueprintDAO.class));
BaseClusterRequest.init(injector.getInstance(BlueprintFactory.class));
http://git-wip-us.apache.org/repos/asf/ambari/blob/2337e539/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java
index 0426625..60217c0 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java
@@ -103,6 +103,7 @@ import org.apache.ambari.server.state.scheduler.RequestExecutionImpl;
import org.apache.ambari.server.state.stack.OsFamily;
import org.apache.ambari.server.state.svccomphost.ServiceComponentHostImpl;
import org.apache.ambari.server.topology.BlueprintFactory;
+import org.apache.ambari.server.topology.SecurityConfigurationFactory;
import org.apache.ambari.server.view.ViewInstanceHandlerList;
import org.eclipse.jetty.server.SessionIdManager;
import org.eclipse.jetty.server.SessionManager;
@@ -331,13 +332,14 @@ public class ControllerModule extends AbstractModule {
to(configuration.getExecutionCommandsCacheSize());
bind(AmbariManagementController.class).to(
- AmbariManagementControllerImpl.class);
+ AmbariManagementControllerImpl.class);
bind(AbstractRootServiceResponseFactory.class).to(RootServiceResponseFactory.class);
bind(ExecutionScheduler.class).to(ExecutionSchedulerImpl.class);
bind(DBAccessor.class).to(DBAccessorImpl.class);
bind(ViewInstanceHandlerList.class).to(AmbariHandlerList.class);
bind(TimelineMetricCacheProvider.class);
bind(TimelineMetricCacheEntryFactory.class);
+ bind(SecurityConfigurationFactory.class).in(Scopes.SINGLETON);
requestStaticInjection(ExecutionCommandWrapper.class);
requestStaticInjection(DatabaseChecker.class);
http://git-wip-us.apache.org/repos/asf/ambari/blob/2337e539/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BaseClusterRequest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BaseClusterRequest.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BaseClusterRequest.java
index 22bffe6..a67317a 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BaseClusterRequest.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BaseClusterRequest.java
@@ -18,11 +18,6 @@
package org.apache.ambari.server.controller.internal;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
import org.apache.ambari.server.api.predicate.InvalidQueryException;
import org.apache.ambari.server.api.predicate.QueryLexer;
import org.apache.ambari.server.api.predicate.Token;
@@ -34,8 +29,14 @@ import org.apache.ambari.server.topology.BlueprintFactory;
import org.apache.ambari.server.topology.Configuration;
import org.apache.ambari.server.topology.HostGroupInfo;
import org.apache.ambari.server.topology.InvalidTopologyTemplateException;
+import org.apache.ambari.server.topology.SecurityConfiguration;
import org.apache.ambari.server.topology.TopologyRequest;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
/**
* Provides common cluster request functionality.
*/
@@ -62,6 +63,11 @@ public abstract class BaseClusterRequest implements TopologyRequest {
protected Configuration configuration;
/**
+ * security configuration
+ */
+ protected SecurityConfiguration securityConfiguration;
+
+ /**
* blueprint factory
*/
protected static BlueprintFactory blueprintFactory;
@@ -162,6 +168,11 @@ public abstract class BaseClusterRequest implements TopologyRequest {
return blueprintFactory;
}
+
+ public SecurityConfiguration getSecurityConfiguration() {
+ return securityConfiguration;
+ }
+
/**
* Get the host resource provider instance.
*
http://git-wip-us.apache.org/repos/asf/ambari/blob/2337e539/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BlueprintConfigurationProcessor.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BlueprintConfigurationProcessor.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BlueprintConfigurationProcessor.java
index 18fca8a..d3d95bd 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BlueprintConfigurationProcessor.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BlueprintConfigurationProcessor.java
@@ -2201,6 +2201,11 @@ public class BlueprintConfigurationProcessor {
}
}
+
+ if(clusterTopology.isClusterKerberosEnabled()) {
+ configuration.setProperty(CLUSTER_ENV_CONFIG_TYPE_NAME, "security_enabled", "true");
+ configTypesUpdated.add(CLUSTER_ENV_CONFIG_TYPE_NAME);
+ }
}
/**
http://git-wip-us.apache.org/repos/asf/ambari/blob/2337e539/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BlueprintResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BlueprintResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BlueprintResourceProvider.java
index 6cb6a74..fa355fa 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BlueprintResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BlueprintResourceProvider.java
@@ -20,16 +20,7 @@ package org.apache.ambari.server.controller.internal;
import com.google.common.base.Preconditions;
import com.google.common.base.Strings;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
+import com.google.gson.Gson;
import org.apache.ambari.server.AmbariException;
import org.apache.ambari.server.DuplicateResourceException;
import org.apache.ambari.server.controller.AmbariManagementController;
@@ -51,11 +42,23 @@ import org.apache.ambari.server.orm.entities.HostGroupComponentEntity;
import org.apache.ambari.server.orm.entities.HostGroupEntity;
import org.apache.ambari.server.orm.entities.StackEntity;
import org.apache.ambari.server.stack.NoSuchStackException;
+import org.apache.ambari.server.state.SecurityType;
import org.apache.ambari.server.topology.Blueprint;
import org.apache.ambari.server.topology.BlueprintFactory;
import org.apache.ambari.server.topology.InvalidTopologyException;
+import org.apache.ambari.server.topology.SecurityConfiguration;
+import org.apache.ambari.server.topology.SecurityConfigurationFactory;
-import com.google.gson.Gson;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
/**
@@ -73,6 +76,11 @@ public class BlueprintResourceProvider extends AbstractControllerResourceProvide
public static final String STACK_VERSION_PROPERTY_ID =
PropertyHelper.getPropertyId("Blueprints", "stack_version");
+ public static final String BLUEPRINT_SECURITY_PROPERTY_ID =
+ PropertyHelper.getPropertyId("Blueprints", "security");
+
+ public static final String BLUEPRINTS_PROPERTY_ID = "Blueprints";
+
// Host Groups
public static final String HOST_GROUP_PROPERTY_ID = "host_groups";
public static final String HOST_GROUP_NAME_PROPERTY_ID = "name";
@@ -107,6 +115,11 @@ public class BlueprintResourceProvider extends AbstractControllerResourceProvide
private static BlueprintFactory blueprintFactory;
/**
+ * Used to create SecurityConfiguration instances
+ */
+ private static SecurityConfigurationFactory securityConfigurationFactory;
+
+ /**
* Blueprint Data Access Object
*/
private static BlueprintDAO blueprintDAO;
@@ -116,7 +129,6 @@ public class BlueprintResourceProvider extends AbstractControllerResourceProvide
*/
private static Gson jsonSerializer;
-
// ----- Constructors ----------------------------------------------------
/**
@@ -140,9 +152,11 @@ public class BlueprintResourceProvider extends AbstractControllerResourceProvide
* @param dao blueprint data access object
* @param gson json serializer
*/
- public static void init(BlueprintFactory factory, BlueprintDAO dao, Gson gson) {
+ public static void init(BlueprintFactory factory, BlueprintDAO dao, SecurityConfigurationFactory
+ securityFactory, Gson gson) {
blueprintFactory = factory;
blueprintDAO = dao;
+ securityConfigurationFactory = securityFactory;
jsonSerializer = gson;
}
@@ -242,8 +256,8 @@ public class BlueprintResourceProvider extends AbstractControllerResourceProvide
modifyResources(new Command<Void>() {
@Override
public Void invoke() throws AmbariException {
- blueprintDAO.removeByName(blueprintName);
- return null;
+ blueprintDAO.removeByName(blueprintName);
+ return null;
}
});
}
@@ -291,7 +305,16 @@ public class BlueprintResourceProvider extends AbstractControllerResourceProvide
}
setResourceProperty(resource, HOST_GROUP_PROPERTY_ID, listGroupProps, requestedIds);
setResourceProperty(resource, CONFIGURATION_PROPERTY_ID,
- populateConfigurationList(entity.getConfigurations()), requestedIds);
+ populateConfigurationList(entity.getConfigurations()), requestedIds);
+
+ if (entity.getSecurityType() != null) {
+ Map<String, String> securityConfigMap = new LinkedHashMap<>();
+ securityConfigMap.put(SecurityConfigurationFactory.TYPE_PROPERTY_ID, entity.getSecurityType().name());
+ if(entity.getSecurityType() == SecurityType.KERBEROS) {
+ securityConfigMap.put(SecurityConfigurationFactory.KERBEROS_DESCRIPTOR_REFERENCE_PROPERTY_ID, entity.getSecurityDescriptorReference());
+ }
+ setResourceProperty(resource, BLUEPRINT_SECURITY_PROPERTY_ID, securityConfigMap, requestedIds);
+ }
return resource;
}
@@ -405,9 +428,12 @@ public class BlueprintResourceProvider extends AbstractControllerResourceProvide
Preconditions.checkArgument(((Map) map).size() <= 1, CONFIGURATION_MAP_SIZE_CHECK_ERROR_MESSAGE);
}
}
+ SecurityConfiguration securityConfiguration = securityConfigurationFactory
+ .createSecurityConfigurationFromRequest((Map<String, Object>) rawBodyMap.get(BLUEPRINTS_PROPERTY_ID), true);
+
Blueprint blueprint;
try {
- blueprint = blueprintFactory.createBlueprint(properties);
+ blueprint = blueprintFactory.createBlueprint(properties, securityConfiguration);
} catch (NoSuchStackException e) {
throw new IllegalArgumentException("Specified stack doesn't exist: " + e, e);
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/2337e539/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterResourceProvider.java
index e2f132e..cd28aac 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterResourceProvider.java
@@ -17,6 +17,7 @@
*/
package org.apache.ambari.server.controller.internal;
+import com.google.gson.Gson;
import org.apache.ambari.server.AmbariException;
import org.apache.ambari.server.controller.AmbariManagementController;
import org.apache.ambari.server.controller.ClusterRequest;
@@ -25,15 +26,6 @@ import org.apache.ambari.server.controller.ConfigurationRequest;
import org.apache.ambari.server.controller.RequestStatusResponse;
import org.apache.ambari.server.controller.ServiceConfigVersionRequest;
import org.apache.ambari.server.controller.ServiceConfigVersionResponse;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
import org.apache.ambari.server.controller.spi.NoSuchParentResourceException;
import org.apache.ambari.server.controller.spi.NoSuchResourceException;
import org.apache.ambari.server.controller.spi.Predicate;
@@ -45,7 +37,21 @@ 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.ambari.server.state.SecurityType;
-import org.apache.ambari.server.topology.*;
+import org.apache.ambari.server.topology.InvalidTopologyException;
+import org.apache.ambari.server.topology.InvalidTopologyTemplateException;
+import org.apache.ambari.server.topology.SecurityConfiguration;
+import org.apache.ambari.server.topology.SecurityConfigurationFactory;
+import org.apache.ambari.server.topology.TopologyManager;
+import org.apache.ambari.server.topology.TopologyRequestFactory;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
/**
@@ -56,8 +62,8 @@ public class ClusterResourceProvider extends AbstractControllerResourceProvider
// ----- Property ID constants ---------------------------------------------
// Clusters
- public static final String CLUSTER_ID_PROPERTY_ID = PropertyHelper.getPropertyId("Clusters", "cluster_id");
- public static final String CLUSTER_NAME_PROPERTY_ID = PropertyHelper.getPropertyId("Clusters", "cluster_name");
+ public static final String CLUSTER_ID_PROPERTY_ID = PropertyHelper.getPropertyId("Clusters", "cluster_id");
+ public static final String CLUSTER_NAME_PROPERTY_ID = PropertyHelper.getPropertyId("Clusters", "cluster_name");
public static final String CLUSTER_VERSION_PROPERTY_ID = PropertyHelper.getPropertyId("Clusters", "version");
public static final String CLUSTER_PROVISIONING_STATE_PROPERTY_ID = PropertyHelper.getPropertyId("Clusters", "provisioning_state");
public static final String CLUSTER_SECURITY_TYPE_PROPERTY_ID = PropertyHelper.getPropertyId("Clusters", "security_type");
@@ -67,6 +73,8 @@ public class ClusterResourceProvider extends AbstractControllerResourceProvider
public static final String CLUSTER_HEALTH_REPORT_PROPERTY_ID = PropertyHelper.getPropertyId("Clusters", "health_report");
public static final String CLUSTER_CREDENTIAL_STORE_PROPERTIES_PROPERTY_ID = PropertyHelper.getPropertyId("Clusters", "credential_store_properties");
public static final String BLUEPRINT_PROPERTY_ID = PropertyHelper.getPropertyId(null, "blueprint");
+ public static final String SECURITY_PROPERTY_ID = PropertyHelper.getPropertyId(null, "security");
+ public static final String CREDENTIALS_PROPERTY_ID = PropertyHelper.getPropertyId(null, "credentials");
public static final String SESSION_ATTRIBUTES_PROPERTY_ID = "session_attributes";
/**
@@ -90,6 +98,11 @@ public class ClusterResourceProvider extends AbstractControllerResourceProvider
private static TopologyRequestFactory topologyRequestFactory;
/**
+ * Used to create SecurityConfiguration instances
+ */
+ private static SecurityConfigurationFactory securityConfigurationFactory;
+
+ /**
* The cluster primary key properties.
*/
private static Set<String> pkPropertyIds =
@@ -108,6 +121,11 @@ public class ClusterResourceProvider extends AbstractControllerResourceProvider
*/
private static Set<String> propertyIds = new HashSet<String>();
+ /**
+ * Used to serialize to/from json.
+ */
+ private static Gson jsonSerializer;
+
static {
propertyIds.add(CLUSTER_ID_PROPERTY_ID);
@@ -122,6 +140,8 @@ public class ClusterResourceProvider extends AbstractControllerResourceProvider
propertyIds.add(CLUSTER_CREDENTIAL_STORE_PROPERTIES_PROPERTY_ID);
propertyIds.add(BLUEPRINT_PROPERTY_ID);
propertyIds.add(SESSION_ATTRIBUTES_PROPERTY_ID);
+ propertyIds.add(SECURITY_PROPERTY_ID);
+ propertyIds.add(CREDENTIALS_PROPERTY_ID);
}
@@ -149,7 +169,7 @@ public class ClusterResourceProvider extends AbstractControllerResourceProvider
RequestStatusResponse createResponse = null;
for (final Map<String, Object> properties : request.getProperties()) {
if (isCreateFromBlueprint(properties)) {
- createResponse = processBlueprintCreate(properties);
+ createResponse = processBlueprintCreate(properties, request.getRequestInfoProperties());
} else {
createClusterResource(properties);
}
@@ -320,6 +340,7 @@ public class ClusterResourceProvider extends AbstractControllerResourceProvider
baseUnsupported.remove("host_groups");
baseUnsupported.remove("default_password");
baseUnsupported.remove("configurations");
+ baseUnsupported.remove("credentials");
return checkConfigPropertyIds(baseUnsupported, "Clusters");
}
@@ -329,14 +350,17 @@ public class ClusterResourceProvider extends AbstractControllerResourceProvider
/**
* Inject the blueprint data access object which is used to obtain blueprint entities.
- *
- * @param manager topology manager
+ * @param manager topology manager
* @param requestFactory request factory
+ * @param instance
*/
//todo: proper static injection mechanism
- public static void init(TopologyManager manager, TopologyRequestFactory requestFactory) {
+ public static void init(TopologyManager manager, TopologyRequestFactory requestFactory,
+ SecurityConfigurationFactory securityFactory, Gson instance) {
topologyManager = manager;
topologyRequestFactory = requestFactory;
+ securityConfigurationFactory = securityFactory;
+ jsonSerializer = instance;
}
@@ -451,6 +475,7 @@ public class ClusterResourceProvider extends AbstractControllerResourceProvider
*
* @param properties request body properties
*
+ * @param requestInfoProperties raw request body
* @return asynchronous response information
*
* @throws ResourceAlreadyExistsException if cluster already exists
@@ -459,25 +484,36 @@ public class ClusterResourceProvider extends AbstractControllerResourceProvider
* @throws NoSuchParentResourceException if a necessary parent resource doesn't exist
*/
@SuppressWarnings("unchecked")
- private RequestStatusResponse processBlueprintCreate(Map<String, Object> properties)
+ private RequestStatusResponse processBlueprintCreate(Map<String, Object> properties, Map<String, String> requestInfoProperties)
throws ResourceAlreadyExistsException, SystemException, UnsupportedPropertyException,
NoSuchParentResourceException {
LOG.info("Creating Cluster '" + properties.get(CLUSTER_NAME_PROPERTY_ID) +
"' based on blueprint '" + String.valueOf(properties.get(BLUEPRINT_PROPERTY_ID)) + "'.");
+ String rawRequestBody = requestInfoProperties.get(Request.REQUEST_INFO_BODY_PROPERTY);
+ Map<String, Object> rawBodyMap = jsonSerializer.<Map<String, Object>>fromJson(rawRequestBody, Map.class);
+
+ SecurityConfiguration securityConfiguration = securityConfigurationFactory.createSecurityConfigurationFromRequest
+ (rawBodyMap, false);
ProvisionClusterRequest createClusterRequest;
try {
- createClusterRequest = topologyRequestFactory.createProvisionClusterRequest(properties);
+ createClusterRequest = topologyRequestFactory.createProvisionClusterRequest(properties, securityConfiguration);
} catch (InvalidTopologyTemplateException e) {
throw new IllegalArgumentException("Invalid Cluster Creation Template: " + e, e);
}
+ if (securityConfiguration != null && securityConfiguration.getType() == SecurityType.NONE &&
+ createClusterRequest.getBlueprint().getSecurity() != null && createClusterRequest.getBlueprint().getSecurity()
+ .getType() == SecurityType.KERBEROS) {
+ throw new IllegalArgumentException("Setting security to NONE is not allowed as security type in blueprint is set to KERBEROS!");
+ }
+
try {
return topologyManager.provisionCluster(createClusterRequest);
} catch (InvalidTopologyException e) {
throw new IllegalArgumentException("Topology validation failed: " + e, e);
- } catch (AmbariException e) {
+ } catch (AmbariException e) {
e.printStackTrace();
throw new SystemException("Unknown exception when asking TopologyManager to provision cluster", e);
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/2337e539/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ExportBlueprintRequest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ExportBlueprintRequest.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ExportBlueprintRequest.java
index c80ae2c..8c8b89d 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ExportBlueprintRequest.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ExportBlueprintRequest.java
@@ -133,7 +133,7 @@ public class ExportBlueprintRequest implements TopologyRequest {
hostGroups.add(new HostGroupImpl(exportedHostGroup.getName(), bpName, stack, exportedHostGroup.getComponents(),
exportedHostGroup.getConfiguration(), String.valueOf(exportedHostGroup.getCardinality())));
}
- blueprint = new BlueprintImpl(bpName, hostGroups, stack, configuration);
+ blueprint = new BlueprintImpl(bpName, hostGroups, stack, configuration, null);
}
private void createHostGroupInfo(Collection<ExportedHostGroup> exportedHostGroups) {
http://git-wip-us.apache.org/repos/asf/ambari/blob/2337e539/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/KerberosDescriptorResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/KerberosDescriptorResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/KerberosDescriptorResourceProvider.java
index cc02119..3cece5d 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/KerberosDescriptorResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/KerberosDescriptorResourceProvider.java
@@ -70,6 +70,12 @@ public class KerberosDescriptorResourceProvider extends AbstractControllerResour
}
@Override
+ public Set<String> checkPropertyIds(Set<String> propertyIds) {
+ LOGGER.debug("Skipping property id validation for kerberos descriptor resources");
+ return Collections.emptySet();
+ }
+
+ @Override
public RequestStatus createResources(Request request) throws SystemException, UnsupportedPropertyException,
ResourceAlreadyExistsException, NoSuchParentResourceException {
http://git-wip-us.apache.org/repos/asf/ambari/blob/2337e539/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ProvisionClusterRequest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ProvisionClusterRequest.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ProvisionClusterRequest.java
index 4a906b1..9716abe 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ProvisionClusterRequest.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ProvisionClusterRequest.java
@@ -17,22 +17,29 @@
*/
package org.apache.ambari.server.controller.internal;
+import com.google.common.base.Enums;
+import com.google.common.base.Strings;
import org.apache.ambari.server.api.predicate.InvalidQueryException;
+import org.apache.ambari.server.security.encryption.CredentialStoreType;
import org.apache.ambari.server.stack.NoSuchStackException;
import org.apache.ambari.server.topology.Configuration;
import org.apache.ambari.server.topology.ConfigurationFactory;
+import org.apache.ambari.server.topology.Credential;
import org.apache.ambari.server.topology.HostGroupInfo;
import org.apache.ambari.server.topology.InvalidTopologyTemplateException;
import org.apache.ambari.server.topology.NoSuchBlueprintException;
import org.apache.ambari.server.topology.RequiredPasswordValidator;
+import org.apache.ambari.server.topology.SecurityConfiguration;
import org.apache.ambari.server.topology.TopologyValidator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Collection;
import java.util.Collections;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Set;
/**
* Request for provisioning a cluster.
@@ -94,14 +101,18 @@ public class ProvisionClusterRequest extends BaseClusterRequest {
*/
private String defaultPassword;
+ private Map<String, Credential> credentialsMap;
+
private final static Logger LOG = LoggerFactory.getLogger(ProvisionClusterRequest.class);
/**
* Constructor.
*
* @param properties request properties
+ * @param securityConfiguration security config related properties
*/
- public ProvisionClusterRequest(Map<String, Object> properties) throws InvalidTopologyTemplateException {
+ public ProvisionClusterRequest(Map<String, Object> properties, SecurityConfiguration securityConfiguration) throws
+ InvalidTopologyTemplateException {
setClusterName(String.valueOf(properties.get(
ClusterResourceProvider.CLUSTER_NAME_PROPERTY_ID)));
@@ -117,12 +128,52 @@ public class ProvisionClusterRequest extends BaseClusterRequest {
throw new InvalidTopologyTemplateException("The specified blueprint doesn't exist: " + e, e);
}
+ this.securityConfiguration = securityConfiguration;
+
Configuration configuration = configurationFactory.getConfiguration(
(Collection<Map<String, String>>) properties.get(CONFIGURATIONS_PROPERTY));
configuration.setParentConfiguration(blueprint.getConfiguration());
setConfiguration(configuration);
parseHostGroupInfo(properties);
+
+ this.credentialsMap = parseCredentials(properties);
+ }
+
+ private Map<String, Credential> parseCredentials(Map<String, Object> properties) throws
+ InvalidTopologyTemplateException {
+ HashMap<String, Credential> credentialHashMap = new HashMap<>();
+ Set<Map<String, String>> credentialsSet = (Set<Map<String, String>>) properties.get(ClusterResourceProvider.CREDENTIALS_PROPERTY_ID);
+ if (credentialsSet != null) {
+ for (Map<String, String> credentialMap : credentialsSet) {
+ String alias = Strings.emptyToNull(credentialMap.get("alias"));
+ if (alias == null) {
+ throw new InvalidTopologyTemplateException("credential.alias property is missing.");
+ }
+ String principal = Strings.emptyToNull(credentialMap.get("principal"));
+ if (principal == null) {
+ throw new InvalidTopologyTemplateException("credential.principal property is missing.");
+ }
+ String key = Strings.emptyToNull(credentialMap.get("key"));
+ if (key == null) {
+ throw new InvalidTopologyTemplateException("credential.key is missing.");
+ }
+ String typeString = Strings.emptyToNull(credentialMap.get("type"));
+ if (typeString == null) {
+ throw new InvalidTopologyTemplateException("credential.type is missing.");
+ }
+ CredentialStoreType type = Enums.getIfPresent(CredentialStoreType.class, typeString.toUpperCase()).orNull();
+ if (type == null) {
+ throw new InvalidTopologyTemplateException("credential.type is invalid.");
+ }
+ credentialHashMap.put(alias, new Credential(alias, principal, key, type));
+ }
+ }
+ return credentialHashMap;
+ }
+
+ public Map<String, Credential> getCredentialsMap() {
+ return credentialsMap;
}
public String getClusterName() {
http://git-wip-us.apache.org/repos/asf/ambari/blob/2337e539/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/BlueprintEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/BlueprintEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/BlueprintEntity.java
index ada924a..8578d6b 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/BlueprintEntity.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/BlueprintEntity.java
@@ -18,21 +18,21 @@
package org.apache.ambari.server.orm.entities;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-import com.google.gson.Gson;
+import org.apache.ambari.server.state.SecurityType;
+import javax.persistence.Basic;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;
-import javax.persistence.Transient;
+import java.util.Collection;
/**
@@ -49,6 +49,14 @@ public class BlueprintEntity {
updatable = false, unique = true, length = 100)
private String blueprintName;
+ @Basic
+ @Enumerated(value = EnumType.STRING)
+ @Column(name = "security_type", nullable = false, insertable = true, updatable = true)
+ private SecurityType securityType = SecurityType.NONE;
+
+ @Basic
+ @Column(name = "security_descriptor_reference", nullable = true, insertable = true, updatable = true)
+ private String securityDescriptorReference;
/**
* Unidirectional one-to-one association to {@link StackEntity}
@@ -136,4 +144,20 @@ public class BlueprintEntity {
public void setConfigurations(Collection<BlueprintConfigEntity> configurations) {
this.configurations = configurations;
}
+
+ public SecurityType getSecurityType() {
+ return securityType;
+ }
+
+ public void setSecurityType(SecurityType securityType) {
+ this.securityType = securityType;
+ }
+
+ public String getSecurityDescriptorReference() {
+ return securityDescriptorReference;
+ }
+
+ public void setSecurityDescriptorReference(String securityDescriptorReference) {
+ this.securityDescriptorReference = securityDescriptorReference;
+ }
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/2337e539/ambari-server/src/main/java/org/apache/ambari/server/state/Clusters.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/Clusters.java b/ambari-server/src/main/java/org/apache/ambari/server/state/Clusters.java
index 3aa27dd..a1ebaba 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/Clusters.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/Clusters.java
@@ -18,12 +18,12 @@
package org.apache.ambari.server.state;
+import org.apache.ambari.server.AmbariException;
+
import java.util.List;
import java.util.Map;
import java.util.Set;
-import org.apache.ambari.server.AmbariException;
-
/**
* Single entity that tracks all clusters and hosts that are managed
* by the Ambari server
@@ -32,7 +32,6 @@ public interface Clusters {
/**
* Add a new Cluster
- *
* @param clusterName
* the cluster name (not {@code null}).
* @param stackId
@@ -42,6 +41,19 @@ public interface Clusters {
throws AmbariException;
/**
+ * Add a new cluster
+ * @param clusterName
+ * the cluster name (not {@code null}).
+ * @param stackId
+ * the stack for the cluster (not {@code null}).
+ * @param securityType
+ * the cluster will be created with this security type.
+ * @throws AmbariException
+ */
+ public void addCluster(String clusterName, StackId stackId, SecurityType securityType)
+ throws AmbariException;
+
+ /**
* Gets the Cluster given the cluster name
* @param clusterName Name of the Cluster to retrieve
* @return <code>Cluster</code> identified by the given name
http://git-wip-us.apache.org/repos/asf/ambari/blob/2337e539/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClustersImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClustersImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClustersImpl.java
index 4040c5f..a89fb91 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClustersImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClustersImpl.java
@@ -18,20 +18,9 @@
package org.apache.ambari.server.state.cluster;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
-
-import javax.persistence.RollbackException;
-
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+import com.google.inject.persist.Transactional;
import org.apache.ambari.server.AmbariException;
import org.apache.ambari.server.ClusterNotFoundException;
import org.apache.ambari.server.DuplicateResourceException;
@@ -73,6 +62,7 @@ import org.apache.ambari.server.state.HostHealthStatus;
import org.apache.ambari.server.state.HostHealthStatus.HealthStatus;
import org.apache.ambari.server.state.HostState;
import org.apache.ambari.server.state.RepositoryInfo;
+import org.apache.ambari.server.state.SecurityType;
import org.apache.ambari.server.state.StackId;
import org.apache.ambari.server.state.configgroup.ConfigGroup;
import org.apache.ambari.server.state.host.HostFactory;
@@ -80,9 +70,18 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.core.GrantedAuthority;
-import com.google.inject.Inject;
-import com.google.inject.Singleton;
-import com.google.inject.persist.Transactional;
+import javax.persistence.RollbackException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
@Singleton
public class ClustersImpl implements Clusters {
@@ -199,6 +198,12 @@ public class ClustersImpl implements Clusters {
@Override
public void addCluster(String clusterName, StackId stackId)
+ throws AmbariException {
+ addCluster(clusterName, stackId, null);
+ }
+
+ @Override
+ public void addCluster(String clusterName, StackId stackId, SecurityType securityType)
throws AmbariException {
checkLoaded();
@@ -232,6 +237,9 @@ public class ClustersImpl implements Clusters {
clusterEntity.setClusterName(clusterName);
clusterEntity.setDesiredStack(stackEntity);
clusterEntity.setResource(resourceEntity);
+ if (securityType != null) {
+ clusterEntity.setSecurityType(securityType);
+ }
try {
clusterDAO.create(clusterEntity);
http://git-wip-us.apache.org/repos/asf/ambari/blob/2337e539/ambari-server/src/main/java/org/apache/ambari/server/topology/AmbariContext.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/topology/AmbariContext.java b/ambari-server/src/main/java/org/apache/ambari/server/topology/AmbariContext.java
index 0cf3bf2..5e93aeb 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/topology/AmbariContext.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/topology/AmbariContext.java
@@ -18,15 +18,6 @@
package org.apache.ambari.server.topology;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.atomic.AtomicLong;
-
import org.apache.ambari.server.AmbariException;
import org.apache.ambari.server.ClusterNotFoundException;
import org.apache.ambari.server.Role;
@@ -68,6 +59,15 @@ import org.apache.ambari.server.state.configgroup.ConfigGroup;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicLong;
+
/**
* Provides topology related information as well as access to the core Ambari functionality.
*/
@@ -136,15 +136,15 @@ public class AmbariContext {
return getController().getActionManager().getTaskById(id);
}
- public void createAmbariResources(ClusterTopology topology, String clusterName) {
+ public void createAmbariResources(ClusterTopology topology, String clusterName, SecurityType securityType) {
Stack stack = topology.getBlueprint().getStack();
- createAmbariClusterResource(clusterName, stack.getName(), stack.getVersion());
+ createAmbariClusterResource(clusterName, stack.getName(), stack.getVersion(), securityType);
createAmbariServiceAndComponentResources(topology, clusterName);
}
- public void createAmbariClusterResource(String clusterName, String stackName, String stackVersion) {
+ public void createAmbariClusterResource(String clusterName, String stackName, String stackVersion, SecurityType securityType) {
String stackInfo = String.format("%s-%s", stackName, stackVersion);
- ClusterRequest clusterRequest = new ClusterRequest(null, clusterName, stackInfo, null);
+ ClusterRequest clusterRequest = new ClusterRequest(null, clusterName, null, securityType, stackInfo, null);
try {
getController().createCluster(clusterRequest);
} catch (AmbariException e) {
http://git-wip-us.apache.org/repos/asf/ambari/blob/2337e539/ambari-server/src/main/java/org/apache/ambari/server/topology/Blueprint.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/topology/Blueprint.java b/ambari-server/src/main/java/org/apache/ambari/server/topology/Blueprint.java
index fa65022..11311db 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/topology/Blueprint.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/topology/Blueprint.java
@@ -103,6 +103,8 @@ public interface Blueprint {
*/
public Collection<HostGroup> getHostGroupsForComponent(String component);
+ public SecurityConfiguration getSecurity();
+
/**
* Validate the blueprint topology.
*
http://git-wip-us.apache.org/repos/asf/ambari/blob/2337e539/ambari-server/src/main/java/org/apache/ambari/server/topology/BlueprintFactory.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/topology/BlueprintFactory.java b/ambari-server/src/main/java/org/apache/ambari/server/topology/BlueprintFactory.java
index 210504d..b8ce749 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/topology/BlueprintFactory.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/topology/BlueprintFactory.java
@@ -22,7 +22,6 @@ package org.apache.ambari.server.topology;
import com.google.inject.Inject;
import org.apache.ambari.server.AmbariException;
import org.apache.ambari.server.ObjectNotFoundException;
-import org.apache.ambari.server.StackAccessException;
import org.apache.ambari.server.controller.AmbariManagementController;
import org.apache.ambari.server.controller.AmbariServer;
import org.apache.ambari.server.controller.internal.Stack;
@@ -88,10 +87,11 @@ public class BlueprintFactory {
* Convert a map of properties to a blueprint entity.
*
* @param properties property map
+ * @param securityConfiguration security related properties
* @return new blueprint entity
*/
@SuppressWarnings("unchecked")
- public Blueprint createBlueprint(Map<String, Object> properties) throws NoSuchStackException {
+ public Blueprint createBlueprint(Map<String, Object> properties, SecurityConfiguration securityConfiguration) throws NoSuchStackException {
String name = String.valueOf(properties.get(BLUEPRINT_NAME_PROPERTY_ID));
// String.valueOf() will return "null" if value is null
if (name.equals("null") || name.isEmpty()) {
@@ -104,7 +104,7 @@ public class BlueprintFactory {
Configuration configuration = configFactory.getConfiguration((Collection<Map<String, String>>)
properties.get(CONFIGURATION_PROPERTY_ID));
- return new BlueprintImpl(name, hostGroups, stack, configuration);
+ return new BlueprintImpl(name, hostGroups, stack, configuration, securityConfiguration);
}
protected Stack createStack(Map<String, Object> properties) throws NoSuchStackException {
http://git-wip-us.apache.org/repos/asf/ambari/blob/2337e539/ambari-server/src/main/java/org/apache/ambari/server/topology/BlueprintImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/topology/BlueprintImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/topology/BlueprintImpl.java
index 481d217..88052b0 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/topology/BlueprintImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/topology/BlueprintImpl.java
@@ -19,12 +19,6 @@
package org.apache.ambari.server.topology;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-
import com.google.gson.Gson;
import org.apache.ambari.server.AmbariException;
import org.apache.ambari.server.StackAccessException;
@@ -39,6 +33,12 @@ import org.apache.ambari.server.orm.entities.HostGroupEntity;
import org.apache.ambari.server.orm.entities.StackEntity;
import org.apache.ambari.server.stack.NoSuchStackException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+
/**
* Blueprint implementation.
*/
@@ -49,10 +49,14 @@ public class BlueprintImpl implements Blueprint {
private Stack stack;
private Configuration configuration;
private BlueprintValidator validator;
-
+ private SecurityConfiguration security;
public BlueprintImpl(BlueprintEntity entity) throws NoSuchStackException {
this.name = entity.getBlueprintName();
+ if (entity.getSecurityType() != null) {
+ this.security = new SecurityConfiguration(entity.getSecurityType(), entity.getSecurityDescriptorReference(),
+ null);
+ }
parseStack(entity.getStack());
@@ -63,9 +67,10 @@ public class BlueprintImpl implements Blueprint {
validator = new BlueprintValidatorImpl(this);
}
- public BlueprintImpl(String name, Collection<HostGroup> groups, Stack stack, Configuration configuration) {
+ public BlueprintImpl(String name, Collection<HostGroup> groups, Stack stack, Configuration configuration, SecurityConfiguration security) {
this.name = name;
this.stack = stack;
+ this.security = security;
// caller should set host group configs
for (HostGroup hostGroup : groups) {
@@ -91,6 +96,10 @@ public class BlueprintImpl implements Blueprint {
return stack.getVersion();
}
+ public SecurityConfiguration getSecurity() {
+ return security;
+ }
+
//todo: safe copy?
@Override
public Map<String, HostGroup> getHostGroups() {
@@ -182,6 +191,14 @@ public class BlueprintImpl implements Blueprint {
BlueprintEntity entity = new BlueprintEntity();
entity.setBlueprintName(name);
+ if (security != null) {
+ if (security.getType() != null) {
+ entity.setSecurityType(security.getType());
+ }
+ if (security.getDescriptorReference() != null) {
+ entity.setSecurityDescriptorReference(security.getDescriptorReference());
+ }
+ }
//todo: not using stackDAO so stackEntity.id is not set
//todo: this is now being set in BlueprintDAO
http://git-wip-us.apache.org/repos/asf/ambari/blob/2337e539/ambari-server/src/main/java/org/apache/ambari/server/topology/Credential.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/topology/Credential.java b/ambari-server/src/main/java/org/apache/ambari/server/topology/Credential.java
new file mode 100644
index 0000000..2651074
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/topology/Credential.java
@@ -0,0 +1,71 @@
+/**
+ * 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 distribut
+ * ed 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.topology;
+
+import org.apache.ambari.server.security.encryption.CredentialStoreType;
+
+/**
+ * Holds credential info submitted in a cluster create template.
+ */
+public class Credential {
+
+ /**
+ * Credential alias like kdc.admin.credential.
+ */
+ private String alias;
+
+ /**
+ * Name of a principal.
+ */
+ private String principal;
+
+ /**
+ * Key of credential.
+ */
+ private String key;
+
+ /**
+ * Type of credential store.
+ */
+ private CredentialStoreType type;
+
+ public Credential(String alias, String principal, String key, CredentialStoreType type) {
+ this.alias = alias;
+ this.principal = principal;
+ this.key = key;
+ this.type = type;
+ }
+
+ public String getAlias() {
+ return alias;
+ }
+
+ public String getPrincipal() {
+ return principal;
+ }
+
+ public String getKey() {
+ return key;
+ }
+
+ public CredentialStoreType getType() {
+ return type;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/2337e539/ambari-server/src/main/java/org/apache/ambari/server/topology/SecurityConfiguration.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/topology/SecurityConfiguration.java b/ambari-server/src/main/java/org/apache/ambari/server/topology/SecurityConfiguration.java
new file mode 100644
index 0000000..b35f7b3
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/topology/SecurityConfiguration.java
@@ -0,0 +1,67 @@
+/**
+ * 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 distribut
+ * ed 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.topology;
+
+import org.apache.ambari.server.state.SecurityType;
+
+/**
+ * Holds security related properties, the securityType and security descriptor (in case of KERBEROS
+ * kerberos_descriptor) either contains the whole descriptor or just the reference to it.
+ *
+ */
+public class SecurityConfiguration {
+
+ /**
+ * Security Type
+ */
+ private SecurityType type;
+
+ /**
+ * Holds a reference to a kerberos_descriptor resource.
+ */
+ private String descriptorReference;
+
+ /**
+ * Content of a kerberos_descriptor as String.
+ */
+ private String descriptor;
+
+ public SecurityConfiguration(SecurityType type) {
+ this.type = type;
+ }
+
+ public SecurityConfiguration(SecurityType type, String descriptorReference, String descriptor) {
+ this.type = type;
+ this.descriptorReference = descriptorReference;
+ this.descriptor = descriptor;
+ }
+
+ public SecurityType getType() {
+ return type;
+ }
+
+ public String getDescriptor() {
+ return descriptor;
+ }
+
+ public String getDescriptorReference() {
+ return descriptorReference;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/2337e539/ambari-server/src/main/java/org/apache/ambari/server/topology/SecurityConfigurationFactory.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/topology/SecurityConfigurationFactory.java b/ambari-server/src/main/java/org/apache/ambari/server/topology/SecurityConfigurationFactory.java
new file mode 100644
index 0000000..5f8cde1
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/topology/SecurityConfigurationFactory.java
@@ -0,0 +1,175 @@
+/**
+ * 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 distribut
+ * ed 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.topology;
+
+import com.google.common.base.Enums;
+import com.google.common.base.Strings;
+import com.google.gson.Gson;
+import com.google.inject.Inject;
+import org.apache.ambari.server.orm.dao.KerberosDescriptorDAO;
+import org.apache.ambari.server.orm.entities.KerberosDescriptorEntity;
+import org.apache.ambari.server.state.SecurityType;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Map;
+import java.util.UUID;
+
+public class SecurityConfigurationFactory {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(SecurityConfigurationFactory.class);
+
+ public static final String SECURITY_PROPERTY_ID = "security";
+ public static final String TYPE_PROPERTY_ID = "type";
+ public static final String KERBEROS_DESCRIPTOR_PROPERTY_ID = "kerberos_descriptor";
+ public static final String KERBEROS_DESCRIPTOR_REFERENCE_PROPERTY_ID = "kerberos_descriptor_reference";
+
+ @Inject
+ protected Gson jsonSerializer;
+
+ @Inject
+ private KerberosDescriptorDAO kerberosDescriptorDAO;
+
+ @Inject
+ private KerberosDescriptorFactory kerberosDescriptorFactory;
+
+ public SecurityConfigurationFactory() {
+ }
+
+ protected SecurityConfigurationFactory(Gson jsonSerializer, KerberosDescriptorDAO kerberosDescriptorDAO, KerberosDescriptorFactory kerberosDescriptorFactory) {
+ this.jsonSerializer = jsonSerializer;
+ this.kerberosDescriptorDAO = kerberosDescriptorDAO;
+ this.kerberosDescriptorFactory = kerberosDescriptorFactory;
+ }
+
+ /**
+ * Creates and also validates SecurityConfiguration based on properties parsed from request Json.
+ *
+ * @param properties Security properties from Json parsed into a Map
+ * @param persistEmbeddedDescriptor whether to save embedded descriptor or not
+ * @return
+ */
+ public SecurityConfiguration createSecurityConfigurationFromRequest(Map<String, Object> properties, boolean
+ persistEmbeddedDescriptor) {
+
+ SecurityConfiguration securityConfiguration = null;
+
+ LOGGER.debug("Creating security configuration from properties: {}", properties);
+ Map<String, Object> securityProperties = (Map<String, Object>) properties.get(SECURITY_PROPERTY_ID);
+
+ if (securityProperties == null) {
+ LOGGER.debug("No security information properties provided, returning null");
+ return securityConfiguration;
+ }
+
+ String securityTypeString = Strings.emptyToNull((String) securityProperties.get(TYPE_PROPERTY_ID));
+ if (securityTypeString == null) {
+ LOGGER.error("Type is missing from security block.");
+ throw new IllegalArgumentException("Type missing from security block.");
+ }
+
+ SecurityType securityType = Enums.getIfPresent(SecurityType.class, securityTypeString).orNull();
+ if (securityType == null) {
+ LOGGER.error("Unsupported security type specified: {}", securityType);
+ throw new IllegalArgumentException("Invalid security type specified: " + securityTypeString);
+ }
+
+ if (securityType == SecurityType.KERBEROS) {
+
+ // get security information from the request propertie if any
+ String descriptorReference = Strings.emptyToNull((String)
+ securityProperties.get(KERBEROS_DESCRIPTOR_REFERENCE_PROPERTY_ID));
+
+ Object descriptorJsonMap = securityProperties.get(KERBEROS_DESCRIPTOR_PROPERTY_ID);
+
+ if (descriptorReference == null && descriptorJsonMap == null) {
+ LOGGER.error("Both kerberos descriptor and kerberos descriptor reference are null in the security configuration!");
+ throw new IllegalArgumentException(KERBEROS_DESCRIPTOR_PROPERTY_ID + " or "
+ + KERBEROS_DESCRIPTOR_REFERENCE_PROPERTY_ID + " is required for KERBEROS security setup.");
+ }
+
+ if (descriptorReference != null && descriptorJsonMap != null) {
+ LOGGER.error("Both kerberos descriptor and kerberos descriptor reference are set in the security configuration!");
+ throw new IllegalArgumentException("Usage of properties : " + KERBEROS_DESCRIPTOR_PROPERTY_ID + " and "
+ + KERBEROS_DESCRIPTOR_REFERENCE_PROPERTY_ID + " at the same time, is not allowed.");
+ }
+
+ String descriptorText = null;
+
+ if (descriptorJsonMap != null) { // this means the reference is null
+ LOGGER.debug("Found embedded descriptor: {}", descriptorJsonMap);
+ descriptorText = jsonSerializer.<Map<String, Object>>toJson(descriptorJsonMap, Map.class);
+ if (persistEmbeddedDescriptor) {
+ descriptorReference = persistKerberosDescriptor(descriptorText);
+ }
+ securityConfiguration = new SecurityConfiguration(SecurityType.KERBEROS, descriptorReference, descriptorText);
+ } else { // this means the reference is not null
+ LOGGER.debug("Found descriptor reference: {}", descriptorReference);
+ securityConfiguration = loadSecurityConfigurationByReference(descriptorReference);
+ }
+ } else {
+ LOGGER.debug("There is no security configuration found in the request");
+ securityConfiguration = new SecurityConfiguration(SecurityType.NONE);
+ }
+ return securityConfiguration;
+ }
+
+ public SecurityConfiguration loadSecurityConfigurationByReference(String reference) {
+ SecurityConfiguration securityConfiguration = null;
+ LOGGER.debug("Loading security configuration by reference: {}", reference);
+
+ if (reference == null) {
+ LOGGER.error("No security configuration reference provided!");
+ throw new IllegalArgumentException("No security configuration reference provided!");
+ }
+
+ KerberosDescriptorEntity descriptorEntity = kerberosDescriptorDAO.findByName(reference);
+
+ if (descriptorEntity == null) {
+ LOGGER.error("No security configuration found for the reference: {}", reference);
+ throw new IllegalArgumentException("No security configuration found for the reference: " + reference);
+ }
+
+ securityConfiguration = new SecurityConfiguration(SecurityType.KERBEROS, reference, descriptorEntity.getKerberosDescriptorText());
+
+ return securityConfiguration;
+
+ }
+
+ private String persistKerberosDescriptor(String descriptor) {
+ LOGGER.debug("Generating new kerberos descriptor reference ...");
+ String kdReference = generateKerberosDescriptorReference();
+
+ KerberosDescriptor kerberosDescriptor = kerberosDescriptorFactory.createKerberosDescriptor(kdReference, descriptor);
+
+ LOGGER.debug("Persisting kerberos descriptor ...");
+ kerberosDescriptorDAO.create(kerberosDescriptor.toEntity());
+ return kdReference;
+ }
+
+ // generates a unique name for the kerberos descriptor for further reference
+ private String generateKerberosDescriptorReference() {
+ String kdReference = UUID.randomUUID().toString();
+ LOGGER.debug("Generated new kerberos descriptor reference: {}", kdReference);
+ return kdReference;
+ }
+
+
+}