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 <rnettle...@hortonworks.com>
Authored: Wed Oct 28 17:57:30 2015 -0400
Committer: Bob Nettleton <rnettle...@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;
+  }
+
+
+}

Reply via email to