http://git-wip-us.apache.org/repos/asf/ambari/blob/4bce5782/ambari-server/src/main/java/org/apache/ambari/server/controller/KerberosHelperImpl.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/KerberosHelperImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/KerberosHelperImpl.java index 8d0fd0f..d86433f 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/controller/KerberosHelperImpl.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/KerberosHelperImpl.java @@ -24,6 +24,7 @@ import java.io.File; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Date; @@ -35,6 +36,7 @@ import java.util.List; import java.util.Map; import java.util.Set; import java.util.TreeMap; +import java.util.TreeSet; import java.util.regex.Matcher; import org.apache.ambari.annotations.Experimental; @@ -48,6 +50,7 @@ import org.apache.ambari.server.actionmanager.RequestFactory; import org.apache.ambari.server.actionmanager.Stage; import org.apache.ambari.server.actionmanager.StageFactory; import org.apache.ambari.server.api.services.AmbariMetaInfo; +import org.apache.ambari.server.api.services.stackadvisor.StackAdvisorException; import org.apache.ambari.server.api.services.stackadvisor.StackAdvisorHelper; import org.apache.ambari.server.api.services.stackadvisor.StackAdvisorRequest; import org.apache.ambari.server.api.services.stackadvisor.recommendations.RecommendationResponse; @@ -92,14 +95,17 @@ import org.apache.ambari.server.stageplanner.RoleGraph; import org.apache.ambari.server.stageplanner.RoleGraphFactory; import org.apache.ambari.server.state.Cluster; import org.apache.ambari.server.state.Clusters; +import org.apache.ambari.server.state.ComponentInfo; import org.apache.ambari.server.state.Config; import org.apache.ambari.server.state.ConfigHelper; import org.apache.ambari.server.state.Host; import org.apache.ambari.server.state.HostState; +import org.apache.ambari.server.state.PropertyInfo; import org.apache.ambari.server.state.SecurityType; import org.apache.ambari.server.state.Service; import org.apache.ambari.server.state.ServiceComponent; import org.apache.ambari.server.state.ServiceComponentHost; +import org.apache.ambari.server.state.ServiceInfo; import org.apache.ambari.server.state.StackId; import org.apache.ambari.server.state.State; import org.apache.ambari.server.state.ValueAttributesInfo; @@ -359,16 +365,16 @@ public class KerberosHelperImpl implements KerberosHelper { RoleCommandOrder roleCommandOrder = ambariManagementController.getRoleCommandOrder(cluster); DeleteIdentityHandler handler = new DeleteIdentityHandler(customCommandExecutionHelper, configuration.getDefaultServerTaskTimeout(), stageFactory, ambariManagementController); DeleteIdentityHandler.CommandParams commandParameters = new DeleteIdentityHandler.CommandParams( - components, - identities, - ambariManagementController.getAuthName(), - dataDirectory, - kerberosDetails.getDefaultRealm(), - kerberosDetails.getKdcType()); + components, + identities, + ambariManagementController.getAuthName(), + dataDirectory, + kerberosDetails.getDefaultRealm(), + kerberosDetails.getKdcType()); OrderedRequestStageContainer stageContainer = new OrderedRequestStageContainer( - roleGraphFactory, - roleCommandOrder, - new RequestStageContainer(actionManager.getNextRequestId(), null, requestFactory, actionManager)); + roleGraphFactory, + roleCommandOrder, + new RequestStageContainer(actionManager.getNextRequestId(), null, requestFactory, actionManager)); handler.addDeleteIdentityStages(cluster, stageContainer, commandParameters, kerberosDetails.manageIdentities()); stageContainer.getRequestStageContainer().persist(); } @@ -376,45 +382,43 @@ public class KerberosHelperImpl implements KerberosHelper { @Override public void configureServices(Cluster cluster, Map<String, Collection<String>> serviceFilter) throws AmbariException, KerberosInvalidConfigurationException { - Map<String, Map<String, String>> existingConfigurations = calculateExistingConfigurations(cluster, null); - Map<String, Set<String>> installedServices = new HashMap<>(); - Set<String> previouslyExistingServices = new HashSet<>(); - - // Calculate the map of installed services to installed components - Map<String, Service> clusterServices = cluster.getServices(); - if(clusterServices != null) { - for (Service clusterService : clusterServices.values()) { - Set<String> installedComponents = installedServices.get(clusterService.getName()); - if (installedComponents == null) { - installedComponents = new HashSet<>(); - installedServices.put(clusterService.getName(), installedComponents); - } + final Map<String, Set<String>> installedServices = new HashMap<>(); + final Set<String> previouslyExistingServices = new HashSet<>(); + + // Calculate the map of installed services to installed components. + // We can create the map in the "shouldIncludeCommand" Command to avoid having to iterate + // over the returned ServiceComponentHost List. + getServiceComponentHosts(cluster, + new Command<Boolean, ServiceComponentHost>() { + @Override + public Boolean invoke(ServiceComponentHost sch) throws AmbariException { + if (sch != null) { + String serviceName = sch.getServiceName(); + + Set<String> installedComponents = installedServices.get(serviceName); + if (installedComponents == null) { + installedComponents = new HashSet<>(); + installedServices.put(serviceName, installedComponents); + } + installedComponents.add(sch.getServiceComponentName()); - Map<String, ServiceComponent> clusterServiceComponents = clusterService.getServiceComponents(); - if (clusterServiceComponents != null) { - for (ServiceComponent clusterServiceComponent : clusterServiceComponents.values()) { - installedComponents.add(clusterServiceComponent.getName()); - - // Determine if this component was PREVIOUSLY installed, which implies that its containing service was PREVIOUSLY installed - if (!previouslyExistingServices.contains(clusterService.getName())) { - Map<String, ServiceComponentHost> clusterServiceComponentHosts = clusterServiceComponent.getServiceComponentHosts(); - if (clusterServiceComponentHosts != null) { - for (ServiceComponentHost clusterServiceComponentHost : clusterServiceComponentHosts.values()) { - if (PREVIOUSLY_INSTALLED_STATES.contains(clusterServiceComponentHost.getState())) { - previouslyExistingServices.add(clusterService.getName()); - break; - } - } + // Determine if this component was PREVIOUSLY installed, which implies that its containing service was PREVIOUSLY installed + if (!previouslyExistingServices.contains(serviceName) && PREVIOUSLY_INSTALLED_STATES.contains(sch.getState())) { + previouslyExistingServices.add(serviceName); } + + return true; } + + return false; } - } - } - } + }); + Map<String, Map<String, String>> existingConfigurations = calculateExistingConfigurations(cluster, null); Map<String, Map<String, String>> updates = getServiceConfigurationUpdates(cluster, existingConfigurations, installedServices, serviceFilter, previouslyExistingServices, true, true); + // Store the updates... for (Map.Entry<String, Map<String, String>> entry : updates.entrySet()) { configHelper.updateConfigType(cluster, cluster.getDesiredStackVersion(), ambariManagementController, entry.getKey(), entry.getValue(), null, @@ -434,7 +438,7 @@ public class KerberosHelperImpl implements KerberosHelper { Map<String, Map<String, String>> kerberosConfigurations = new HashMap<>(); KerberosDetails kerberosDetails = getKerberosDetails(cluster, null); - KerberosDescriptor kerberosDescriptor = getKerberosDescriptor(cluster); + KerberosDescriptor kerberosDescriptor = getKerberosDescriptor(cluster, false); Map<String, String> kerberosDescriptorProperties = kerberosDescriptor.getProperties(); Map<String, Map<String, String>> configurations = addAdditionalConfigurations(cluster, @@ -442,10 +446,10 @@ public class KerberosHelperImpl implements KerberosHelper { Map<String, Set<String>> propertiesToIgnore = new HashMap<>(); - // If Ambari is managing it own identities then add AMBARI to the set of installed servcie so + // If Ambari is managing it own identities then add AMBARI to the set of installed service so // that its Kerberos descriptor entries will be included. - if (createAmbariIdentities(existingConfigurations.get("kerberos-env"))) { - installedServices = new HashMap<>(installedServices); + if (createAmbariIdentities(existingConfigurations.get(KERBEROS_ENV))) { + installedServices = new HashMap<String, Set<String>>(installedServices); installedServices.put("AMBARI", Collections.singleton("AMBARI_SERVER")); } @@ -482,7 +486,7 @@ public class KerberosHelperImpl implements KerberosHelper { processIdentityConfigurations(identityConfigurations, kerberosConfigurations, configurations, propertiesToIgnore); mergeConfigurations(kerberosConfigurations, - componentDescriptor.getConfigurations(!servicePreviouslyExisted), configurations); + componentDescriptor.getConfigurations(!servicePreviouslyExisted), configurations, null); } } } @@ -491,14 +495,134 @@ public class KerberosHelperImpl implements KerberosHelper { } } - setAuthToLocalRules(kerberosDescriptor, kerberosDetails.getDefaultRealm(), installedServices, configurations, kerberosConfigurations); + setAuthToLocalRules(cluster, kerberosDescriptor, kerberosDetails.getDefaultRealm(), installedServices, configurations, kerberosConfigurations, false); return (applyStackAdvisorUpdates) ? applyStackAdvisorUpdates(cluster, installedServices.keySet(), configurations, kerberosConfigurations, propertiesToIgnore, - new HashMap<>(), kerberosEnabled) + new HashMap<>(), kerberosEnabled) : kerberosConfigurations; } + /** + * Adds host assignments, recommended by the Stack Advisor, to the configuration map (clusterHostInfo) + * for the components specified in the component filter <code>componentFilter</code> (or all if the + * component filter is <code>null</code>). + * + * @param cluster the cluster + * @param services the relevant services to consider + * @param componentFilter the set of components to add to the clusterHostInfo structure + * @param configurations the configurations map to update + * @throws AmbariException if an error occurs + */ + private void applyStackAdvisorHostRecommendations(Cluster cluster, + Set<String> services, + Set<String> componentFilter, + Map<String, Map<String, String>> configurations) + throws AmbariException { + StackId stackVersion = cluster.getCurrentStackVersion(); + List<String> hostNames = new ArrayList<>(); + + Collection<Host> hosts = cluster.getHosts(); + if (hosts != null) { + for (Host host : hosts) { + hostNames.add(host.getHostName()); + } + } + + StackAdvisorRequest request = StackAdvisorRequest.StackAdvisorRequestBuilder + .forStack(stackVersion.getStackName(), stackVersion.getStackVersion()) + .forServices(services) + .forHosts(hostNames) + .withComponentHostsMap(cluster.getServiceComponentHostMap(null, services)) + .ofType(StackAdvisorRequest.StackAdvisorRequestType.HOST_GROUPS) + .build(); + + try { + RecommendationResponse response = stackAdvisorHelper.recommend(request); + + RecommendationResponse.Recommendation recommendation = (response == null) ? null : response.getRecommendations(); + RecommendationResponse.Blueprint blueprint = (recommendation == null) ? null : recommendation.getBlueprint(); + Set<RecommendationResponse.HostGroup> hostGroups = (blueprint == null) ? null : blueprint.getHostGroups(); + + + if (hostGroups != null) { + RecommendationResponse.BlueprintClusterBinding blueprintBinding = recommendation.getBlueprintClusterBinding(); + Map<String, RecommendationResponse.BindingHostGroup> bindingMap = new HashMap<>(); + if (blueprintBinding != null) { + Set<RecommendationResponse.BindingHostGroup> bindingHostGroups = blueprintBinding.getHostGroups(); + if (bindingHostGroups != null) { + for (RecommendationResponse.BindingHostGroup bindingHostGroup : bindingHostGroups) { + bindingMap.put(bindingHostGroup.getName(), bindingHostGroup); + } + } + } + + // Get (and created if needed) the clusterHostInfo map + Map<String, String> clusterHostInfoMap = configurations.get("clusterHostInfo"); + if (clusterHostInfoMap == null) { + clusterHostInfoMap = new HashMap<>(); + configurations.put("clusterHostInfo", clusterHostInfoMap); + } + + Map<String, String> componentToClusterInfoMap = StageUtils.getComponentToClusterInfoKeyMap(); + + // Iterate through the recommendations to find the recommended host assignments + for (RecommendationResponse.HostGroup hostGroup : hostGroups) { + Set<Map<String, String>> components = hostGroup.getComponents(); + + if (components != null) { + RecommendationResponse.BindingHostGroup binding = bindingMap.get(hostGroup.getName()); + + if (binding != null) { + Set<Map<String, String>> hostGroupHosts = binding.getHosts(); + + if (hostGroupHosts != null) { + for (Map<String, String> component : components) { + String componentName = component.get("name"); + + // If the component filter is null or the current component is found in the filter, + // include it in the map + if ((componentFilter == null) || componentFilter.contains(componentName)) { + String key = componentToClusterInfoMap.get(componentName); + + if (StringUtils.isEmpty(key)) { + // If not found in the componentToClusterInfoMap, then keys are assumed to be + // in the form of <component_name>_hosts (lowercase) + key = componentName.toLowerCase() + "_hosts"; + } + + Set<String> fqdns = new TreeSet<>(); + + // Values are a comma-delimited list of hosts. + // If a value exists, split it and add the tokens to the set + if (!StringUtils.isEmpty(clusterHostInfoMap.get(key))) { + fqdns.addAll(Arrays.asList(clusterHostInfoMap.get(key).split(","))); + } + + // Add the set of hosts for the current host group + for (Map<String, String> hostGroupHost : hostGroupHosts) { + String fqdn = hostGroupHost.get("fqdn"); + + if (!StringUtils.isEmpty(fqdn)) { + fqdns.add(fqdn); + } + } + + // create the comma-delimited list of hosts + clusterHostInfoMap.put(key, StringUtils.join(fqdns, ',')); + } + } + } + } + } + } + } + } catch (StackAdvisorException e) { + LOG.error("Failed to obtain the recommended host groups for the preconfigured components.", e); + throw new AmbariException(e.getMessage(), e); + } + } + @Override public Map<String, Map<String, String>> applyStackAdvisorUpdates(Cluster cluster, Set<String> services, Map<String, Map<String, String>> existingConfigurations, @@ -568,9 +692,16 @@ public class KerberosHelperImpl implements KerberosHelper { } Set<StackId> visitedStacks = new HashSet<>(); + Map<String, Service> installedServices = cluster.getServices(); for (String serviceName : services) { - Service service = cluster.getService(serviceName); + Service service = installedServices.get(serviceName); + + // Skip services that are not really installed + if (service == null) { + continue; + } + StackId stackId = service.getDesiredStackId(); if (visitedStacks.contains(stackId)) { @@ -579,7 +710,7 @@ public class KerberosHelperImpl implements KerberosHelper { StackAdvisorRequest request = StackAdvisorRequest.StackAdvisorRequestBuilder .forStack(stackId.getStackName(), stackId.getStackVersion()) - .forServices(new ArrayList<>(services)) + .forServices(services) .forHosts(hostNames) .withComponentHostsMap(cluster.getServiceComponentHostMap(null, services)) .withConfigurations(requestConfigurations) @@ -647,7 +778,7 @@ public class KerberosHelperImpl implements KerberosHelper { "\n\tConfigType: {}\n\tProperty: {}\n\tValue: {}", configType, propertyName, recommendedValue); - if(kerberosConfigProperties == null) { + if (kerberosConfigProperties == null) { kerberosConfigProperties = new HashMap<>(); kerberosConfigurations.put(configType, kerberosConfigProperties); } @@ -723,7 +854,7 @@ public class KerberosHelperImpl implements KerberosHelper { // Only perform this task if Ambari manages Kerberos identities if (kerberosDetails.manageIdentities()) { - KerberosDescriptor kerberosDescriptor = getKerberosDescriptor(cluster); + KerberosDescriptor kerberosDescriptor = getKerberosDescriptor(cluster, false); Map<String, String> kerberosDescriptorProperties = kerberosDescriptor.getProperties(); Map<String, Map<String, String>> configurations = addAdditionalConfigurations(cluster, @@ -947,16 +1078,18 @@ public class KerberosHelperImpl implements KerberosHelper { } @Override - public void setAuthToLocalRules(KerberosDescriptor kerberosDescriptor, String realm, + public void setAuthToLocalRules(Cluster cluster, + KerberosDescriptor kerberosDescriptor, String realm, Map<String, Set<String>> installedServices, Map<String, Map<String, String>> existingConfigurations, - Map<String, Map<String, String>> kerberosConfigurations) + Map<String, Map<String, String>> kerberosConfigurations, + boolean includePreconfigureData) throws AmbariException { boolean processAuthToLocalRules = true; - Map<String, String> kerberosEnvProperties = existingConfigurations.get("kerberos-env"); - if (kerberosEnvProperties.containsKey("manage_auth_to_local")) { - processAuthToLocalRules = Boolean.valueOf(kerberosEnvProperties.get("manage_auth_to_local")); + Map<String, String> kerberosEnvProperties = existingConfigurations.get(KERBEROS_ENV); + if (kerberosEnvProperties.containsKey(MANAGE_AUTH_TO_LOCAL_RULES)) { + processAuthToLocalRules = Boolean.valueOf(kerberosEnvProperties.get(MANAGE_AUTH_TO_LOCAL_RULES)); } if (kerberosDescriptor != null && processAuthToLocalRules) { @@ -966,7 +1099,7 @@ public class KerberosHelperImpl implements KerberosHelper { // a flag to be used by the AuthToLocalBuilder marking whether the default realm rule should contain the //L option, indicating username case insensitive behaviour // the 'kerberos-env' structure is expected to be available here as it was previously validated - boolean caseInsensitiveUser = Boolean.valueOf(existingConfigurations.get("kerberos-env").get("case_insensitive_username_rules")); + boolean caseInsensitiveUser = Boolean.valueOf(existingConfigurations.get(KERBEROS_ENV).get(CASE_INSENSITIVE_USERNAME_RULES)); // Additional realms that need to be handled according to the Kerberos Descriptor String additionalRealms = kerberosDescriptor.getProperty("additional_realms"); @@ -976,43 +1109,69 @@ public class KerberosHelperImpl implements KerberosHelper { filterContext.put("configurations", existingConfigurations); filterContext.put("services", installedServices.keySet()); - // Determine which properties need to be set AuthToLocalBuilder authToLocalBuilder = new AuthToLocalBuilder(realm, additionalRealms, caseInsensitiveUser); - addIdentities(authToLocalBuilder, kerberosDescriptor.getIdentities(true, filterContext), null, existingConfigurations); + // Add in the default configurations for the services that need to be preconfigured. These + // configurations may be needed while calculating the auth-to-local rules. + Map<String, Map<String, String>> replacements = (includePreconfigureData) + ? addConfigurationsForPreProcessedServices(deepCopy(existingConfigurations), cluster, kerberosDescriptor, false) + : existingConfigurations; + + // Process top-level identities + addIdentities(authToLocalBuilder, kerberosDescriptor.getIdentities(true, filterContext), null, replacements); + + // Determine which properties need to be set authToLocalProperties = kerberosDescriptor.getAuthToLocalProperties(); if (authToLocalProperties != null) { authToLocalPropertiesToSet.addAll(authToLocalProperties); } - for(Map.Entry<String, Set<String>> installedService: installedServices.entrySet()) { - String serviceName = installedService.getKey(); + // Iterate through the services in the Kerberos descriptor. If a found service is installed + // or marked to be preconfigured, add the relevant data to the auth-to-local rules. + Map<String, KerberosServiceDescriptor> serviceDescriptors = kerberosDescriptor.getServices(); + if (serviceDescriptors != null) { + for (KerberosServiceDescriptor serviceDescriptor : serviceDescriptors.values()) { + String serviceName = serviceDescriptor.getName(); + boolean preconfigure = includePreconfigureData && serviceDescriptor.shouldPreconfigure(); + boolean explicitlyAdded = installedServices.containsKey(serviceName); + + // Add this service's identities if we are implicitly preconfigurring the service or if the + // service has been explicitly added to the cluster + if (preconfigure || explicitlyAdded) { + LOG.info("Adding identities for service {} to auth to local mapping [{}]", + serviceName, + (explicitlyAdded) ? "explicit" : "preconfigured"); - KerberosServiceDescriptor serviceDescriptor = kerberosDescriptor.getService(serviceName); - if(serviceDescriptor != null) { - LOG.info("Adding identities for service {} to auth to local mapping", installedService); + // Process the service-level Kerberos descriptor + addIdentities(authToLocalBuilder, serviceDescriptor.getIdentities(true, filterContext), null, replacements); - // Process the service-level Kerberos descriptor - addIdentities(authToLocalBuilder, serviceDescriptor.getIdentities(true, filterContext), null, existingConfigurations); + authToLocalProperties = serviceDescriptor.getAuthToLocalProperties(); + if (authToLocalProperties != null) { + authToLocalPropertiesToSet.addAll(authToLocalProperties); + } - authToLocalProperties = serviceDescriptor.getAuthToLocalProperties(); - if (authToLocalProperties != null) { - authToLocalPropertiesToSet.addAll(authToLocalProperties); - } + // Process the relevant component-level Kerberos descriptors + Map<String, KerberosComponentDescriptor> componentDescriptors = serviceDescriptor.getComponents(); + if (componentDescriptors != null) { + Set<String> installedServiceComponents = installedServices.get(serviceName); + // Ensure installedComponents is not null.... + if (installedServiceComponents == null) { + installedServiceComponents = Collections.emptySet(); + } - // Process the relevant component-level Kerberos descriptors - Set<String> installedComponents = installedService.getValue(); - if(installedComponents != null) { - for (String installedComponent : installedComponents) { - KerberosComponentDescriptor componentDescriptor = serviceDescriptor.getComponent(installedComponent); + for (KerberosComponentDescriptor componentDescriptor : componentDescriptors.values()) { + String componentName = componentDescriptor.getName(); - if (componentDescriptor != null) { - LOG.info("Adding identities for component {} to auth to local mapping", installedComponent); - addIdentities(authToLocalBuilder, componentDescriptor.getIdentities(true, filterContext), null, existingConfigurations); + // Add this component's identities if we are implicitly preconfiguring the parent + // service or if the component has been explicitly added to the cluster + if (preconfigure || (installedServiceComponents.contains(componentName))) { + LOG.info("Adding identities for component {} to auth to local mapping", componentName); + addIdentities(authToLocalBuilder, componentDescriptor.getIdentities(true, filterContext), null, replacements); - authToLocalProperties = componentDescriptor.getAuthToLocalProperties(); - if (authToLocalProperties != null) { - authToLocalPropertiesToSet.addAll(authToLocalProperties); + authToLocalProperties = componentDescriptor.getAuthToLocalProperties(); + if (authToLocalProperties != null) { + authToLocalPropertiesToSet.addAll(authToLocalProperties); + } } } } @@ -1065,63 +1224,82 @@ public class KerberosHelperImpl implements KerberosHelper { @Override - public List<ServiceComponentHost> getServiceComponentHostsToProcess(Cluster cluster, - KerberosDescriptor kerberosDescriptor, - Map<String, ? extends Collection<String>> serviceComponentFilter, - Collection<String> hostFilter, Collection<String> identityFilter, - Command<Boolean, ServiceComponentHost> shouldProcessCommand) + public List<ServiceComponentHost> getServiceComponentHostsToProcess(final Cluster cluster, + final KerberosDescriptor kerberosDescriptor, + final Map<String, ? extends Collection<String>> serviceComponentFilter, + final Collection<String> hostFilter, Collection<String> identityFilter, + final Command<Boolean, ServiceComponentHost> shouldProcessCommand) throws AmbariException { - List<ServiceComponentHost> serviceComponentHostsToProcess = new ArrayList<>(); - Map<String, Service> services = cluster.getServices(); - - if ((services != null) && !services.isEmpty()) { - Collection<Host> hosts = cluster.getHosts(); - - if ((hosts != null) && !hosts.isEmpty()) { - // Iterate over the hosts in the cluster to find the components installed in each. For each - // component (aka service component host - sch) determine the configuration updates and - // and the principals an keytabs to create. - for (Host host : hosts) { - String hostname = host.getHostName(); - - // Filter hosts as needed.... - if ((hostFilter == null) || hostFilter.contains(hostname)) { - // Get a list of components on the current host - List<ServiceComponentHost> serviceComponentHosts = cluster.getServiceComponentHosts(hostname); - - if ((serviceComponentHosts != null) && !serviceComponentHosts.isEmpty()) { - - // Iterate over the components installed on the current host to get the service and - // component-level Kerberos descriptors in order to determine which principals, - // keytab files, and configurations need to be created or updated. - for (ServiceComponentHost sch : serviceComponentHosts) { - String serviceName = sch.getServiceName(); - String componentName = sch.getServiceComponentName(); - - // If there is no filter or the filter contains the current service name... - if ((serviceComponentFilter == null) || serviceComponentFilter.containsKey(serviceName)) { - Collection<String> componentFilter = (serviceComponentFilter == null) ? null : serviceComponentFilter.get(serviceName); - KerberosServiceDescriptor serviceDescriptor = kerberosDescriptor.getService(serviceName); - - if (serviceDescriptor != null) { - // If there is no filter or the filter contains the current component name, - // test to see if this component should be processed by querying the handler... - if (((componentFilter == null) || componentFilter.contains(componentName)) && shouldProcessCommand.invoke(sch)) { - serviceComponentHostsToProcess.add(sch); - } - } - } + return getServiceComponentHosts(cluster, new Command<Boolean, ServiceComponentHost>() { + @Override + public Boolean invoke(ServiceComponentHost sch) throws AmbariException { + if (sch != null) { + // Check the host filter + if ((hostFilter == null) || hostFilter.contains(sch.getHostName())) { + String serviceName = sch.getServiceName(); + + // Check the service filter + if ((serviceComponentFilter == null) || serviceComponentFilter.containsKey(serviceName)) { + KerberosServiceDescriptor serviceDescriptor = kerberosDescriptor.getService(serviceName); + + if (serviceDescriptor != null) { + Collection<String> componentFilter = (serviceComponentFilter == null) ? null : serviceComponentFilter.get(serviceName); + + // Check the service/component filter and the shouldProcessCommand + return (((componentFilter == null) || componentFilter.contains(sch.getServiceComponentName())) && + ((shouldProcessCommand == null) || shouldProcessCommand.invoke(sch))); } } } } + + return false; + } + }); + } + + /** + * Find the {@link ServiceComponentHost}s for the cluster, filtering using the + * supplied "should include" command (<code>shouldIncludeCommand</code>). + * <p> + * If <code>shouldIncludeCommand</code> is <code>null/code>, no filtering will be performed causing + * all found {@link ServiceComponentHost}s to be returned. + * + * @param cluster the cluster + * @param shouldIncludeCommand the filtering logic + * @return a list of (filtered) {@link ServiceComponentHost}s + * @throws AmbariException if an error occurs + */ + private List<ServiceComponentHost> getServiceComponentHosts(Cluster cluster, + Command<Boolean, ServiceComponentHost> shouldIncludeCommand) + throws AmbariException { + List<ServiceComponentHost> serviceComponentHostsToProcess = new ArrayList<>(); + // Get the hosts in the cluster + Collection<Host> hosts = cluster.getHosts(); + + if ((hosts != null) && !hosts.isEmpty()) { + // Iterate over the hosts in the cluster to find the components installed in each. + for (Host host : hosts) { + String hostname = host.getHostName(); + + // Get a list of components on the current host + List<ServiceComponentHost> serviceComponentHosts = cluster.getServiceComponentHosts(hostname); + + if ((serviceComponentHosts != null) && !serviceComponentHosts.isEmpty()) { + // Iterate over the components installed on the current host and execute the shouldIncludeCommand + // Command (if supplied) to get the desired ServiceComponentHost instances. + for (ServiceComponentHost sch : serviceComponentHosts) { + if ((shouldIncludeCommand == null) || shouldIncludeCommand.invoke(sch)) { + serviceComponentHostsToProcess.add(sch); + } + } + } } } return serviceComponentHostsToProcess; } - @Override public Set<String> getHostsWithValidKerberosClient(Cluster cluster) throws AmbariException { @@ -1140,41 +1318,30 @@ public class KerberosHelperImpl implements KerberosHelper { } @Override - public KerberosDescriptor getKerberosDescriptor(Cluster cluster) throws AmbariException { - return getKerberosDescriptor(KerberosDescriptorType.COMPOSITE, cluster, false, null); + public KerberosDescriptor getKerberosDescriptor(Cluster cluster, boolean includePreconfigureData) throws AmbariException { + return getKerberosDescriptor(KerberosDescriptorType.COMPOSITE, cluster, false, null, includePreconfigureData); } @Override public KerberosDescriptor getKerberosDescriptor(KerberosDescriptorType kerberosDescriptorType, Cluster cluster, - boolean evaluateWhenClauses, Collection<String> additionalServices) + boolean evaluateWhenClauses, Collection<String> additionalServices, + boolean includePreconfigureData) throws AmbariException { - KerberosDescriptor kerberosDescriptor; KerberosDescriptor stackDescriptor = (kerberosDescriptorType == KerberosDescriptorType.STACK || kerberosDescriptorType == KerberosDescriptorType.COMPOSITE) - ? getKerberosDescriptorFromStack(cluster) + ? getKerberosDescriptorFromStack(cluster, includePreconfigureData) : null; KerberosDescriptor userDescriptor = (kerberosDescriptorType == KerberosDescriptorType.USER || kerberosDescriptorType == KerberosDescriptorType.COMPOSITE) ? getKerberosDescriptorUpdates(cluster) : null; - if (stackDescriptor == null) { - if (userDescriptor == null) { - return new KerberosDescriptor(); // return an empty Kerberos descriptor since we have no data - } else { - kerberosDescriptor = userDescriptor; - } - } else { - if (userDescriptor != null) { - stackDescriptor.update(userDescriptor); - } - kerberosDescriptor = stackDescriptor; - } + KerberosDescriptor kerberosDescriptor = combineKerberosDescriptors(stackDescriptor, userDescriptor); if (evaluateWhenClauses) { Set<String> services = new HashSet<>(cluster.getServices().keySet()); - if(additionalServices != null) { + if (additionalServices != null) { services.addAll(additionalServices); } @@ -1220,7 +1387,8 @@ public class KerberosHelperImpl implements KerberosHelper { @Override public Map<String, Map<String, String>> mergeConfigurations(Map<String, Map<String, String>> configurations, Map<String, KerberosConfigurationDescriptor> updates, - Map<String, Map<String, String>> replacements) + Map<String, Map<String, String>> replacements, + Set<String> configurationTypeFilter) throws AmbariException { if ((updates != null) && !updates.isEmpty()) { @@ -1230,11 +1398,59 @@ public class KerberosHelperImpl implements KerberosHelper { for (Map.Entry<String, KerberosConfigurationDescriptor> entry : updates.entrySet()) { String type = entry.getKey(); - KerberosConfigurationDescriptor configurationDescriptor = entry.getValue(); - if (configurationDescriptor != null) { - Map<String, String> updatedProperties = configurationDescriptor.getProperties(); - mergeConfigurations(configurations, type, updatedProperties, replacements); + if ((configurationTypeFilter == null) || (configurationTypeFilter.contains(type))) { + KerberosConfigurationDescriptor configurationDescriptor = entry.getValue(); + + if (configurationDescriptor != null) { + Map<String, String> updatedProperties = configurationDescriptor.getProperties(); + mergeConfigurations(configurations, type, updatedProperties, replacements); + } + } + } + } + + return configurations; + } + + @Override + public Map<String, Map<String, String>> processPreconfiguredServiceConfigurations(Map<String, Map<String, String>> configurations, + Map<String, Map<String, String>> replacements, + Cluster cluster, + KerberosDescriptor kerberosDescriptor) + throws AmbariException { + + // Ensure the Kerberos descriptor exists.... + if (kerberosDescriptor == null) { + kerberosDescriptor = getKerberosDescriptor(cluster, true); + } + + Map<String, KerberosServiceDescriptor> serviceDescriptors = kerberosDescriptor.getServices(); + + if (serviceDescriptors != null) { + if (configurations == null) { + configurations = new HashMap<>(); + } + + // Add in the default configurations for the services that need to be preconfigured. These + // configurations may be needed while calculating the auth-to-local rules. + Map<String, Map<String, String>> replacementsWithDefaults = addConfigurationsForPreProcessedServices(deepCopy(replacements), cluster, kerberosDescriptor, true); + + Map<String, Service> existingServices = cluster.getServices(); + + for (KerberosServiceDescriptor serviceDescriptor : serviceDescriptors.values()) { + String serviceName = serviceDescriptor.getName(); + boolean shouldPreconfigure = serviceDescriptor.shouldPreconfigure(); + + if (!existingServices.containsKey(serviceName) && shouldPreconfigure) { + configurations = mergeConfigurations(configurations, serviceDescriptor.getConfigurations(), replacementsWithDefaults, replacements.keySet()); + + Map<String, KerberosComponentDescriptor> componentDescriptors = serviceDescriptor.getComponents(); + if (componentDescriptors != null) { + for (KerberosComponentDescriptor componentDescriptor : componentDescriptors.values()) { + configurations = mergeConfigurations(configurations, componentDescriptor.getConfigurations(), replacementsWithDefaults, replacements.keySet()); + } + } } } } @@ -1318,16 +1534,15 @@ public class KerberosHelperImpl implements KerberosHelper { @Override public Map<String, Map<String, String>> calculateConfigurations(Cluster cluster, String hostname, Map<String, String> kerberosDescriptorProperties) - throws AmbariException - { + throws AmbariException { return addAdditionalConfigurations(cluster, - calculateExistingConfigurations(cluster, hostname), - hostname, kerberosDescriptorProperties); + calculateExistingConfigurations(cluster, hostname), + hostname, kerberosDescriptorProperties); } private Map<String, String> principalNames(Cluster cluster, Map<String, Map<String, String>> configuration) throws AmbariException { Map<String, String> result = new HashMap<>(); - for (Map.Entry<String, String> each : getKerberosDescriptor(cluster).principals().entrySet()) { + for (Map.Entry<String, String> each : getKerberosDescriptor(cluster, false).principals().entrySet()) { result.put(each.getKey(), variableReplacementHelper.replaceVariables(each.getValue(), configuration)); } return result; @@ -1355,12 +1570,11 @@ public class KerberosHelperImpl implements KerberosHelper { // Only calculate the active identities if the kerberos-env configurtaion is available. Else // important information like the realm will be missing (kerberos-env/realm) - Config kerberosEnvConfig = cluster.getDesiredConfigByType("kerberos-env"); - if(kerberosEnvConfig == null) { + Config kerberosEnvConfig = cluster.getDesiredConfigByType(KERBEROS_ENV); + if (kerberosEnvConfig == null) { LOG.debug("Calculating the active identities for {} is being skipped since the kerberos-env configuration is not available", clusterName, cluster.getSecurityType().name(), SecurityType.KERBEROS.name()); - } - else { + } else { Collection<String> hosts; String ambariServerHostname = StageUtils.getHostName(); @@ -1383,7 +1597,7 @@ public class KerberosHelperImpl implements KerberosHelper { } if (!hosts.isEmpty()) { - KerberosDescriptor kerberosDescriptor = getKerberosDescriptor(cluster); + KerberosDescriptor kerberosDescriptor = getKerberosDescriptor(cluster, false); if (kerberosDescriptor != null) { Map<String, String> kerberosDescriptorProperties = kerberosDescriptor.getProperties(); @@ -1410,7 +1624,7 @@ public class KerberosHelperImpl implements KerberosHelper { if (hostname.equals(ambariServerHostname)) { // Determine if we should _calculate_ the Ambari service identities. // If kerberos-env/create_ambari_principal is not set to false the identity should be calculated. - if(createAmbariIdentities(kerberosEnvConfig.getProperties())) { + if (createAmbariIdentities(kerberosEnvConfig.getProperties())) { List<KerberosIdentityDescriptor> ambariIdentities = getAmbariServerIdentities(kerberosDescriptor); if (ambariIdentities != null) { identities.addAll(ambariIdentities); @@ -1743,7 +1957,7 @@ public class KerberosHelperImpl implements KerberosHelper { final Handler handler) throws AmbariException, KerberosOperationException { - final KerberosDescriptor kerberosDescriptor = getKerberosDescriptor(cluster); + final KerberosDescriptor kerberosDescriptor = getKerberosDescriptor(cluster, false); List<ServiceComponentHost> schToProcess = getServiceComponentHostsToProcess( cluster, @@ -1751,7 +1965,7 @@ public class KerberosHelperImpl implements KerberosHelper { serviceComponentFilter, hostFilter, identityFilter, - arg -> true); + arg -> true); // While iterating over all the ServiceComponentHosts find hosts that have KERBEROS_CLIENT @@ -1791,7 +2005,7 @@ public class KerberosHelperImpl implements KerberosHelper { Map<String, Set<String>> clusterHostInfo = StageUtils.getClusterHostInfo(cluster); String clusterHostInfoJson = StageUtils.getGson().toJson(clusterHostInfo); - @Experimental(feature=ExperimentalFeature.MULTI_SERVICE, comment="The cluster stack id is deprecated") + @Experimental(feature = ExperimentalFeature.MULTI_SERVICE, comment = "The cluster stack id is deprecated") Map<String, String> hostParams = customCommandExecutionHelper.createDefaultHostParams(cluster, cluster.getDesiredStackVersion()); String hostParamsJson = StageUtils.getGson().toJson(hostParams); String ambariServerHostname = StageUtils.getHostName(); @@ -1855,7 +2069,7 @@ public class KerberosHelperImpl implements KerberosHelper { } List<ServiceComponentHost> serviceComponentHostsToProcess = new ArrayList<>(); - KerberosDescriptor kerberosDescriptor = getKerberosDescriptor(cluster); + KerberosDescriptor kerberosDescriptor = getKerberosDescriptor(cluster, false); KerberosIdentityDataFileWriter kerberosIdentityDataFileWriter = null; Map<String, String> kerberosDescriptorProperties = kerberosDescriptor.getProperties(); @@ -1965,7 +2179,7 @@ public class KerberosHelperImpl implements KerberosHelper { Map<String, Set<String>> clusterHostInfo = StageUtils.getClusterHostInfo(cluster); String clusterHostInfoJson = StageUtils.getGson().toJson(clusterHostInfo); - @Experimental(feature=ExperimentalFeature.MULTI_SERVICE, comment="The cluster stack id is deprecated") + @Experimental(feature = ExperimentalFeature.MULTI_SERVICE, comment = "The cluster stack id is deprecated") Map<String, String> hostParams = customCommandExecutionHelper.createDefaultHostParams(cluster, cluster.getDesiredStackVersion()); String hostParamsJson = StageUtils.getGson().toJson(hostParams); String ambariServerHostname = StageUtils.getHostName(); @@ -2037,7 +2251,7 @@ public class KerberosHelperImpl implements KerberosHelper { throw new AmbariException(message); } - Config configKerberosEnv = cluster.getDesiredConfigByType("kerberos-env"); + Config configKerberosEnv = cluster.getDesiredConfigByType(KERBEROS_ENV); if (configKerberosEnv == null) { String message = "The 'kerberos-env' configuration is not available"; LOG.error(message); @@ -2052,14 +2266,14 @@ public class KerberosHelperImpl implements KerberosHelper { } kerberosDetails.setSecurityType(cluster.getSecurityType()); - kerberosDetails.setDefaultRealm(kerberosEnvProperties.get("realm")); + kerberosDetails.setDefaultRealm(kerberosEnvProperties.get(DEFAULT_REALM)); kerberosDetails.setKerberosEnvProperties(kerberosEnvProperties); // If set, override the manage identities behavior kerberosDetails.setManageIdentities(manageIdentities); - String kdcTypeProperty = kerberosEnvProperties.get("kdc_type"); + String kdcTypeProperty = kerberosEnvProperties.get(KDC_TYPE); if ((kdcTypeProperty == null) && kerberosDetails.manageIdentities()) { String message = "The 'kerberos-env/kdc_type' value must be set to a valid KDC type"; LOG.error(message); @@ -2253,12 +2467,12 @@ public class KerberosHelperImpl implements KerberosHelper { /** * Creates a new stage * - * @param id the new stage's id - * @param cluster the relevant Cluster - * @param requestId the relevant request Id - * @param requestContext a String describing the stage - * @param commandParams JSON-encoded command parameters - * @param hostParams JSON-encoded host parameters + * @param id the new stage's id + * @param cluster the relevant Cluster + * @param requestId the relevant request Id + * @param requestContext a String describing the stage + * @param commandParams JSON-encoded command parameters + * @param hostParams JSON-encoded host parameters * @return a newly created Stage */ private Stage createNewStage(long id, Cluster cluster, long requestId, @@ -2302,7 +2516,7 @@ public class KerberosHelperImpl implements KerberosHelper { Map<String, String> commandParameters, String commandDetail, Integer timeout) throws AmbariException { - Stage stage = createNewStage(id, cluster, requestId, requestContext, commandParams, hostParams); + Stage stage = createNewStage(id, cluster, requestId, requestContext, commandParams, hostParams); stage.addServerActionCommand(actionClass.getName(), null, Role.AMBARI_SERVER_ACTION, RoleCommand.EXECUTE, cluster.getClusterName(), event, commandParameters, commandDetail, ambariManagementController.findConfigurationTagsWithOverrides(cluster, null), timeout, @@ -2628,11 +2842,12 @@ public class KerberosHelperImpl implements KerberosHelper { * Get the default Kerberos descriptor from the stack, which is the same as the value from * <code>stacks/:stackName/versions/:version/artifacts/kerberos_descriptor</code> * - * @param cluster the cluster + * @param cluster the cluster + * @param includePreconfigureData <code>true</code> to include the preconfigure data; otherwise false * @return a Kerberos Descriptor * @throws AmbariException if an error occurs while retrieving the Kerberos descriptor */ - private KerberosDescriptor getKerberosDescriptorFromStack(Cluster cluster) throws AmbariException { + private KerberosDescriptor getKerberosDescriptorFromStack(Cluster cluster, boolean includePreconfigureData) throws AmbariException { // !!! FIXME in a per-service view, what does this become? Set<StackId> stackIds = new HashSet<>(); @@ -2649,14 +2864,14 @@ public class KerberosHelperImpl implements KerberosHelper { // ------------------------------- // Get the default Kerberos descriptor from the stack, which is the same as the value from // stacks/:stackName/versions/:version/artifacts/kerberos_descriptor - return ambariMetaInfo.getKerberosDescriptor(stackId.getStackName(), stackId.getStackVersion()); + return ambariMetaInfo.getKerberosDescriptor(stackId.getStackName(), stackId.getStackVersion(), includePreconfigureData); // ------------------------------- } /** * Recursively walk the Kerberos descriptor tree to find all Kerberos identity definitions and * determine which should be filtered out. - * + * <p> * No actual filtering is performed while processing since any referenced Kerberos identities need * to be accessible throughout the process. So a map of container path to a list of identities is * created an returned @@ -2668,14 +2883,14 @@ public class KerberosHelperImpl implements KerberosHelper { * @return * @throws AmbariException */ - private Map<String,Set<String>> processWhenClauses(String currentPath, AbstractKerberosDescriptorContainer container, Map<String, Object> context, Map<String,Set<String>> identitiesToRemove) throws AmbariException { + private Map<String, Set<String>> processWhenClauses(String currentPath, AbstractKerberosDescriptorContainer container, Map<String, Object> context, Map<String, Set<String>> identitiesToRemove) throws AmbariException { // Get the list of this container's identities. // Do not filter these identities using KerberosIdentityDescriptor#shouldInclude since we will do // that later. List<KerberosIdentityDescriptor> identities = container.getIdentities(true, null); - if((identities != null) && !identities.isEmpty()) { + if ((identities != null) && !identities.isEmpty()) { Set<String> set = null; for (KerberosIdentityDescriptor identity : identities) { @@ -2691,8 +2906,8 @@ public class KerberosHelperImpl implements KerberosHelper { } Collection<? extends AbstractKerberosDescriptorContainer> children = container.getChildContainers(); - if(children != null) { - for(AbstractKerberosDescriptorContainer child: children) { + if (children != null) { + for (AbstractKerberosDescriptorContainer child : children) { identitiesToRemove = processWhenClauses(currentPath + "/" + child.getName(), child, context, identitiesToRemove); } } @@ -2749,6 +2964,142 @@ public class KerberosHelperImpl implements KerberosHelper { } + /** + * Gathers the Kerberos-related configurations for services not yet installed, but flagged to be + * preconfigured. + * <p> + * Only existing configuration types will be updated, new types will not be added since they are + * expected only when the relevant service has been installed. This is to help reduce the number + * of service restarts when new services are added to clusters where Kerberos has been enabled. + * <p> + * If desired, the Stack Advisor will be invoked to request recommended hosts for the component. + * This is needed to fill out the clusterHostInfo structure in the configuration map. For example, + * <code>clusterHostInfo/knox_gateway_hosts</code> + * + * @param configurations the existing configurations (updated in-place) + * @param cluster the cluster + * @param kerberosDescriptor the kerberos descriptor + * @param calculateClusterHostInfo true, to query the Stack Advisor for recommended hosts for the + * preconfigured services and components; false, otherwise + * @return the updated configuration map + * @throws AmbariException if an error occurs + */ + private Map<String, Map<String, String>> addConfigurationsForPreProcessedServices(Map<String, Map<String, String>> configurations, + Cluster cluster, + KerberosDescriptor kerberosDescriptor, + boolean calculateClusterHostInfo) + throws AmbariException { + + Map<String, KerberosServiceDescriptor> serviceDescriptorMap = kerberosDescriptor.getServices(); + + if (serviceDescriptorMap != null) { + Map<String, Service> existingServices = cluster.getServices(); + Set<String> allServices = new HashSet<>(existingServices.keySet()); + Set<String> componentFilter = new HashSet<>(); + StackId stackVersion = cluster.getCurrentStackVersion(); + + for (KerberosServiceDescriptor serviceDescriptor : serviceDescriptorMap.values()) { + String serviceName = serviceDescriptor.getName(); + boolean shouldPreconfigure = serviceDescriptor.shouldPreconfigure(); + + if (shouldPreconfigure && !existingServices.containsKey(serviceName)) { + if (ambariMetaInfo.isValidService(stackVersion.getStackName(), stackVersion.getStackVersion(), serviceName)) { + ServiceInfo serviceInfo = ambariMetaInfo.getService(stackVersion.getStackName(), stackVersion.getStackVersion(), serviceName); + + Collection<PropertyInfo> servicePropertiesInfos = serviceInfo.getProperties(); + if (servicePropertiesInfos != null) { + Map<String, Map<String, String>> propertiesToAdd = new HashMap<>(); + + for (PropertyInfo propertyInfo : servicePropertiesInfos) { + String type = ConfigHelper.fileNameToConfigType(propertyInfo.getFilename()); + + Map<String, String> map = propertiesToAdd.get(type); + if (map == null) { + map = new HashMap<>(); + propertiesToAdd.put(type, map); + } + map.put(propertyInfo.getName(), propertyInfo.getValue()); + } + + for (Map.Entry<String, Map<String, String>> entry : propertiesToAdd.entrySet()) { + if (!configurations.containsKey(entry.getKey())) { + configurations.put(entry.getKey(), entry.getValue()); + } + } + } + + // This is only needed if the Stack Advisor is being called to get recommended host + // for components + if (calculateClusterHostInfo) { + // Add the service to preconfigure to the all services set for use later + allServices.add(serviceName); + + // Add the components for the service to preconfigure to the component filter + List<ComponentInfo> componentInfos = serviceInfo.getComponents(); + if (componentInfos != null) { + for (ComponentInfo componentInfo : componentInfos) { + componentFilter.add(componentInfo.getName()); + } + } + } + } + } + } + + if (calculateClusterHostInfo && (allServices.size() > existingServices.size())) { + applyStackAdvisorHostRecommendations(cluster, allServices, componentFilter, configurations); + } + } + + return configurations; + } + + /** + * Combines a stack-level Kerberos descriptor with a user-suppled Kerberos descriptor to creae a + * composite {@link KerberosDescriptor} using the following logic: + * <p> + * <ul> + * <li> + * If both the stack-level and the user-supplied Kerberos descriptors are <code>null</code>, + * return an empty {@link KerberosDescriptor}. + * </li> + * <li> + * If the stack-level Kerberos descriptor is <code>null</code> and the user-supplied Kerberos + * descriptor is <code>non-null</code>, return the user-supplied Kerberos descriptor. + * </li> + * <li> + * If the stack-level Kerberos descriptor is <code>non-null</code> and the user-supplied + * Kerberos descriptor is <code>null</code>, return the stack-level Kerberos descriptor. + * </li> + * <li> + * If neither the stack-level nor the user-supplied Kerberos descriptors are <code>null</code>, + * return the stack-level Kerberos descriptor that has been updated using data from the + * user-supplied Kerberos descriptor. + * </li> + * </ul> + * + * @param stackDescriptor the stack-level Keberos descriptor + * @param userDescriptor the user-supplied Kerberos descriptor + * @return a KerberosDescriptor + */ + private KerberosDescriptor combineKerberosDescriptors(KerberosDescriptor stackDescriptor, KerberosDescriptor userDescriptor) { + KerberosDescriptor kerberosDescriptor; + if (stackDescriptor == null) { + if (userDescriptor == null) { + return new KerberosDescriptor(); // return an empty Kerberos descriptor since we have no data + } else { + kerberosDescriptor = userDescriptor; + } + } else { + if (userDescriptor != null) { + stackDescriptor.update(userDescriptor); + } + kerberosDescriptor = stackDescriptor; + } + + return kerberosDescriptor; + } + /* ******************************************************************************************** * Helper classes and enums * ******************************************************************************************** *\ @@ -2994,7 +3345,7 @@ public class KerberosHelperImpl implements KerberosHelper { hostParamsJson); Collection<ServiceComponentHost> filteredComponents = filterServiceComponentHostsForHosts( - new ArrayList<>(serviceComponentHosts), hostsWithValidKerberosClient); + new ArrayList<>(serviceComponentHosts), hostsWithValidKerberosClient); if (!filteredComponents.isEmpty()) { List<String> hostsToUpdate = createUniqueHostList(filteredComponents, Collections.singleton(HostState.HEALTHY)); @@ -3005,7 +3356,7 @@ public class KerberosHelperImpl implements KerberosHelper { ActionExecutionContext actionExecContext = new ActionExecutionContext( cluster.getClusterName(), - SET_KEYTAB, + SET_KEYTAB, requestResourceFilters, requestParams); customCommandExecutionHelper.addExecutionCommandsToStage(actionExecContext, stage, @@ -3024,14 +3375,14 @@ public class KerberosHelperImpl implements KerberosHelper { */ public void addCheckMissingKeytabsStage(Cluster cluster, String clusterHostInfoJson, String hostParamsJson, ServiceComponentHostServerActionEvent event, Map<String, String> commandParameters, RoleCommandOrder roleCommandOrder, RequestStageContainer requestStageContainer, List<ServiceComponentHost> serviceComponentHosts) throws AmbariException { Stage stage = createNewStage(requestStageContainer.getLastStageId(), - cluster, - requestStageContainer.getId(), - "Checking keytabs", - StageUtils.getGson().toJson(commandParameters), - hostParamsJson); + cluster, + requestStageContainer.getId(), + "Checking keytabs", + StageUtils.getGson().toJson(commandParameters), + hostParamsJson); Collection<ServiceComponentHost> filteredComponents = filterServiceComponentHostsForHosts( - new ArrayList<>(serviceComponentHosts), getHostsWithValidKerberosClient(cluster)); + new ArrayList<>(serviceComponentHosts), getHostsWithValidKerberosClient(cluster)); List<String> hostsToUpdate = createUniqueHostList(filteredComponents, Collections.singleton(HostState.HEALTHY)); Map<String, String> requestParams = new HashMap<>(); @@ -3040,10 +3391,10 @@ public class KerberosHelperImpl implements KerberosHelper { requestResourceFilters.add(reqResFilter); ActionExecutionContext actionExecContext = new ActionExecutionContext( - cluster.getClusterName(), - CHECK_KEYTABS, - requestResourceFilters, - requestParams); + cluster.getClusterName(), + CHECK_KEYTABS, + requestResourceFilters, + requestParams); customCommandExecutionHelper.addExecutionCommandsToStage(actionExecContext, stage, requestParams, null); RoleGraph roleGraph = roleGraphFactory.createNew(roleCommandOrder); roleGraph.build(stage); @@ -3079,19 +3430,18 @@ public class KerberosHelperImpl implements KerberosHelper { } void addDisableSecurityHookStage(Cluster cluster, - String clusterHostInfoJson, - String hostParamsJson, - Map<String, String> commandParameters, - RoleCommandOrder roleCommandOrder, - RequestStageContainer requestStageContainer) - throws AmbariException - { + String clusterHostInfoJson, + String hostParamsJson, + Map<String, String> commandParameters, + RoleCommandOrder roleCommandOrder, + RequestStageContainer requestStageContainer) + throws AmbariException { Stage stage = createNewStage(requestStageContainer.getLastStageId(), - cluster, - requestStageContainer.getId(), - "Disable security", - StageUtils.getGson().toJson(commandParameters), - hostParamsJson); + cluster, + requestStageContainer.getId(), + "Disable security", + StageUtils.getGson().toJson(commandParameters), + hostParamsJson); addDisableSecurityCommandToAllServices(cluster, stage); RoleGraph roleGraph = roleGraphFactory.createNew(roleCommandOrder); roleGraph.build(stage); @@ -3103,27 +3453,26 @@ public class KerberosHelperImpl implements KerberosHelper { private void addDisableSecurityCommandToAllServices(Cluster cluster, Stage stage) throws AmbariException { for (Service service : cluster.getServices().values()) { for (ServiceComponent component : service.getServiceComponents().values()) { - if (!component.getServiceComponentHosts().isEmpty()) { - String firstHost = component.getServiceComponentHosts().keySet().iterator().next(); // it is only necessary to send it to one host - ActionExecutionContext exec = new ActionExecutionContext( + if (!component.getServiceComponentHosts().isEmpty()) { + String firstHost = component.getServiceComponentHosts().keySet().iterator().next(); // it is only necessary to send it to one host + ActionExecutionContext exec = new ActionExecutionContext( cluster.getClusterName(), "DISABLE_SECURITY", singletonList(new RequestResourceFilter(service.getName(), component.getName(), singletonList(firstHost))), Collections.emptyMap()); - customCommandExecutionHelper.addExecutionCommandsToStage(exec, stage, Collections.emptyMap(), null); + customCommandExecutionHelper.addExecutionCommandsToStage(exec, stage, Collections.emptyMap(), null); } } } } void addStopZookeeperStage(Cluster cluster, - String clusterHostInfoJson, - String hostParamsJson, - Map<String, String> commandParameters, - RoleCommandOrder roleCommandOrder, - RequestStageContainer requestStageContainer) - throws AmbariException - { + String clusterHostInfoJson, + String hostParamsJson, + Map<String, String> commandParameters, + RoleCommandOrder roleCommandOrder, + RequestStageContainer requestStageContainer) + throws AmbariException { Service zookeeper; try { zookeeper = cluster.getService("ZOOKEEPER"); @@ -3131,19 +3480,19 @@ public class KerberosHelperImpl implements KerberosHelper { return; } Stage stage = createNewStage(requestStageContainer.getLastStageId(), - cluster, - requestStageContainer.getId(), - "Stopping ZooKeeper", - StageUtils.getGson().toJson(commandParameters), - hostParamsJson); + cluster, + requestStageContainer.getId(), + "Stopping ZooKeeper", + StageUtils.getGson().toJson(commandParameters), + hostParamsJson); for (ServiceComponent component : zookeeper.getServiceComponents().values()) { - Set<String> hosts = component.getServiceComponentHosts().keySet(); - ActionExecutionContext exec = new ActionExecutionContext( + Set<String> hosts = component.getServiceComponentHosts().keySet(); + ActionExecutionContext exec = new ActionExecutionContext( cluster.getClusterName(), "STOP", singletonList(new RequestResourceFilter(zookeeper.getName(), component.getName(), new ArrayList<>(hosts))), Collections.emptyMap()); - customCommandExecutionHelper.addExecutionCommandsToStage(exec, stage, Collections.emptyMap(), null); + customCommandExecutionHelper.addExecutionCommandsToStage(exec, stage, Collections.emptyMap(), null); } RoleGraph roleGraph = roleGraphFactory.createNew(roleCommandOrder); roleGraph.build(stage); @@ -3168,7 +3517,7 @@ public class KerberosHelperImpl implements KerberosHelper { hostParamsJson); Collection<ServiceComponentHost> filteredComponents = filterServiceComponentHostsForHosts( - new ArrayList<>(serviceComponentHosts), hostsWithValidKerberosClient); + new ArrayList<>(serviceComponentHosts), hostsWithValidKerberosClient); if (!filteredComponents.isEmpty()) { List<String> hostsToUpdate = createUniqueHostList(filteredComponents, Collections.singleton(HostState.HEALTHY)); @@ -3181,7 +3530,7 @@ public class KerberosHelperImpl implements KerberosHelper { ActionExecutionContext actionExecContext = new ActionExecutionContext( cluster.getClusterName(), - REMOVE_KEYTAB, + REMOVE_KEYTAB, requestResourceFilters, requestParams); customCommandExecutionHelper.addExecutionCommandsToStage(actionExecContext, stage, @@ -3325,6 +3674,7 @@ public class KerberosHelperImpl implements KerberosHelper { commandParameters.put(KerberosServerAction.UPDATE_CONFIGURATIONS, "true"); commandParameters.put(KerberosServerAction.DEFAULT_REALM, kerberosDetails.getDefaultRealm()); commandParameters.put(KerberosServerAction.INCLUDE_AMBARI_IDENTITY, (kerberosDetails.createAmbariPrincipal()) ? "true" : "false"); + commandParameters.put(KerberosServerAction.PRECONFIGURE_SERVICES, kerberosDetails.getPreconfigureServices()); if (dataDirectory != null) { commandParameters.put(KerberosServerAction.DATA_DIRECTORY, dataDirectory.getAbsolutePath()); @@ -3431,10 +3781,10 @@ public class KerberosHelperImpl implements KerberosHelper { } addDisableSecurityHookStage(cluster, clusterHostInfoJson, hostParamsJson, commandParameters, - roleCommandOrder, requestStageContainer); + roleCommandOrder, requestStageContainer); addStopZookeeperStage(cluster, clusterHostInfoJson, hostParamsJson, commandParameters, - roleCommandOrder, requestStageContainer); + roleCommandOrder, requestStageContainer); // ***************************************************************** // Create stage to prepare operations @@ -3580,7 +3930,7 @@ public class KerberosHelperImpl implements KerberosHelper { if (!regenerateAllKeytabs) { addCheckMissingKeytabsStage(cluster, clusterHostInfoJson, hostParamsJson, event, - commandParameters, roleCommandOrder, requestStageContainer, serviceComponentHosts); + commandParameters, roleCommandOrder, requestStageContainer, serviceComponentHosts); } // ***************************************************************** @@ -3752,5 +4102,9 @@ public class KerberosHelperImpl implements KerberosHelper { return (kerberosEnvProperties == null) || !"false".equalsIgnoreCase(kerberosEnvProperties.get(CREATE_AMBARI_PRINCIPAL)); } + + public String getPreconfigureServices() { + return (kerberosEnvProperties == null) ? "" : kerberosEnvProperties.get(PRECONFIGURE_SERVICES); + } } }
http://git-wip-us.apache.org/repos/asf/ambari/blob/4bce5782/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 91a84ea..b4e1027 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 @@ -538,7 +538,7 @@ public class BlueprintConfigurationProcessor { String clusterName = clusterTopology.getAmbariContext().getClusterName(clusterTopology.getClusterId()); Cluster cluster = clusterTopology.getAmbariContext().getController().getClusters().getCluster(clusterName); authToLocalPerClusterMap = new HashMap<>(); - authToLocalPerClusterMap.put(Long.valueOf(clusterTopology.getClusterId()), clusterTopology.getAmbariContext().getController().getKerberosHelper().getKerberosDescriptor(cluster).getAllAuthToLocalProperties()); + authToLocalPerClusterMap.put(Long.valueOf(clusterTopology.getClusterId()), clusterTopology.getAmbariContext().getController().getKerberosHelper().getKerberosDescriptor(cluster, false).getAllAuthToLocalProperties()); } catch (AmbariException e) { LOG.error("Error while getting authToLocal properties. ", e); } http://git-wip-us.apache.org/repos/asf/ambari/blob/4bce5782/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterKerberosDescriptorResourceProvider.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterKerberosDescriptorResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterKerberosDescriptorResourceProvider.java index 59bd96a..2678d55 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterKerberosDescriptorResourceProvider.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterKerberosDescriptorResourceProvider.java @@ -158,7 +158,8 @@ public class ClusterKerberosDescriptorResourceProvider extends ReadOnlyResourceP kerberosDescriptor = kerberosHelper.getKerberosDescriptor(kerberosDescriptorType, cluster, getEvaluateWhen(requestInfoProperties), - getAdditionalServices(requestInfoProperties)); + getAdditionalServices(requestInfoProperties), + false); } catch (AmbariException e) { throw new SystemException("An unexpected error occurred building the cluster's composite Kerberos Descriptor", e); } http://git-wip-us.apache.org/repos/asf/ambari/blob/4bce5782/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/StackVersionResourceProvider.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/StackVersionResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/StackVersionResourceProvider.java index 64ead40..094c75b 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/StackVersionResourceProvider.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/StackVersionResourceProvider.java @@ -19,10 +19,7 @@ package org.apache.ambari.server.controller.internal; -import java.io.File; -import java.io.IOException; import java.util.Arrays; -import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.Map; @@ -42,12 +39,6 @@ import org.apache.ambari.server.controller.spi.Resource.Type; 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.kerberos.KerberosDescriptor; -import org.apache.ambari.server.state.kerberos.KerberosDescriptorFactory; -import org.apache.ambari.server.state.kerberos.KerberosServiceDescriptor; -import org.apache.ambari.server.state.kerberos.KerberosServiceDescriptorFactory; - -import com.google.inject.Inject; @StaticallyInject public class StackVersionResourceProvider extends ReadOnlyResourceProvider { @@ -67,18 +58,6 @@ public class StackVersionResourceProvider extends ReadOnlyResourceProvider { private static Set<String> pkPropertyIds = new HashSet<>( Arrays.asList(new String[]{STACK_NAME_PROPERTY_ID, STACK_VERSION_PROPERTY_ID})); - /** - * KerberosDescriptorFactory used to create KerberosDescriptor instances - */ - @Inject - private static KerberosDescriptorFactory kerberosDescriptorFactory; - - /** - * KerberosServiceDescriptorFactory used to create KerberosServiceDescriptor instances - */ - @Inject - private static KerberosServiceDescriptorFactory kerberosServiceDescriptorFactory; - protected StackVersionResourceProvider(Set<String> propertyIds, Map<Type, String> keyPropertyIds, AmbariManagementController managementController) { @@ -153,51 +132,6 @@ public class StackVersionResourceProvider extends ReadOnlyResourceProvider { return resources; } - /** - * Given data from a StackVersionResponse build a complete Kerberos descriptor hierarchy. - * - * @param stackVersionResponse the StackVersionResponse instance containing the details of the - * stack and the relevant Kerberos descriptor files - * @return a KerberosDescriptor containing the complete hierarchy for the stack - * @throws IOException if the specified File is not found or not a readable - * @throws AmbariException if the specified File does not contain valid JSON-encoded Kerberos - * descriptor - */ - private KerberosDescriptor buildKerberosDescriptor(StackVersionResponse stackVersionResponse) - throws IOException { - KerberosDescriptor kerberosDescriptor = null; - - // Process the stack-level Kerberos descriptor file - File stackKerberosDescriptorFile = stackVersionResponse.getStackKerberosDescriptorFile(); - if (stackKerberosDescriptorFile != null) { - kerberosDescriptor = kerberosDescriptorFactory.createInstance(stackKerberosDescriptorFile); - } - - // Process the service-level Kerberos descriptor files - Collection<File> serviceDescriptorFiles = stackVersionResponse.getServiceKerberosDescriptorFiles(); - if ((serviceDescriptorFiles != null) && !serviceDescriptorFiles.isEmpty()) { - // Make sure kerberosDescriptor is not null. This will be the case if there is no stack-level - // Kerberos descriptor file. - if (kerberosDescriptor == null) { - kerberosDescriptor = new KerberosDescriptor(); - } - - // For each service-level Kerberos descriptor file, parse into an array of KerberosServiceDescriptors - // and then append each to the KerberosDescriptor hierarchy. - for (File file : serviceDescriptorFiles) { - KerberosServiceDescriptor[] serviceDescriptors = kerberosServiceDescriptorFactory.createInstances(file); - - if (serviceDescriptors != null) { - for (KerberosServiceDescriptor serviceDescriptor : serviceDescriptors) { - kerberosDescriptor.putService(serviceDescriptor); - } - } - } - } - - return kerberosDescriptor; - } - private StackVersionRequest getRequest(Map<String, Object> properties) { return new StackVersionRequest( (String) properties.get(STACK_NAME_PROPERTY_ID), http://git-wip-us.apache.org/repos/asf/ambari/blob/4bce5782/ambari-server/src/main/java/org/apache/ambari/server/controller/utilities/RemovableIdentities.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/utilities/RemovableIdentities.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/utilities/RemovableIdentities.java index d4bb501..66bf7b3 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/controller/utilities/RemovableIdentities.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/utilities/RemovableIdentities.java @@ -58,7 +58,7 @@ public class RemovableIdentities { if (cluster.getSecurityType() != SecurityType.KERBEROS) { return RemovableIdentities.none(); } - KerberosServiceDescriptor serviceDescriptor = kerberosHelper.getKerberosDescriptor(cluster).getService(event.getServiceName()); + KerberosServiceDescriptor serviceDescriptor = kerberosHelper.getKerberosDescriptor(cluster, false).getService(event.getServiceName()); if (serviceDescriptor == null) { return RemovableIdentities.none(); } @@ -77,7 +77,7 @@ public class RemovableIdentities { if (cluster.getSecurityType() != SecurityType.KERBEROS) { return RemovableIdentities.none(); } - KerberosServiceDescriptor serviceDescriptor = kerberosHelper.getKerberosDescriptor(cluster).getService(event.getServiceName()); + KerberosServiceDescriptor serviceDescriptor = kerberosHelper.getKerberosDescriptor(cluster, false).getService(event.getServiceName()); if (serviceDescriptor == null) { return RemovableIdentities.none(); } http://git-wip-us.apache.org/repos/asf/ambari/blob/4bce5782/ambari-server/src/main/java/org/apache/ambari/server/controller/utilities/UsedIdentities.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/utilities/UsedIdentities.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/utilities/UsedIdentities.java index 46f5642..2f0974e 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/controller/utilities/UsedIdentities.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/utilities/UsedIdentities.java @@ -50,7 +50,7 @@ public class UsedIdentities { */ public static UsedIdentities populate(Cluster cluster, ServiceExclude serviceExclude, ComponentExclude componentExclude, KerberosHelper kerberosHelper) throws AmbariException { List<KerberosIdentityDescriptor> result = new ArrayList<>(); - KerberosDescriptor root = kerberosHelper.getKerberosDescriptor(cluster); + KerberosDescriptor root = kerberosHelper.getKerberosDescriptor(cluster, false); result.addAll(nullToEmpty(root.getIdentities())); for (Service service : cluster.getServices().values()) { if (serviceExclude.shouldExclude(service.getName())) { http://git-wip-us.apache.org/repos/asf/ambari/blob/4bce5782/ambari-server/src/main/java/org/apache/ambari/server/customactions/ActionDefinitionManager.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/customactions/ActionDefinitionManager.java b/ambari-server/src/main/java/org/apache/ambari/server/customactions/ActionDefinitionManager.java index 1f2d26f..dde2647 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/customactions/ActionDefinitionManager.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/customactions/ActionDefinitionManager.java @@ -34,8 +34,8 @@ import javax.xml.bind.Unmarshaller; import org.apache.ambari.server.AmbariException; import org.apache.ambari.server.actionmanager.ActionType; import org.apache.ambari.server.actionmanager.TargetHostType; -import org.apache.ambari.server.api.services.AmbariMetaInfo; import org.apache.ambari.server.security.authorization.RoleAuthorization; +import org.apache.ambari.server.stack.StackDirectory; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -93,7 +93,7 @@ public class ActionDefinitionManager { } File[] customActionDefinitionFiles - = customActionDefinitionRoot.listFiles(AmbariMetaInfo.FILENAME_FILTER); + = customActionDefinitionRoot.listFiles(StackDirectory.FILENAME_FILTER); if (customActionDefinitionFiles != null) { for (File definitionFile : customActionDefinitionFiles) { http://git-wip-us.apache.org/repos/asf/ambari/blob/4bce5782/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/AbstractPrepareKerberosServerAction.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/AbstractPrepareKerberosServerAction.java b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/AbstractPrepareKerberosServerAction.java index dd2b223..d6b8ffc 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/AbstractPrepareKerberosServerAction.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/AbstractPrepareKerberosServerAction.java @@ -152,7 +152,7 @@ public abstract class AbstractPrepareKerberosServerAction extends KerberosServer // Calculate the set of configurations to update and replace any variables // using the previously calculated Map of configurations for the host. kerberosHelper.mergeConfigurations(kerberosConfigurations, - componentDescriptor.getConfigurations(true), currentConfigurations); + componentDescriptor.getConfigurations(true), currentConfigurations, null); // Add component-level principals (and keytabs) kerberosHelper.addIdentities(kerberosIdentityDataFileWriter, componentIdentities, http://git-wip-us.apache.org/repos/asf/ambari/blob/4bce5782/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/KerberosServerAction.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/KerberosServerAction.java b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/KerberosServerAction.java index 2e331bb..c86ffa3 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/KerberosServerAction.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/KerberosServerAction.java @@ -135,6 +135,12 @@ public abstract class KerberosServerAction extends AbstractServerAction { */ public static final String INCLUDE_AMBARI_IDENTITY = "include_ambari_identity"; + /** + * Keys used in CommandParams from ExecutionCommand to declare how to pre-configure services. + * Expected values are, "ALL", "DEFAULT", and "NONE". + */ + public static final String PRECONFIGURE_SERVICES = "preconfigure_services"; + private static final Logger LOG = LoggerFactory.getLogger(KerberosServerAction.class); /** http://git-wip-us.apache.org/repos/asf/ambari/blob/4bce5782/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/PreconfigureServiceType.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/PreconfigureServiceType.java b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/PreconfigureServiceType.java new file mode 100644 index 0000000..c843b14 --- /dev/null +++ b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/PreconfigureServiceType.java @@ -0,0 +1,46 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ambari.server.serveraction.kerberos; + +/** + * PreconfigureServiceType enumerates the ways in which services may be pre-configured. + */ +public enum PreconfigureServiceType { + /** + * Preconfigure services that have been explicitly flagged. + * <p> + * For example, in the Kerberos descriptor using + * <code> + * "preconfigure" : true + * </code> + * <p> + * For example, declared in the stack-specific kerberos_preconfigure.json file + */ + DEFAULT, + + /** + * Preconfigure all services, flagged or not. + */ + ALL, + + /** + * Do not preconfiure any services, even if flagged. + */ + NONE +}