You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by ec...@apache.org on 2017/11/01 15:59:31 UTC
[1/2] ambari git commit: AMBARI-22278. Improve Kerberos principal and
keytab accounting (echekanskiy)
Repository: ambari
Updated Branches:
refs/heads/trunk 8a8d48fde -> d03c24b9f
http://git-wip-us.apache.org/repos/asf/ambari/blob/d03c24b9/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 1b0f4fb..3491f18 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
@@ -30,6 +30,8 @@ import org.apache.ambari.server.actionmanager.HostRoleStatus;
import org.apache.ambari.server.agent.CommandReport;
import org.apache.ambari.server.agent.ExecutionCommand;
import org.apache.ambari.server.controller.KerberosHelper;
+import org.apache.ambari.server.orm.dao.HostDAO;
+import org.apache.ambari.server.orm.entities.HostEntity;
import org.apache.ambari.server.security.credential.PrincipalKeyCredential;
import org.apache.ambari.server.serveraction.AbstractServerAction;
import org.apache.ambari.server.state.Cluster;
@@ -171,6 +173,8 @@ public abstract class KerberosServerAction extends AbstractServerAction {
@Inject
private KerberosHelper kerberosHelper;
+ @Inject
+ HostDAO hostDAO;
/**
* Given a (command parameter) Map and a property name, attempts to safely retrieve the requested
* data.
@@ -543,21 +547,8 @@ public abstract class KerberosServerAction extends AbstractServerAction {
if (record != null) {
String principal = record.get(KerberosIdentityDataFileReader.PRINCIPAL);
-
if (principal != null) {
- String hostname = record.get(KerberosIdentityDataFileReader.HOSTNAME);
-
- if(KerberosHelper.AMBARI_SERVER_HOST_NAME.equals(hostname)) {
- // Replace KerberosHelper.AMBARI_SERVER_HOST_NAME with the actual hostname where the Ambari
- // server is... this host
- hostname = StageUtils.getHostName();
- }
-
- // Evaluate the principal "pattern" found in the record to generate the "evaluated principal"
- // by replacing the _HOST and _REALM variables.
- String evaluatedPrincipal = principal.replace("_HOST", hostname).replace("_REALM", defaultRealm);
-
- commandReport = processIdentity(record, evaluatedPrincipal, operationHandler, kerberosConfiguration, requestSharedDataContext);
+ commandReport = processIdentity(record, principal, operationHandler, kerberosConfiguration, requestSharedDataContext);
}
}
@@ -588,6 +579,14 @@ public abstract class KerberosServerAction extends AbstractServerAction {
}
}
+ protected Long ambariServerHostID(){
+ String ambariServerHostName = StageUtils.getHostName();
+ HostEntity ambariServerHostEntity = hostDAO.findByName(ambariServerHostName);
+ return (ambariServerHostEntity == null)
+ ? null
+ : ambariServerHostEntity.getHostId();
+ }
+
/**
* A Kerberos operation type
* <ul>
http://git-wip-us.apache.org/repos/asf/ambari/blob/d03c24b9/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/PrepareDisableKerberosServerAction.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/PrepareDisableKerberosServerAction.java b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/PrepareDisableKerberosServerAction.java
index e1f8419..b9381b4 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/PrepareDisableKerberosServerAction.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/PrepareDisableKerberosServerAction.java
@@ -107,7 +107,7 @@ public class PrepareDisableKerberosServerAction extends AbstractPrepareKerberosS
Map<String, Map<String, String>> configurations = kerberosHelper.calculateConfigurations(cluster, null, kerberosDescriptor, false, false);
processServiceComponentHosts(cluster, kerberosDescriptor, schToProcess, identityFilter, dataDirectory,
- configurations, kerberosConfigurations, includeAmbariIdentity, propertiesToIgnore, false);
+ configurations, kerberosConfigurations, includeAmbariIdentity, propertiesToIgnore);
// Add auth-to-local configurations to the set of changes
Map<String, Set<String>> authToLocalProperties = kerberosHelper.translateConfigurationSpecifications(kerberosDescriptor.getAllAuthToLocalProperties());
http://git-wip-us.apache.org/repos/asf/ambari/blob/d03c24b9/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/PrepareEnableKerberosServerAction.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/PrepareEnableKerberosServerAction.java b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/PrepareEnableKerberosServerAction.java
index 335451f..671ad95 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/PrepareEnableKerberosServerAction.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/PrepareEnableKerberosServerAction.java
@@ -119,7 +119,7 @@ public class PrepareEnableKerberosServerAction extends PrepareKerberosIdentities
Map<String, Map<String, String>> configurations = kerberosHelper.calculateConfigurations(cluster, null, kerberosDescriptor, false, false);
processServiceComponentHosts(cluster, kerberosDescriptor, schToProcess, identityFilter, dataDirectory,
- configurations, kerberosConfigurations, true, propertiesToIgnore, false);
+ configurations, kerberosConfigurations, true, propertiesToIgnore);
// Calculate the set of configurations to update and replace any variables
// using the previously calculated Map of configurations for the host.
http://git-wip-us.apache.org/repos/asf/ambari/blob/d03c24b9/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/PrepareKerberosIdentitiesServerAction.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/PrepareKerberosIdentitiesServerAction.java b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/PrepareKerberosIdentitiesServerAction.java
index 038d1b5..b0fca8d 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/PrepareKerberosIdentitiesServerAction.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/PrepareKerberosIdentitiesServerAction.java
@@ -123,8 +123,7 @@ public class PrepareKerberosIdentitiesServerAction extends AbstractPrepareKerber
Map<String, Map<String, String>> configurations = kerberosHelper.calculateConfigurations(cluster, null, kerberosDescriptor, false, false);
processServiceComponentHosts(cluster, kerberosDescriptor, schToProcess, identityFilter, dataDirectory,
- configurations, kerberosConfigurations, includeAmbariIdentity, propertiesToIgnore,
- hostFilter != null);
+ configurations, kerberosConfigurations, includeAmbariIdentity, propertiesToIgnore);
kerberosHelper.applyStackAdvisorUpdates(cluster, services, configurations, kerberosConfigurations,
propertiesToIgnore, propertiesToRemove, true);
http://git-wip-us.apache.org/repos/asf/ambari/blob/d03c24b9/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/stageutils/ResolvedKerberosKeytab.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/stageutils/ResolvedKerberosKeytab.java b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/stageutils/ResolvedKerberosKeytab.java
new file mode 100644
index 0000000..f66d273
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/stageutils/ResolvedKerberosKeytab.java
@@ -0,0 +1,257 @@
+/*
+ * 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.stageutils;
+
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.ambari.server.state.kerberos.VariableReplacementHelper;
+import org.apache.commons.lang3.tuple.Pair;
+
+import com.google.common.collect.ImmutableSet;
+
+/**
+ * Class that represents keytab. Contains principals that mapped to host.
+ * Same keytab can have different set of principals on different hosts.
+ */
+// TODO This class need to replace {@link org.apache.ambari.server.serveraction.kerberos.KerberosIdentityDataFile}
+// TODO and all related structures and become main item that {@link org.apache.ambari.server.serveraction.kerberos.KerberosServerAction}
+// TODO operates with instead of identity records.
+public class ResolvedKerberosKeytab {
+
+ private String ownerName = null;
+ private String ownerAccess = null;
+ private String groupName = null;
+ private String groupAccess = null;
+ private String file = null;
+ private Set<Pair<Long, String>> mappedPrincipals = null;
+ private boolean isAmbariServerKeytab = false;
+ private boolean mustWriteAmbariJaasFile = false;
+
+ public ResolvedKerberosKeytab(
+ String file,
+ String ownerName,
+ String ownerAccess,
+ String groupName,
+ String groupAccess,
+ Set<Pair<Long, String>> mappedPrincipals,
+ boolean isAmbariServerKeytab,
+ boolean writeAmbariJaasFile
+ ) {
+ this.ownerName = ownerName;
+ this.ownerAccess = ownerAccess;
+ this.groupName = groupName;
+ this.groupAccess = groupAccess;
+ this.file = file;
+ this.mappedPrincipals = mappedPrincipals;
+ this.isAmbariServerKeytab = isAmbariServerKeytab;
+ this.mustWriteAmbariJaasFile = writeAmbariJaasFile;
+ }
+
+ /**
+ * Gets the path to the keytab file
+ * <p/>
+ * The value may include variable placeholders to be replaced as needed
+ * <ul>
+ * <li>
+ * ${variable} placeholders are replaced on the server - see
+ * {@link VariableReplacementHelper#replaceVariables(String, Map)}
+ * </li>
+ * </ul>
+ *
+ * @return a String declaring the keytab file's absolute path
+ * @see VariableReplacementHelper#replaceVariables(String, Map)
+ */
+ public String getFile() {
+ return file;
+ }
+
+ /**
+ * Sets the path to the keytab file
+ *
+ * @param file a String declaring this keytab's file path
+ * @see #getFile()
+ */
+ public void setFile(String file) {
+ this.file = file;
+ }
+
+ /**
+ * Gets the local username to set as the owner of the keytab file
+ *
+ * @return a String declaring the name of the user to own the keytab file
+ */
+ public String getOwnerName() {
+ return ownerName;
+ }
+
+ /**
+ * Sets the local username to set as the owner of the keytab file
+ *
+ * @param name a String declaring the name of the user to own the keytab file
+ */
+ public void setOwnerName(String name) {
+ this.ownerName = name;
+ }
+
+ /**
+ * Gets the access permissions that should be set on the keytab file related to the file's owner
+ *
+ * @return a String declaring the access permissions that should be set on the keytab file related
+ * to the file's owner
+ * @see #ownerAccess
+ */
+ public String getOwnerAccess() {
+ return ownerAccess;
+ }
+
+ /**
+ * Sets the access permissions that should be set on the keytab file related to the file's owner
+ *
+ * @param access a String declaring the access permissions that should be set on the keytab file
+ * related to the file's owner
+ * @see #ownerAccess
+ */
+ public void setOwnerAccess(String access) {
+ this.ownerAccess = access;
+ }
+
+ /**
+ * Gets the local group name to set as the group owner of the keytab file
+ *
+ * @return a String declaring the name of the group to own the keytab file
+ */
+ public String getGroupName() {
+ return groupName;
+ }
+
+ /**
+ * Sets the local group name to set as the group owner of the keytab file
+ *
+ * @param name a String declaring the name of the group to own the keytab file
+ */
+ public void setGroupName(String name) {
+ this.groupName = name;
+ }
+
+ /**
+ * Gets the access permissions that should be set on the keytab file related to the file's group
+ *
+ * @return a String declaring the access permissions that should be set on the keytab file related
+ * to the file's group
+ * @see #groupAccess
+ */
+ public String getGroupAccess() {
+ return groupAccess;
+ }
+
+ /**
+ * Sets the access permissions that should be set on the keytab file related to the file's group
+ *
+ * @param access a String declaring the access permissions that should be set on the keytab file
+ * related to the file's group
+ * @see #groupAccess
+ */
+ public void setGroupAccess(String access) {
+ this.groupAccess = access;
+ }
+
+ /**
+ * Gets evaluated host-to-principal set associated with given keytab.
+ *
+ * @return a Set with mappedPrincipals associated with given keytab
+ */
+ public Set<Pair<Long, String>> getMappedPrincipals() {
+ return mappedPrincipals;
+ }
+
+ /**
+ * Sets evaluated host-to-principal set associated with given keytab.
+ *
+ * @param mappedPrincipals a Map with host-to-principal mapping associated with given keytab
+ */
+ public void setMappedPrincipals(Set<Pair<Long, String>> mappedPrincipals) {
+ this.mappedPrincipals = mappedPrincipals;
+ }
+
+ /**
+ * Gets set of hosts associated with given keytab.
+ *
+ * @return a Set with hosts
+ */
+ public Set<Long> getHosts() {
+ ImmutableSet.Builder<Long> builder = ImmutableSet.builder();
+ for (Pair<Long, String> principal : getMappedPrincipals()) {
+ if (principal.getLeft() != null) {
+ builder.add(principal.getLeft());
+ }
+ }
+ return builder.build();
+ }
+
+ /**
+ * Gets a set of principals associated with given keytab.
+ *
+ * @return a Set of principals
+ */
+ public Set<String> getPrincipals() {
+ ImmutableSet.Builder<String> builder = ImmutableSet.builder();
+ for (Pair<Long, String> principal : getMappedPrincipals()) {
+ builder.add(principal.getRight());
+ }
+ return builder.build();
+ }
+
+ /**
+ * Indicates if given keytab is Ambari Server keytab and can be distributed to host with Ambari Server side action.
+ *
+ * @return true, if given keytab is Ambari Server keytab.
+ */
+ public boolean isAmbariServerKeytab() {
+ return isAmbariServerKeytab;
+ }
+
+ /**
+ * Sets flag to indicate if given keytab is Ambari Server keytab and can be distributed to host with Ambari Server
+ * side action.
+ *
+ * @param isAmbariServerKeytab flag value
+ */
+ public void setAmbariServerKeytab(boolean isAmbariServerKeytab) {
+ this.isAmbariServerKeytab = isAmbariServerKeytab;
+ }
+
+ /**
+ * Indicates if this keytab must be written to Ambari Server jaas file.
+ *
+ * @return true, if this keytab must be written to Ambari Server jaas file.
+ */
+ public boolean isMustWriteAmbariJaasFile() {
+ return mustWriteAmbariJaasFile;
+ }
+
+ /**
+ * Sets flag to indicate if this keytab must be written to Ambari Server jaas file.
+ *
+ * @param mustWriteAmbariJaasFile flag value
+ */
+ public void setMustWriteAmbariJaasFile(boolean mustWriteAmbariJaasFile) {
+ this.mustWriteAmbariJaasFile = mustWriteAmbariJaasFile;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/d03c24b9/ambari-server/src/main/java/org/apache/ambari/server/serveraction/upgrades/PreconfigureKerberosAction.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/upgrades/PreconfigureKerberosAction.java b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/upgrades/PreconfigureKerberosAction.java
index 5af7c6b..ca78dbb 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/upgrades/PreconfigureKerberosAction.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/upgrades/PreconfigureKerberosAction.java
@@ -38,8 +38,14 @@ import org.apache.ambari.server.actionmanager.HostRoleStatus;
import org.apache.ambari.server.agent.CommandReport;
import org.apache.ambari.server.controller.AmbariManagementController;
import org.apache.ambari.server.controller.KerberosHelper;
+import org.apache.ambari.server.orm.dao.HostDAO;
+import org.apache.ambari.server.orm.dao.KerberosKeytabDAO;
+import org.apache.ambari.server.orm.dao.KerberosPrincipalDAO;
+import org.apache.ambari.server.orm.dao.KerberosPrincipalHostDAO;
+import org.apache.ambari.server.orm.entities.HostEntity;
import org.apache.ambari.server.orm.entities.RepositoryVersionEntity;
import org.apache.ambari.server.serveraction.kerberos.PreconfigureServiceType;
+import org.apache.ambari.server.serveraction.kerberos.stageutils.ResolvedKerberosKeytab;
import org.apache.ambari.server.state.Cluster;
import org.apache.ambari.server.state.ConfigHelper;
import org.apache.ambari.server.state.Host;
@@ -56,6 +62,7 @@ import org.apache.ambari.server.state.kerberos.KerberosIdentityDescriptor;
import org.apache.ambari.server.state.kerberos.KerberosServiceDescriptor;
import org.apache.ambari.server.state.kerberos.VariableReplacementHelper;
import org.apache.ambari.server.state.stack.upgrade.Direction;
+import org.apache.ambari.server.utils.StageUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.StringUtils;
@@ -82,6 +89,18 @@ public class PreconfigureKerberosAction extends AbstractUpgradeServerAction {
@Inject
private VariableReplacementHelper variableReplacementHelper;
+ @Inject
+ private HostDAO hostDAO;
+
+ @Inject
+ private KerberosKeytabDAO kerberosKeytabDAO;
+
+ @Inject
+ KerberosPrincipalHostDAO kerberosPrincipalHostDAO;
+
+ @Inject
+ KerberosPrincipalDAO kerberosPrincipalDAO;
+
@Override
public CommandReport execute(ConcurrentMap<String, Object> requestSharedDataContext) throws AmbariException, InterruptedException {
Map<String, String> commandParameters = getCommandParameters();
@@ -131,7 +150,7 @@ public class PreconfigureKerberosAction extends AbstractUpgradeServerAction {
}
}
- processServiceComponentHosts(cluster, kerberosDescriptor, configurations, kerberosConfigurations, propertiesToIgnore);
+ processServiceComponentHosts(cluster, kerberosDescriptor, configurations, kerberosConfigurations, propertiesToIgnore, getDefaultRealm(configurations));
// Calculate the set of configurations to update and replace any variables
// using the previously calculated Map of configurations for the host.
@@ -280,7 +299,7 @@ public class PreconfigureKerberosAction extends AbstractUpgradeServerAction {
private void processServiceComponentHosts(Cluster cluster, KerberosDescriptor kerberosDescriptor,
Map<String, Map<String, String>> currentConfigurations,
Map<String, Map<String, String>> kerberosConfigurations,
- Map<String, Set<String>> propertiesToBeIgnored)
+ Map<String, Set<String>> propertiesToBeIgnored, String realm)
throws AmbariException {
Collection<Host> hosts = cluster.getHosts();
@@ -292,7 +311,7 @@ public class PreconfigureKerberosAction extends AbstractUpgradeServerAction {
try {
Map<String, Set<String>> propertiesToIgnore = null;
-
+ HashMap<String, ResolvedKerberosKeytab> resolvedKeytabs = new HashMap<>();
for (Host host : hosts) {
// Iterate over the components installed on the current host to get the service and
// component-level Kerberos descriptors in order to determine which principals,
@@ -323,7 +342,8 @@ public class PreconfigureKerberosAction extends AbstractUpgradeServerAction {
// Add service-level principals (and keytabs)
kerberosHelper.addIdentities(null, serviceIdentities,
- null, hostName, serviceName, componentName, kerberosConfigurations, currentConfigurations, false);
+ null, hostName, host.getHostId(), serviceName, componentName, kerberosConfigurations, currentConfigurations,
+ resolvedKeytabs, realm);
propertiesToIgnore = gatherPropertiesToIgnore(serviceIdentities, propertiesToIgnore);
KerberosComponentDescriptor componentDescriptor = serviceDescriptor.getComponent(componentName);
@@ -338,7 +358,8 @@ public class PreconfigureKerberosAction extends AbstractUpgradeServerAction {
// Add component-level principals (and keytabs)
kerberosHelper.addIdentities(null, componentIdentities,
- null, hostName, serviceName, componentName, kerberosConfigurations, currentConfigurations, false);
+ null, hostName, host.getHostId(), serviceName, componentName, kerberosConfigurations, currentConfigurations,
+ resolvedKeytabs,realm);
propertiesToIgnore = gatherPropertiesToIgnore(componentIdentities, propertiesToIgnore);
}
}
@@ -359,7 +380,8 @@ public class PreconfigureKerberosAction extends AbstractUpgradeServerAction {
List<KerberosIdentityDescriptor> componentIdentities = Collections.singletonList(identity);
kerberosHelper.addIdentities(null, componentIdentities,
- null, KerberosHelper.AMBARI_SERVER_HOST_NAME, "AMBARI", componentName, kerberosConfigurations, currentConfigurations, false);
+ null, KerberosHelper.AMBARI_SERVER_HOST_NAME, ambariServerHostID(), "AMBARI", componentName, kerberosConfigurations, currentConfigurations,
+ resolvedKeytabs, realm);
propertiesToIgnore = gatherPropertiesToIgnore(componentIdentities, propertiesToIgnore);
}
}
@@ -367,6 +389,11 @@ public class PreconfigureKerberosAction extends AbstractUpgradeServerAction {
if ((propertiesToBeIgnored != null) && (propertiesToIgnore != null)) {
propertiesToBeIgnored.putAll(propertiesToIgnore);
}
+
+ // create database records for keytabs that must be presented on cluster
+ for (ResolvedKerberosKeytab keytab : resolvedKeytabs.values()) {
+ kerberosHelper.processResolvedKeytab(keytab);
+ }
} catch (IOException e) {
throw new AmbariException(e.getMessage(), e);
}
@@ -582,5 +609,14 @@ public class PreconfigureKerberosAction extends AbstractUpgradeServerAction {
}
}
}
+
+ protected Long ambariServerHostID(){
+ String ambariServerHostName = StageUtils.getHostName();
+ HostEntity ambariServerHostEntity = hostDAO.findByName(ambariServerHostName);
+ return (ambariServerHostEntity == null)
+ ? null
+ : ambariServerHostEntity.getHostId();
+ }
+
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/d03c24b9/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceImpl.java
index 1104d19..ea0ceae 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceImpl.java
@@ -601,7 +601,7 @@ public class ServiceImpl implements Service {
List<Component> result = new ArrayList<>();
for (ServiceComponent component : getServiceComponents().values()) {
for (ServiceComponentHost host : component.getServiceComponentHosts().values()) {
- result.add(new Component(host.getHostName(), getName(), component.getName()));
+ result.add(new Component(host.getHostName(), getName(), component.getName(), host.getHost().getHostId()));
}
}
return result;
http://git-wip-us.apache.org/repos/asf/ambari/blob/d03c24b9/ambari-server/src/main/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostImpl.java
index 3b8f6da..e30c2ce 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/svccomphost/ServiceComponentHostImpl.java
@@ -1280,7 +1280,7 @@ public class ServiceComponentHostImpl implements ServiceComponentHost {
ServiceComponentUninstalledEvent event = new ServiceComponentUninstalledEvent(
clusterId, stackName, stackVersion, serviceName, componentName,
- hostName, recoveryEnabled);
+ hostName, recoveryEnabled, host.getHostId());
eventPublisher.publish(event);
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/d03c24b9/ambari-server/src/main/resources/Ambari-DDL-Derby-CREATE.sql
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/Ambari-DDL-Derby-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-Derby-CREATE.sql
index 2b4d15c..7d63494 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-Derby-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-Derby-CREATE.sql
@@ -922,12 +922,23 @@ CREATE TABLE kerberos_principal (
CONSTRAINT PK_kerberos_principal PRIMARY KEY (principal_name)
);
+CREATE TABLE kerberos_keytab (
+ keytab_path VARCHAR(255) NOT NULL,
+ CONSTRAINT PK_krb_keytab_path_host_id PRIMARY KEY (keytab_path)
+);
+
+
CREATE TABLE kerberos_principal_host (
principal_name VARCHAR(255) NOT NULL,
+ keytab_path VARCHAR(255) NOT NULL,
+ is_distributed SMALLINT NOT NULL DEFAULT 0,
host_id BIGINT NOT NULL,
- CONSTRAINT PK_kerberos_principal_host PRIMARY KEY (principal_name, host_id),
+ CONSTRAINT PK_kerberos_principal_host PRIMARY KEY (principal_name, keytab_path, host_id),
CONSTRAINT FK_krb_pr_host_id FOREIGN KEY (host_id) REFERENCES hosts (host_id),
- CONSTRAINT FK_krb_pr_host_principalname FOREIGN KEY (principal_name) REFERENCES kerberos_principal (principal_name));
+ CONSTRAINT FK_krb_pr_host_principalname FOREIGN KEY (principal_name) REFERENCES kerberos_principal (principal_name),
+ CONSTRAINT FK_krb_pr_host_keytab_path FOREIGN KEY (keytab_path) REFERENCES kerberos_keytab (keytab_path)
+);
+
CREATE TABLE kerberos_descriptor
(
http://git-wip-us.apache.org/repos/asf/ambari/blob/d03c24b9/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql
index b487205..af17353 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql
@@ -940,12 +940,21 @@ CREATE TABLE kerberos_principal (
CONSTRAINT PK_kerberos_principal PRIMARY KEY (principal_name)
);
+CREATE TABLE kerberos_keytab (
+ keytab_path VARCHAR(255) NOT NULL,
+ CONSTRAINT PK_krb_keytab_path_host_id PRIMARY KEY (keytab_path)
+);
+
CREATE TABLE kerberos_principal_host (
principal_name VARCHAR(255) NOT NULL,
+ keytab_path VARCHAR(255) NOT NULL,
+ is_distributed SMALLINT NOT NULL DEFAULT 0,
host_id BIGINT NOT NULL,
- CONSTRAINT PK_kerberos_principal_host PRIMARY KEY (principal_name, host_id),
+ CONSTRAINT PK_kerberos_principal_host PRIMARY KEY (principal_name, keytab_path, host_id),
CONSTRAINT FK_krb_pr_host_id FOREIGN KEY (host_id) REFERENCES hosts (host_id),
- CONSTRAINT FK_krb_pr_host_principalname FOREIGN KEY (principal_name) REFERENCES kerberos_principal (principal_name));
+ CONSTRAINT FK_krb_pr_host_principalname FOREIGN KEY (principal_name) REFERENCES kerberos_principal (principal_name),
+ CONSTRAINT FK_krb_pr_host_keytab_path FOREIGN KEY (keytab_path) REFERENCES kerberos_keytab (keytab_path)
+);
CREATE TABLE kerberos_descriptor
(
http://git-wip-us.apache.org/repos/asf/ambari/blob/d03c24b9/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql
index bb87618..89c7971 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql
@@ -919,12 +919,21 @@ CREATE TABLE kerberos_principal (
CONSTRAINT PK_kerberos_principal PRIMARY KEY (principal_name)
);
+CREATE TABLE kerberos_keytab (
+ keytab_path VARCHAR2(255) NOT NULL,
+ CONSTRAINT PK_krb_keytab_path_host_id PRIMARY KEY (keytab_path)
+);
+
CREATE TABLE kerberos_principal_host (
principal_name VARCHAR2(255) NOT NULL,
+ keytab_path VARCHAR2(255) NOT NULL,
+ is_distributed NUMBER(1) DEFAULT 0 NOT NULL,
host_id NUMBER(19) NOT NULL,
- CONSTRAINT PK_kerberos_principal_host PRIMARY KEY (principal_name, host_id),
+ CONSTRAINT PK_kerberos_principal_host PRIMARY KEY (principal_name, keytab_path, host_id),
CONSTRAINT FK_krb_pr_host_id FOREIGN KEY (host_id) REFERENCES hosts (host_id),
- CONSTRAINT FK_krb_pr_host_principalname FOREIGN KEY (principal_name) REFERENCES kerberos_principal (principal_name));
+ CONSTRAINT FK_krb_pr_host_principalname FOREIGN KEY (principal_name) REFERENCES kerberos_principal (principal_name),
+ CONSTRAINT FK_krb_pr_host_keytab_path FOREIGN KEY (keytab_path) REFERENCES kerberos_keytab (keytab_path)
+);
CREATE TABLE kerberos_descriptor
(
http://git-wip-us.apache.org/repos/asf/ambari/blob/d03c24b9/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql
index 7c0611d..3d2bd3a 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql
@@ -921,12 +921,19 @@ CREATE TABLE kerberos_principal (
cached_keytab_path VARCHAR(255),
CONSTRAINT PK_kerberos_principal PRIMARY KEY (principal_name));
+CREATE TABLE kerberos_keytab (
+ keytab_path VARCHAR(255) NOT NULL,
+ CONSTRAINT PK_krb_keytab_path_host_id PRIMARY KEY (keytab_path));
+
CREATE TABLE kerberos_principal_host (
principal_name VARCHAR(255) NOT NULL,
+ keytab_path VARCHAR(255) NOT NULL,
+ is_distributed SMALLINT NOT NULL DEFAULT 0,
host_id BIGINT NOT NULL,
- CONSTRAINT PK_kerberos_principal_host PRIMARY KEY (principal_name, host_id),
+ CONSTRAINT PK_kerberos_principal_host PRIMARY KEY (principal_name, keytab_path, host_id),
CONSTRAINT FK_krb_pr_host_id FOREIGN KEY (host_id) REFERENCES hosts (host_id),
- CONSTRAINT FK_krb_pr_host_principalname FOREIGN KEY (principal_name) REFERENCES kerberos_principal (principal_name));
+ CONSTRAINT FK_krb_pr_host_principalname FOREIGN KEY (principal_name) REFERENCES kerberos_principal (principal_name),
+ CONSTRAINT FK_krb_pr_host_keytab_path FOREIGN KEY (keytab_path) REFERENCES kerberos_keytab (keytab_path));
CREATE TABLE kerberos_descriptor(
kerberos_descriptor_name VARCHAR(255) NOT NULL,
http://git-wip-us.apache.org/repos/asf/ambari/blob/d03c24b9/ambari-server/src/main/resources/Ambari-DDL-SQLAnywhere-CREATE.sql
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/Ambari-DDL-SQLAnywhere-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-SQLAnywhere-CREATE.sql
index e240c5a..55a6c61 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-SQLAnywhere-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-SQLAnywhere-CREATE.sql
@@ -918,12 +918,21 @@ CREATE TABLE kerberos_principal (
CONSTRAINT PK_kerberos_principal PRIMARY KEY (principal_name)
);
+CREATE TABLE kerberos_keytab (
+ keytab_path VARCHAR(255) NOT NULL,
+ CONSTRAINT PK_krb_keytab_path_host_id PRIMARY KEY (keytab_path)
+);
+
CREATE TABLE kerberos_principal_host (
principal_name VARCHAR(255) NOT NULL,
+ keytab_path VARCHAR(255) NOT NULL,
+ is_distributed SMALLINT NOT NULL DEFAULT 0,
host_id NUMERIC(19) NOT NULL,
- CONSTRAINT PK_kerberos_principal_host PRIMARY KEY (principal_name, host_id),
+ CONSTRAINT PK_kerberos_principal_host PRIMARY KEY (principal_name, keytab_path, host_id),
CONSTRAINT FK_krb_pr_host_id FOREIGN KEY (host_id) REFERENCES hosts (host_id),
- CONSTRAINT FK_krb_pr_host_principalname FOREIGN KEY (principal_name) REFERENCES kerberos_principal (principal_name));
+ CONSTRAINT FK_krb_pr_host_principalname FOREIGN KEY (principal_name) REFERENCES kerberos_principal (principal_name),
+ CONSTRAINT FK_krb_pr_host_keytab_path FOREIGN KEY (keytab_path) REFERENCES kerberos_keytab (keytab_path)
+);
CREATE TABLE kerberos_descriptor
(
http://git-wip-us.apache.org/repos/asf/ambari/blob/d03c24b9/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql
index 3839ee4..e5e8af5 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql
@@ -941,12 +941,21 @@ CREATE TABLE kerberos_principal (
CONSTRAINT PK_kerberos_principal PRIMARY KEY CLUSTERED (principal_name)
);
+CREATE TABLE kerberos_keytab (
+ keytab_path VARCHAR(255) NOT NULL,
+ CONSTRAINT PK_krb_keytab_path_host_id PRIMARY KEY CLUSTERED (keytab_path)
+);
+
CREATE TABLE kerberos_principal_host (
principal_name VARCHAR(255) NOT NULL,
+ keytab_path VARCHAR(255) NOT NULL,
+ is_distributed SMALLINT NOT NULL DEFAULT 0,
host_id BIGINT NOT NULL,
- CONSTRAINT PK_kerberos_principal_host PRIMARY KEY CLUSTERED (principal_name, host_id),
+ CONSTRAINT PK_kerberos_principal_host PRIMARY KEY CLUSTERED (principal_name, keytab_path, host_id),
CONSTRAINT FK_krb_pr_host_id FOREIGN KEY (host_id) REFERENCES hosts (host_id),
- CONSTRAINT FK_krb_pr_host_principalname FOREIGN KEY (principal_name) REFERENCES kerberos_principal (principal_name));
+ CONSTRAINT FK_krb_pr_host_principalname FOREIGN KEY (principal_name) REFERENCES kerberos_principal (principal_name),
+ CONSTRAINT FK_krb_pr_host_keytab_path FOREIGN KEY (keytab_path) REFERENCES kerberos_keytab (keytab_path)
+);
CREATE TABLE kerberos_descriptor
(
http://git-wip-us.apache.org/repos/asf/ambari/blob/d03c24b9/ambari-server/src/main/resources/META-INF/persistence.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/META-INF/persistence.xml b/ambari-server/src/main/resources/META-INF/persistence.xml
index 0f8e964..67eef70 100644
--- a/ambari-server/src/main/resources/META-INF/persistence.xml
+++ b/ambari-server/src/main/resources/META-INF/persistence.xml
@@ -45,6 +45,7 @@
<class>org.apache.ambari.server.orm.entities.HostStateEntity</class>
<class>org.apache.ambari.server.orm.entities.HostVersionEntity</class>
<class>org.apache.ambari.server.orm.entities.KerberosPrincipalEntity</class>
+ <class>org.apache.ambari.server.orm.entities.KerberosKeytabEntity</class>
<class>org.apache.ambari.server.orm.entities.KerberosPrincipalHostEntity</class>
<class>org.apache.ambari.server.orm.entities.KeyValueEntity</class>
<class>org.apache.ambari.server.orm.entities.MemberEntity</class>
http://git-wip-us.apache.org/repos/asf/ambari/blob/d03c24b9/ambari-server/src/main/resources/common-services/KERBEROS/1.10.3-10/package/scripts/kerberos_common.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/KERBEROS/1.10.3-10/package/scripts/kerberos_common.py b/ambari-server/src/main/resources/common-services/KERBEROS/1.10.3-10/package/scripts/kerberos_common.py
index 21accdd..fcaa547 100644
--- a/ambari-server/src/main/resources/common-services/KERBEROS/1.10.3-10/package/scripts/kerberos_common.py
+++ b/ambari-server/src/main/resources/common-services/KERBEROS/1.10.3-10/package/scripts/kerberos_common.py
@@ -441,10 +441,9 @@ class KerberosScript(Script):
if principal is not None:
curr_content = Script.structuredOut
- if "keytabs" not in curr_content:
- curr_content['keytabs'] = {}
-
- curr_content['keytabs'][principal.replace("_HOST", params.hostname)] = '_REMOVED_'
+ if "removedKeytabs" not in curr_content:
+ curr_content['removedKeytabs'] = {}
+ curr_content['removedKeytabs'][principal.replace("_HOST", params.hostname)] = keytab_file_path
self.put_structured_out(curr_content)
http://git-wip-us.apache.org/repos/asf/ambari/blob/d03c24b9/ambari-server/src/main/resources/common-services/KERBEROS/1.10.3-30/package/scripts/kerberos_common.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/KERBEROS/1.10.3-30/package/scripts/kerberos_common.py b/ambari-server/src/main/resources/common-services/KERBEROS/1.10.3-30/package/scripts/kerberos_common.py
index 21accdd..fcaa547 100644
--- a/ambari-server/src/main/resources/common-services/KERBEROS/1.10.3-30/package/scripts/kerberos_common.py
+++ b/ambari-server/src/main/resources/common-services/KERBEROS/1.10.3-30/package/scripts/kerberos_common.py
@@ -441,10 +441,9 @@ class KerberosScript(Script):
if principal is not None:
curr_content = Script.structuredOut
- if "keytabs" not in curr_content:
- curr_content['keytabs'] = {}
-
- curr_content['keytabs'][principal.replace("_HOST", params.hostname)] = '_REMOVED_'
+ if "removedKeytabs" not in curr_content:
+ curr_content['removedKeytabs'] = {}
+ curr_content['removedKeytabs'][principal.replace("_HOST", params.hostname)] = keytab_file_path
self.put_structured_out(curr_content)
http://git-wip-us.apache.org/repos/asf/ambari/blob/d03c24b9/ambari-server/src/test/java/org/apache/ambari/server/agent/TestHeartbeatHandler.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/agent/TestHeartbeatHandler.java b/ambari-server/src/test/java/org/apache/ambari/server/agent/TestHeartbeatHandler.java
index 20ff949..b4ff5c1 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/agent/TestHeartbeatHandler.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/agent/TestHeartbeatHandler.java
@@ -1549,7 +1549,7 @@ public class TestHeartbeatHandler {
kerberosIdentityDataFileWriter.writeRecord("c6403.ambari.apache.org", "HDFS", "DATANODE",
"dn/_HOST@_REALM", "service",
"/etc/security/keytabs/dn.service.keytab",
- "hdfs", "r", "hadoop", "", "false", "false");
+ "hdfs", "r", "hadoop", "", "false");
kerberosIdentityDataFileWriter.close();
http://git-wip-us.apache.org/repos/asf/ambari/blob/d03c24b9/ambari-server/src/test/java/org/apache/ambari/server/controller/KerberosHelperTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/KerberosHelperTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/KerberosHelperTest.java
index 7ed52d2..a3074ae 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/KerberosHelperTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/KerberosHelperTest.java
@@ -3456,6 +3456,8 @@ public class KerberosHelperTest extends EasyMockSupport {
if (managingIdentities) {
final Host host = createMockHost("host1");
+ expect(host.getHostId()).andReturn(1l).anyTimes();
+
expect(cluster.getHosts()).andReturn(Collections.singleton(host)).anyTimes();
final ServiceComponentHost schKerberosClient = createMock(ServiceComponentHost.class);
@@ -3463,6 +3465,7 @@ public class KerberosHelperTest extends EasyMockSupport {
expect(schKerberosClient.getServiceComponentName()).andReturn(Role.KERBEROS_CLIENT.name()).anyTimes();
expect(schKerberosClient.getHostName()).andReturn("host1").anyTimes();
expect(schKerberosClient.getState()).andReturn(State.INSTALLED).anyTimes();
+ expect(schKerberosClient.getHost()).andReturn(host).anyTimes();
final ServiceComponent serviceComponentKerberosClient = createNiceMock(ServiceComponent.class);
expect(serviceComponentKerberosClient.getName()).andReturn(Role.KERBEROS_CLIENT.name()).anyTimes();
@@ -3622,12 +3625,15 @@ public class KerberosHelperTest extends EasyMockSupport {
private void testDeleteTestIdentity(final PrincipalKeyCredential PrincipalKeyCredential) throws Exception {
KerberosHelper kerberosHelper = injector.getInstance(KerberosHelper.class);
+ Host host1 = createMock(Host.class);
+ expect(host1.getHostId()).andReturn(1l).anyTimes();
final ServiceComponentHost schKerberosClient = createMock(ServiceComponentHost.class);
expect(schKerberosClient.getServiceName()).andReturn(Service.Type.KERBEROS.name()).anyTimes();
expect(schKerberosClient.getServiceComponentName()).andReturn(Role.KERBEROS_CLIENT.name()).anyTimes();
expect(schKerberosClient.getHostName()).andReturn("host1").anyTimes();
expect(schKerberosClient.getState()).andReturn(State.INSTALLED).anyTimes();
+ expect(schKerberosClient.getHost()).andReturn(host1).anyTimes();
final ServiceComponentHost sch1 = createMock(ServiceComponentHost.class);
expect(sch1.getServiceName()).andReturn("SERVICE1").anyTimes();
http://git-wip-us.apache.org/repos/asf/ambari/blob/d03c24b9/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/HostKerberosIdentityResourceProviderTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/HostKerberosIdentityResourceProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/HostKerberosIdentityResourceProviderTest.java
index 9c94f35..59fbba0 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/HostKerberosIdentityResourceProviderTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/HostKerberosIdentityResourceProviderTest.java
@@ -139,11 +139,12 @@ public class HostKerberosIdentityResourceProviderTest extends EasyMockSupport {
expect(principalDescriptor1.getLocalUsername()).andReturn("principal1");
KerberosKeytabDescriptor keytabDescriptor1 = createStrictMock(KerberosKeytabDescriptor.class);
- expect(keytabDescriptor1.getOwnerAccess()).andReturn("rw").times(1);
- expect(keytabDescriptor1.getGroupAccess()).andReturn("r").times(1);
expect(keytabDescriptor1.getFile()).andReturn("/etc/security/keytabs/principal1.headless.keytab").times(1);
- expect(keytabDescriptor1.getOwnerName()).andReturn("principal1").times(1);
- expect(keytabDescriptor1.getGroupName()).andReturn("principal1").times(1);
+ expect(keytabDescriptor1.getOwnerAccess()).andReturn("rw").once();
+ expect(keytabDescriptor1.getGroupAccess()).andReturn("r").once();
+ expect(keytabDescriptor1.getFile()).andReturn("/etc/security/keytabs/principal1.headless.keytab").times(1);
+ expect(keytabDescriptor1.getOwnerName()).andReturn("principal1").once();
+ expect(keytabDescriptor1.getGroupName()).andReturn("principal1").once();
KerberosIdentityDescriptor identity1 = createStrictMock(KerberosIdentityDescriptor.class);
expect(identity1.getPrincipalDescriptor()).andReturn(principalDescriptor1).times(1);
@@ -189,8 +190,7 @@ public class HostKerberosIdentityResourceProviderTest extends EasyMockSupport {
expect(kerberosPrincipalDAO.exists("principal5@EXAMPLE.COM")).andReturn(false).times(1);
KerberosPrincipalHostDAO kerberosPrincipalHostDAO = createStrictMock(KerberosPrincipalHostDAO.class);
- expect(kerberosPrincipalHostDAO.exists("principal1@EXAMPLE.COM", 100L)).andReturn(true).times(1);
- expect(kerberosPrincipalHostDAO.exists("principal2/Host100@EXAMPLE.COM", 100L)).andReturn(false).times(1);
+ expect(kerberosPrincipalHostDAO.exists("principal1@EXAMPLE.COM", 100L, "/etc/security/keytabs/principal1.headless.keytab")).andReturn(true).times(1);
HostEntity host100 = createStrictMock(HostEntity.class);
expect(host100.getHostId()).andReturn(100L).times(1);
http://git-wip-us.apache.org/repos/asf/ambari/blob/d03c24b9/ambari-server/src/test/java/org/apache/ambari/server/controller/utilities/KerberosIdentityCleanerTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/utilities/KerberosIdentityCleanerTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/utilities/KerberosIdentityCleanerTest.java
index 2518da9..ff0f687 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/utilities/KerberosIdentityCleanerTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/utilities/KerberosIdentityCleanerTest.java
@@ -77,7 +77,7 @@ public class KerberosIdentityCleanerTest extends EasyMockSupport {
@Test
public void removesAllKerberosIdentitesOfComponentAfterComponentWasUninstalled() throws Exception {
installComponent(OOZIE, OOZIE_SERVER, HOST);
- kerberosHelper.deleteIdentities(cluster, singletonList(new Component(HOST, OOZIE, OOZIE_SERVER)), newHashSet("/OOZIE/OOZIE_SERVER/oozie_server1", "/OOZIE/OOZIE_SERVER/oozie_server2"));
+ kerberosHelper.deleteIdentities(cluster, singletonList(new Component(HOST, OOZIE, OOZIE_SERVER, -1l)), newHashSet("/OOZIE/OOZIE_SERVER/oozie_server1", "/OOZIE/OOZIE_SERVER/oozie_server2"));
expectLastCall().once();
replayAll();
uninstallComponent(OOZIE, OOZIE_SERVER, HOST);
@@ -95,7 +95,7 @@ public class KerberosIdentityCleanerTest extends EasyMockSupport {
public void skipsRemovingIdentityThatIsSharedByPrincipalName() throws Exception {
installComponent(OOZIE, OOZIE_SERVER, HOST);
installComponent(OOZIE_2, OOZIE_SERVER_2, HOST);
- kerberosHelper.deleteIdentities(cluster, singletonList(new Component(HOST, OOZIE, OOZIE_SERVER)), newHashSet("/OOZIE/OOZIE_SERVER/oozie_server1"));
+ kerberosHelper.deleteIdentities(cluster, singletonList(new Component(HOST, OOZIE, OOZIE_SERVER, -1l)), newHashSet("/OOZIE/OOZIE_SERVER/oozie_server1"));
expectLastCall().once();
replayAll();
uninstallComponent(OOZIE, OOZIE_SERVER, HOST);
@@ -106,7 +106,7 @@ public class KerberosIdentityCleanerTest extends EasyMockSupport {
public void skipsRemovingIdentityThatIsSharedByKeyTabFilePath() throws Exception {
installComponent(YARN, RESOURCE_MANAGER, HOST);
installComponent(YARN_2, RESOURCE_MANAGER_2, HOST);
- kerberosHelper.deleteIdentities(cluster, singletonList(new Component(HOST, YARN, RESOURCE_MANAGER)), newHashSet("/YARN/RESOURCE_MANAGER/rm_unique"));
+ kerberosHelper.deleteIdentities(cluster, singletonList(new Component(HOST, YARN, RESOURCE_MANAGER, -1l)), newHashSet("/YARN/RESOURCE_MANAGER/rm_unique"));
expectLastCall().once();
replayAll();
uninstallComponent(YARN, RESOURCE_MANAGER, HOST);
@@ -141,7 +141,7 @@ public class KerberosIdentityCleanerTest extends EasyMockSupport {
}
private ArrayList<Component> hdfsComponents() {
- return newArrayList(new Component(HOST, HDFS, NAMENODE), new Component(HOST, HDFS, DATANODE));
+ return newArrayList(new Component(HOST, HDFS, NAMENODE, 0l), new Component(HOST, HDFS, DATANODE, 0l));
}
private void installComponent(String serviceName, String componentName, String... hostNames) {
@@ -163,7 +163,7 @@ public class KerberosIdentityCleanerTest extends EasyMockSupport {
}
private void uninstallComponent(String service, String component, String host) throws KerberosMissingAdminCredentialsException {
- kerberosIdentityCleaner.componentRemoved(new ServiceComponentUninstalledEvent(CLUSTER_ID, "any", "any", service, component, host, false));
+ kerberosIdentityCleaner.componentRemoved(new ServiceComponentUninstalledEvent(CLUSTER_ID, "any", "any", service, component, host, false, -1l));
}
private void uninstallService(String service, List<Component> components) throws KerberosMissingAdminCredentialsException {
http://git-wip-us.apache.org/repos/asf/ambari/blob/d03c24b9/ambari-server/src/test/java/org/apache/ambari/server/events/listeners/upgrade/HostVersionOutOfSyncListenerTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/events/listeners/upgrade/HostVersionOutOfSyncListenerTest.java b/ambari-server/src/test/java/org/apache/ambari/server/events/listeners/upgrade/HostVersionOutOfSyncListenerTest.java
index 24d4f55..108159c 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/events/listeners/upgrade/HostVersionOutOfSyncListenerTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/events/listeners/upgrade/HostVersionOutOfSyncListenerTest.java
@@ -514,7 +514,7 @@ public class HostVersionOutOfSyncListenerTest {
ServiceComponentUninstalledEvent event = new ServiceComponentUninstalledEvent(
c1.getClusterId(), clusterStackId.getStackName(), clusterStackId.getStackVersion(),
- "HDFS", "DATANODE", sch.getHostName(), false);
+ "HDFS", "DATANODE", sch.getHostName(), false, -1l);
m_eventPublisher.publish(event);
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/d03c24b9/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/AbstractPrepareKerberosServerActionTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/AbstractPrepareKerberosServerActionTest.java b/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/AbstractPrepareKerberosServerActionTest.java
index 5522132..d580e6a 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/AbstractPrepareKerberosServerActionTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/AbstractPrepareKerberosServerActionTest.java
@@ -20,6 +20,7 @@ package org.apache.ambari.server.serveraction.kerberos;
import static org.easymock.EasyMock.anyBoolean;
import static org.easymock.EasyMock.anyObject;
+import static org.easymock.EasyMock.createNiceMock;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay;
import static org.easymock.EasyMock.verify;
@@ -33,12 +34,15 @@ import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentMap;
+import javax.persistence.EntityManager;
+
import org.apache.ambari.server.AmbariException;
import org.apache.ambari.server.agent.CommandReport;
import org.apache.ambari.server.audit.AuditLogger;
import org.apache.ambari.server.controller.KerberosHelper;
import org.apache.ambari.server.state.Cluster;
import org.apache.ambari.server.state.Clusters;
+import org.apache.ambari.server.state.Host;
import org.apache.ambari.server.state.Service;
import org.apache.ambari.server.state.ServiceComponentHost;
import org.apache.ambari.server.state.kerberos.KerberosComponentDescriptor;
@@ -52,6 +56,7 @@ import org.junit.Test;
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Injector;
+import com.google.inject.Provider;
public class AbstractPrepareKerberosServerActionTest {
private class PrepareKerberosServerAction extends AbstractPrepareKerberosServerAction{
@@ -79,6 +84,8 @@ public class AbstractPrepareKerberosServerActionTest {
bind(KerberosIdentityDataFileWriterFactory.class).toInstance(kerberosIdentityDataFileWriterFactory);
bind(Clusters.class).toInstance(clusters);
bind(AuditLogger.class).toInstance(auditLogger);
+ Provider<EntityManager> entityManagerProvider = EasyMock.createNiceMock(Provider.class);
+ bind(EntityManager.class).toProvider(entityManagerProvider);
}
});
@@ -131,10 +138,12 @@ public class AbstractPrepareKerberosServerActionTest {
expect(serviceComponentHostHDFS.getHostName()).andReturn(hostName).atLeastOnce();
expect(serviceComponentHostHDFS.getServiceName()).andReturn(hdfsService).atLeastOnce();
expect(serviceComponentHostHDFS.getServiceComponentName()).andReturn(hdfsComponent).atLeastOnce();
+ expect(serviceComponentHostHDFS.getHost()).andReturn(createNiceMock(Host.class)).atLeastOnce();
expect(serviceComponentHostZK.getHostName()).andReturn(hostName).atLeastOnce();
expect(serviceComponentHostZK.getServiceName()).andReturn(zookeeperService).atLeastOnce();
expect(serviceComponentHostZK.getServiceComponentName()).andReturn(zkComponent).atLeastOnce();
+ expect(serviceComponentHostZK.getHost()).andReturn(createNiceMock(Host.class)).atLeastOnce();
expect(kerberosDescriptor.getService(hdfsService)).andReturn(serviceDescriptor).once();
@@ -150,7 +159,7 @@ public class AbstractPrepareKerberosServerActionTest {
identityFilter,
"",
configurations, kerberosConfigurations,
- false, propertiesToIgnore, false);
+ false, propertiesToIgnore);
verify(kerberosHelper);
http://git-wip-us.apache.org/repos/asf/ambari/blob/d03c24b9/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/ConfigureAmbariIdentitiesServerActionTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/ConfigureAmbariIdentitiesServerActionTest.java b/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/ConfigureAmbariIdentitiesServerActionTest.java
index c232117..39dee24 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/ConfigureAmbariIdentitiesServerActionTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/ConfigureAmbariIdentitiesServerActionTest.java
@@ -18,6 +18,9 @@
package org.apache.ambari.server.serveraction.kerberos;
+import static org.easymock.EasyMock.anyObject;
+import static org.easymock.EasyMock.anyString;
+import static org.easymock.EasyMock.eq;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.expectLastCall;
@@ -75,13 +78,11 @@ public class ConfigureAmbariIdentitiesServerActionTest extends EasyMockSupport {
Injector injector = createInjector();
HostEntity hostEntity;
-
if (ambariServerHasAgent) {
KerberosPrincipalHostDAO kerberosPrincipalHostDAO = injector.getInstance(KerberosPrincipalHostDAO.class);
- expect(kerberosPrincipalHostDAO.exists(principal, 1L)).andReturn(false).once();
- kerberosPrincipalHostDAO.create(principal, 1L);
- expectLastCall().once();
-
+ expect(kerberosPrincipalHostDAO.exists(eq(principal), eq(1L), anyString())).andReturn(false).anyTimes();
+ kerberosPrincipalHostDAO.create(anyObject());
+ expectLastCall().anyTimes();
hostEntity = createMock(HostEntity.class);
expect(hostEntity.getHostId()).andReturn(1L).once();
} else {
http://git-wip-us.apache.org/repos/asf/ambari/blob/d03c24b9/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/FinalizeKerberosServerActionTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/FinalizeKerberosServerActionTest.java b/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/FinalizeKerberosServerActionTest.java
index 8b679bf..c9301f3 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/FinalizeKerberosServerActionTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/FinalizeKerberosServerActionTest.java
@@ -30,6 +30,8 @@ import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
+import javax.persistence.EntityManager;
+
import org.apache.ambari.server.AmbariException;
import org.apache.ambari.server.Role;
import org.apache.ambari.server.RoleCommand;
@@ -44,6 +46,7 @@ import org.apache.ambari.server.state.Cluster;
import org.apache.ambari.server.state.Clusters;
import org.apache.ambari.server.state.Host;
import org.apache.ambari.server.state.ServiceComponentHost;
+import org.easymock.EasyMock;
import org.easymock.EasyMockSupport;
import org.junit.Rule;
import org.junit.Test;
@@ -52,6 +55,7 @@ import org.junit.rules.TemporaryFolder;
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Injector;
+import com.google.inject.Provider;
import junit.framework.Assert;
@@ -193,6 +197,7 @@ public class FinalizeKerberosServerActionTest extends EasyMockSupport {
bind(KerberosHelper.class).toInstance(createMock(KerberosHelper.class));
bind(Clusters.class).toInstance(clusters);
bind(AuditLogger.class).toInstance(createNiceMock(AuditLogger.class));
+ bind(EntityManager.class).toProvider(EasyMock.createNiceMock(Provider.class));
}
});
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/d03c24b9/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/KerberosIdentityDataFileTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/KerberosIdentityDataFileTest.java b/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/KerberosIdentityDataFileTest.java
index cfe0fee..323ba8e 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/KerberosIdentityDataFileTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/KerberosIdentityDataFileTest.java
@@ -54,7 +54,7 @@ public class KerberosIdentityDataFileTest {
"principal" + i, "principal_type" + i, "keytabFilePath" + i,
"keytabFileOwnerName" + i, "keytabFileOwnerAccess" + i,
"keytabFileGroupName" + i, "keytabFileGroupAccess" + i,
- "false", "false");
+ "false");
}
// Add some odd characters
@@ -62,7 +62,7 @@ public class KerberosIdentityDataFileTest {
"principal", "principal_type", "keytabFilePath",
"'keytabFileOwnerName'", "<keytabFileOwnerAccess>",
"\"keytabFileGroupName\"", "keytab,File,Group,Access",
- "false", "false");
+ "false");
writer.close();
Assert.assertTrue(writer.isClosed());
@@ -153,7 +153,7 @@ public class KerberosIdentityDataFileTest {
"principal", "principal_type", "keytabFilePath",
"keytabFileOwnerName", "keytabFileOwnerAccess",
"keytabFileGroupName", "keytabFileGroupAccess",
- "true", "false");
+ "true");
writer.close();
Assert.assertTrue(writer.isClosed());
@@ -179,7 +179,7 @@ public class KerberosIdentityDataFileTest {
"principal", "principal_type", "keytabFilePath",
"keytabFileOwnerName", "keytabFileOwnerAccess",
"keytabFileGroupName", "keytabFileGroupAccess",
- "true", "false");
+ "true");
writer.close();
Assert.assertTrue(writer.isClosed());
http://git-wip-us.apache.org/repos/asf/ambari/blob/d03c24b9/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/KerberosServerActionTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/KerberosServerActionTest.java b/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/KerberosServerActionTest.java
index a43db4d..7bf26c5 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/KerberosServerActionTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/serveraction/kerberos/KerberosServerActionTest.java
@@ -32,6 +32,8 @@ import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
+import javax.persistence.EntityManager;
+
import org.apache.ambari.server.AmbariException;
import org.apache.ambari.server.actionmanager.HostRoleCommand;
import org.apache.ambari.server.actionmanager.HostRoleStatus;
@@ -51,6 +53,7 @@ import org.junit.Test;
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Injector;
+import com.google.inject.Provider;
import junit.framework.Assert;
@@ -76,6 +79,8 @@ public class KerberosServerActionTest {
@Override
protected void configure() {
bind(KerberosHelper.class).toInstance(createNiceMock(KerberosHelper.class));
+ Provider<EntityManager> entityManagerProvider = createNiceMock(Provider.class);
+ bind(EntityManager.class).toProvider(entityManagerProvider);
bind(KerberosServerAction.class).toInstance(new KerberosServerAction() {
@Override
@@ -120,7 +125,7 @@ public class KerberosServerActionTest {
"principal|_HOST|_REALM" + i, "principal_type", "keytabFilePath" + i,
"keytabFileOwnerName" + i, "keytabFileOwnerAccess" + i,
"keytabFileGroupName" + i, "keytabFileGroupAccess" + i,
- "false", "false");
+ "false");
}
writer.close();
@@ -202,8 +207,7 @@ public class KerberosServerActionTest {
Assert.assertEquals(HostRoleStatus.COMPLETED.toString(), report.getStatus());
for (Map.Entry<String, Object> entry : sharedMap.entrySet()) {
- Assert.assertEquals(entry.getValue(),
- entry.getKey().replace("_HOST", "hostName").replace("_REALM", "REALM.COM"));
+ Assert.assertEquals(entry.getValue(), entry.getKey());
}
verify(kerberosHelper);
http://git-wip-us.apache.org/repos/asf/ambari/blob/d03c24b9/ambari-server/src/test/java/org/apache/ambari/server/serveraction/upgrades/PreconfigureKerberosActionTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/serveraction/upgrades/PreconfigureKerberosActionTest.java b/ambari-server/src/test/java/org/apache/ambari/server/serveraction/upgrades/PreconfigureKerberosActionTest.java
index a7bf33c..a08f7a0 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/serveraction/upgrades/PreconfigureKerberosActionTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/serveraction/upgrades/PreconfigureKerberosActionTest.java
@@ -70,8 +70,11 @@ import org.apache.ambari.server.metadata.CachedRoleCommandOrderProvider;
import org.apache.ambari.server.metadata.RoleCommandOrderProvider;
import org.apache.ambari.server.orm.DBAccessor;
import org.apache.ambari.server.orm.dao.ArtifactDAO;
+import org.apache.ambari.server.orm.dao.HostDAO;
import org.apache.ambari.server.orm.dao.HostRoleCommandDAO;
import org.apache.ambari.server.orm.dao.KerberosPrincipalDAO;
+import org.apache.ambari.server.orm.entities.HostEntity;
+import org.apache.ambari.server.orm.entities.KerberosKeytabEntity;
import org.apache.ambari.server.orm.entities.RepositoryVersionEntity;
import org.apache.ambari.server.orm.entities.UpgradeEntity;
import org.apache.ambari.server.security.encryption.CredentialStoreService;
@@ -179,6 +182,12 @@ public class PreconfigureKerberosActionTest extends EasyMockSupport {
Injector injector = getInjector();
+ HostDAO hostDAO = injector.getInstance(HostDAO.class);
+ EntityManager entityManager = injector.getInstance(EntityManager.class);
+
+ expect(hostDAO.findByName(anyString())).andReturn(createNiceMock(HostEntity.class)).anyTimes();
+ expect(entityManager.find(eq(KerberosKeytabEntity.class), anyString())).andReturn(createNiceMock(KerberosKeytabEntity.class)).anyTimes();
+
ExecutionCommand executionCommand = createMockExecutionCommand(getDefaultCommandParams());
UpgradeEntity upgradeProgress = createMock(UpgradeEntity.class);
@@ -590,6 +599,7 @@ public class PreconfigureKerberosActionTest extends EasyMockSupport {
bind(Clusters.class).toInstance(createMock(Clusters.class));
bind(StackAdvisorHelper.class).toInstance(createMock(StackAdvisorHelper.class));
bind(ConfigHelper.class).toInstance(createMock(ConfigHelper.class));
+ bind(HostDAO.class).toInstance(createMock(HostDAO.class));
}
});
}
[2/2] ambari git commit: AMBARI-22278. Improve Kerberos principal and
keytab accounting (echekanskiy)
Posted by ec...@apache.org.
AMBARI-22278. Improve Kerberos principal and keytab accounting (echekanskiy)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/d03c24b9
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/d03c24b9
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/d03c24b9
Branch: refs/heads/trunk
Commit: d03c24b9f21cd91af78e0bfca2a1ce1e0de51bdf
Parents: 8a8d48f
Author: Eugene Chekanskiy <ec...@hortonworks.com>
Authored: Thu Oct 12 13:22:15 2017 +0300
Committer: Eugene Chekanskiy <ec...@hortonworks.com>
Committed: Wed Nov 1 17:52:04 2017 +0200
----------------------------------------------------------------------
.../ambari/server/agent/HeartbeatProcessor.java | 72 ++++--
.../controller/DeleteIdentityHandler.java | 3 +-
.../server/controller/KerberosHelper.java | 21 +-
.../server/controller/KerberosHelperImpl.java | 138 +++++++++-
.../HostKerberosIdentityResourceProvider.java | 16 +-
.../ServiceComponentUninstalledEvent.java | 11 +-
.../server/orm/dao/KerberosKeytabDAO.java | 110 ++++++++
.../server/orm/dao/KerberosPrincipalDAO.java | 7 +
.../orm/dao/KerberosPrincipalHostDAO.java | 40 ++-
.../orm/entities/KerberosKeytabEntity.java | 86 +++++++
.../entities/KerberosPrincipalHostEntity.java | 57 +++-
.../entities/KerberosPrincipalHostEntityPK.java | 19 +-
.../AbstractPrepareKerberosServerAction.java | 29 ++-
.../kerberos/CleanupServerAction.java | 14 +-
.../server/serveraction/kerberos/Component.java | 13 +-
.../ConfigureAmbariIdentitiesServerAction.java | 31 ++-
.../kerberos/CreateKeytabFilesServerAction.java | 64 +++--
.../kerberos/CreatePrincipalsServerAction.java | 48 ++--
.../kerberos/KerberosIdentityDataFile.java | 2 -
.../KerberosIdentityDataFileWriter.java | 9 +-
.../kerberos/KerberosServerAction.java | 27 +-
.../PrepareDisableKerberosServerAction.java | 2 +-
.../PrepareEnableKerberosServerAction.java | 2 +-
.../PrepareKerberosIdentitiesServerAction.java | 3 +-
.../stageutils/ResolvedKerberosKeytab.java | 257 +++++++++++++++++++
.../upgrades/PreconfigureKerberosAction.java | 48 +++-
.../apache/ambari/server/state/ServiceImpl.java | 2 +-
.../svccomphost/ServiceComponentHostImpl.java | 2 +-
.../main/resources/Ambari-DDL-Derby-CREATE.sql | 15 +-
.../main/resources/Ambari-DDL-MySQL-CREATE.sql | 13 +-
.../main/resources/Ambari-DDL-Oracle-CREATE.sql | 13 +-
.../resources/Ambari-DDL-Postgres-CREATE.sql | 11 +-
.../resources/Ambari-DDL-SQLAnywhere-CREATE.sql | 13 +-
.../resources/Ambari-DDL-SQLServer-CREATE.sql | 13 +-
.../src/main/resources/META-INF/persistence.xml | 1 +
.../package/scripts/kerberos_common.py | 7 +-
.../package/scripts/kerberos_common.py | 7 +-
.../server/agent/TestHeartbeatHandler.java | 2 +-
.../server/controller/KerberosHelperTest.java | 6 +
...ostKerberosIdentityResourceProviderTest.java | 12 +-
.../utilities/KerberosIdentityCleanerTest.java | 10 +-
.../HostVersionOutOfSyncListenerTest.java | 2 +-
...AbstractPrepareKerberosServerActionTest.java | 11 +-
...nfigureAmbariIdentitiesServerActionTest.java | 11 +-
.../FinalizeKerberosServerActionTest.java | 5 +
.../kerberos/KerberosIdentityDataFileTest.java | 8 +-
.../kerberos/KerberosServerActionTest.java | 10 +-
.../PreconfigureKerberosActionTest.java | 10 +
48 files changed, 1097 insertions(+), 216 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/d03c24b9/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartbeatProcessor.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartbeatProcessor.java b/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartbeatProcessor.java
index 2690008..83d2c98 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartbeatProcessor.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/agent/HeartbeatProcessor.java
@@ -52,7 +52,9 @@ import org.apache.ambari.server.events.publishers.AlertEventPublisher;
import org.apache.ambari.server.events.publishers.AmbariEventPublisher;
import org.apache.ambari.server.events.publishers.VersionEventPublisher;
import org.apache.ambari.server.metadata.ActionMetadata;
+import org.apache.ambari.server.orm.dao.KerberosKeytabDAO;
import org.apache.ambari.server.orm.dao.KerberosPrincipalHostDAO;
+import org.apache.ambari.server.orm.entities.KerberosPrincipalHostEntity;
import org.apache.ambari.server.state.Alert;
import org.apache.ambari.server.state.Cluster;
import org.apache.ambari.server.state.Clusters;
@@ -88,7 +90,6 @@ import com.google.inject.Injector;
/**
* HeartbeatProcessor class is used for bulk processing data retrieved from agents in background
- *
*/
public class HeartbeatProcessor extends AbstractService{
private static final Logger LOG = LoggerFactory.getLogger(HeartbeatProcessor.class);
@@ -135,6 +136,9 @@ public class HeartbeatProcessor extends AbstractService{
KerberosPrincipalHostDAO kerberosPrincipalHostDAO;
@Inject
+ KerberosKeytabDAO kerberosKeytabDao;
+
+ @Inject
Gson gson;
@Inject
@@ -153,7 +157,7 @@ public class HeartbeatProcessor extends AbstractService{
@Override
protected void doStart() {
LOG.info("**** Starting heartbeats processing threads ****");
- for (int i=0; i< poolSize; i++) {
+ for (int i = 0; i < poolSize; i++) {
executor.scheduleAtFixedRate(new HeartbeatProcessingTask(), delay, period, TimeUnit.MILLISECONDS);
}
}
@@ -201,6 +205,7 @@ public class HeartbeatProcessor extends AbstractService{
/**
* Incapsulates logic for processing data from agent heartbeat
+ *
* @param heartbeat Agent heartbeat object
* @throws AmbariException
*/
@@ -217,14 +222,12 @@ public class HeartbeatProcessor extends AbstractService{
}
-
/**
* Extracts all of the {@link Alert}s from the heartbeat and fires
* {@link AlertEvent}s for each one. If there is a problem looking up the
* cluster, then alerts will not be processed.
*
- * @param heartbeat
- * the heartbeat to process.
+ * @param heartbeat the heartbeat to process.
*/
protected void processAlerts(HeartBeat heartbeat) {
if (heartbeat == null) {
@@ -247,6 +250,7 @@ public class HeartbeatProcessor extends AbstractService{
/**
* Update host status basing on components statuses
+ *
* @param heartbeat heartbeat to process
* @throws AmbariException
*/
@@ -349,8 +353,9 @@ public class HeartbeatProcessor extends AbstractService{
/**
* Process reports of tasks executed on agents
+ *
* @param heartbeat heartbeat to process
- * @param now cached current time
+ * @param now cached current time
* @throws AmbariException
*/
protected void processCommandReports(
@@ -424,8 +429,7 @@ public class HeartbeatProcessor extends AbstractService{
String customCommand = report.getCustomCommand();
- boolean adding = SET_KEYTAB.equalsIgnoreCase(customCommand);
- if (adding || REMOVE_KEYTAB.equalsIgnoreCase(customCommand)) {
+ if (SET_KEYTAB.equalsIgnoreCase(customCommand) || REMOVE_KEYTAB.equalsIgnoreCase(customCommand)) {
WriteKeytabsStructuredOut writeKeytabsStructuredOut;
try {
writeKeytabsStructuredOut = gson.fromJson(report.getStructuredOut(), WriteKeytabsStructuredOut.class);
@@ -435,25 +439,35 @@ public class HeartbeatProcessor extends AbstractService{
}
if (writeKeytabsStructuredOut != null) {
- Map<String, String> keytabs = writeKeytabsStructuredOut.getKeytabs();
- if (keytabs != null) {
- for (Map.Entry<String, String> entry : keytabs.entrySet()) {
- String principal = entry.getKey();
- if (!kerberosPrincipalHostDAO.exists(principal, host.getHostId())) {
- if (adding) {
- kerberosPrincipalHostDAO.create(principal, host.getHostId());
- } else if ("_REMOVED_".equalsIgnoreCase(entry.getValue())) {
- kerberosPrincipalHostDAO.remove(principal, host.getHostId());
- }
+ if (SET_KEYTAB.equalsIgnoreCase(customCommand)) {
+ Map<String, String> keytabs = writeKeytabsStructuredOut.getKeytabs();
+ if (keytabs != null) {
+ for (Map.Entry<String, String> entry : keytabs.entrySet()) {
+ String principal = entry.getKey();
+ String keytabPath = entry.getValue();
+ KerberosPrincipalHostEntity kphe = kerberosPrincipalHostDAO.find(principal, host.getHostId(), keytabPath);
+ kphe.setDistributed(true);
+ kerberosPrincipalHostDAO.merge(kphe);
+ }
+ }
+ } else if (REMOVE_KEYTAB.equalsIgnoreCase(customCommand)) {
+ Map<String, String> deletedKeytabs = writeKeytabsStructuredOut.getRemovedKeytabs();
+ if (deletedKeytabs != null) {
+ for (Map.Entry<String, String> entry : deletedKeytabs.entrySet()) {
+ String keytabPath = entry.getValue();
+ kerberosPrincipalHostDAO.removeByKeytabPath(keytabPath);
+ kerberosKeytabDao.remove(keytabPath);
}
}
}
}
} else if (CHECK_KEYTABS.equalsIgnoreCase(customCommand)) {
ListKeytabsStructuredOut structuredOut = gson.fromJson(report.getStructuredOut(), ListKeytabsStructuredOut.class);
- for (MissingKeytab each : structuredOut.missingKeytabs){
- LOG.info("Missing keytab: {} on host: {} principal: {}", each.keytabFilePath, hostname, each.principal);
- kerberosPrincipalHostDAO.remove(each.principal, host.getHostId());
+ for (MissingKeytab each : structuredOut.missingKeytabs) {
+ LOG.info("Missing principal: {} for keytab: {} on host: {}", each.principal, each.keytabFilePath, hostname);
+ KerberosPrincipalHostEntity kphe = kerberosPrincipalHostDAO.find(each.principal, host.getHostId(), each.keytabFilePath);
+ kphe.setDistributed(false);
+ kerberosPrincipalHostDAO.merge(kphe);
}
}
}
@@ -517,7 +531,7 @@ public class HeartbeatProcessor extends AbstractService{
// Necessary for resetting clients stale configs after starting service
if ((RoleCommand.INSTALL.toString().equals(report.getRoleCommand()) ||
(RoleCommand.CUSTOM_COMMAND.toString().equals(report.getRoleCommand()) &&
- "INSTALL".equals(report.getCustomCommand()))) && svcComp.isClientComponent()){
+ "INSTALL".equals(report.getCustomCommand()))) && svcComp.isClientComponent()) {
scHost.updateActualConfigs(report.getConfigurationTags());
scHost.setRestartRequired(false);
}
@@ -588,6 +602,7 @@ public class HeartbeatProcessor extends AbstractService{
/**
* Process reports of status commands
+ *
* @param heartbeat heartbeat to process
* @throws AmbariException
*/
@@ -701,7 +716,10 @@ public class HeartbeatProcessor extends AbstractService{
*/
private static class WriteKeytabsStructuredOut {
@SerializedName("keytabs")
- private Map<String,String> keytabs;
+ private Map<String, String> keytabs;
+
+ @SerializedName("removedKeytabs")
+ private Map<String, String> removedKeytabs;
public Map<String, String> getKeytabs() {
return keytabs;
@@ -710,6 +728,14 @@ public class HeartbeatProcessor extends AbstractService{
public void setKeytabs(Map<String, String> keytabs) {
this.keytabs = keytabs;
}
+
+ public Map<String, String> getRemovedKeytabs() {
+ return removedKeytabs;
+ }
+
+ public void setRemovedKeytabs(Map<String, String> removedKeytabs) {
+ this.removedKeytabs = removedKeytabs;
+ }
}
private static class ListKeytabsStructuredOut {
http://git-wip-us.apache.org/repos/asf/ambari/blob/d03c24b9/ambari-server/src/main/java/org/apache/ambari/server/controller/DeleteIdentityHandler.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/DeleteIdentityHandler.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/DeleteIdentityHandler.java
index 29f8e2a..a7b9d80 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/DeleteIdentityHandler.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/DeleteIdentityHandler.java
@@ -227,8 +227,7 @@ class DeleteIdentityHandler {
calculateConfig(kerberosDescriptor, serviceNames()),
new HashMap<>(),
false,
- new HashMap<>(),
- false);
+ new HashMap<>());
return createCommandReport(0, HostRoleStatus.COMPLETED, "{}", actionLog.getStdOut(), actionLog.getStdErr());
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/d03c24b9/ambari-server/src/main/java/org/apache/ambari/server/controller/KerberosHelper.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/KerberosHelper.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/KerberosHelper.java
index b8e1be1..749943d 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/KerberosHelper.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/KerberosHelper.java
@@ -33,6 +33,7 @@ import org.apache.ambari.server.serveraction.kerberos.KerberosIdentityDataFileWr
import org.apache.ambari.server.serveraction.kerberos.KerberosInvalidConfigurationException;
import org.apache.ambari.server.serveraction.kerberos.KerberosMissingAdminCredentialsException;
import org.apache.ambari.server.serveraction.kerberos.KerberosOperationException;
+import org.apache.ambari.server.serveraction.kerberos.stageutils.ResolvedKerberosKeytab;
import org.apache.ambari.server.state.Cluster;
import org.apache.ambari.server.state.SecurityType;
import org.apache.ambari.server.state.ServiceComponentHost;
@@ -588,15 +589,15 @@ public interface KerberosHelper {
* values
* @param configurations a Map of configurations to use a replacements for variables
* in identity fields
- * @param ignoreHeadless boolean value to specify if headless principals must not be processed
* @return an integer indicating the number of identities added to the data file
* @throws java.io.IOException if an error occurs while writing a record to the data file
*/
int addIdentities(KerberosIdentityDataFileWriter kerberosIdentityDataFileWriter,
Collection<KerberosIdentityDescriptor> identities,
- Collection<String> identityFilter, String hostname, String serviceName,
+ Collection<String> identityFilter, String hostname, Long hostId, String serviceName,
String componentName, Map<String, Map<String, String>> kerberosConfigurations,
- Map<String, Map<String, String>> configurations, boolean ignoreHeadless)
+ Map<String, Map<String, String>> configurations,
+ Map<String, ResolvedKerberosKeytab> resolvedKeytabs, String realm)
throws IOException;
/**
* Calculates the map of configurations relative to the cluster and host.
@@ -735,6 +736,20 @@ public interface KerberosHelper {
PrincipalKeyCredential getKDCAdministratorCredentials(String clusterName) throws AmbariException;
/**
+ * Saves underlying entities in persistent storage.
+ *
+ * @param resolvedKerberosKeytab kerberos keytab to be persisted
+ */
+ void processResolvedKeytab(ResolvedKerberosKeytab resolvedKerberosKeytab);
+
+ /**
+ * Removes existent persisted keytabs if they are not in {@code expectedKeytabs} collection.
+ *
+ * @param expectedKeytabs collection to compare existent keytabs
+ */
+ void removeStaleKeytabs(Collection<ResolvedKerberosKeytab> expectedKeytabs);
+
+ /**
* Translates a collection of configuration specifications (<code>config-type/property-name</code>)
* to a map of configuration types to a set of property names.
* <p>
http://git-wip-us.apache.org/repos/asf/ambari/blob/d03c24b9/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 4f14614..f913831 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
@@ -60,8 +60,11 @@ import org.apache.ambari.server.controller.internal.RequestStageContainer;
import org.apache.ambari.server.controller.utilities.KerberosChecker;
import org.apache.ambari.server.metadata.RoleCommandOrder;
import org.apache.ambari.server.orm.dao.ArtifactDAO;
+import org.apache.ambari.server.orm.dao.KerberosKeytabDAO;
import org.apache.ambari.server.orm.dao.KerberosPrincipalDAO;
+import org.apache.ambari.server.orm.dao.KerberosPrincipalHostDAO;
import org.apache.ambari.server.orm.entities.ArtifactEntity;
+import org.apache.ambari.server.orm.entities.KerberosKeytabEntity;
import org.apache.ambari.server.security.credential.Credential;
import org.apache.ambari.server.security.credential.PrincipalKeyCredential;
import org.apache.ambari.server.security.encryption.CredentialStoreService;
@@ -91,6 +94,7 @@ import org.apache.ambari.server.serveraction.kerberos.PrepareDisableKerberosServ
import org.apache.ambari.server.serveraction.kerberos.PrepareEnableKerberosServerAction;
import org.apache.ambari.server.serveraction.kerberos.PrepareKerberosIdentitiesServerAction;
import org.apache.ambari.server.serveraction.kerberos.UpdateKerberosConfigsServerAction;
+import org.apache.ambari.server.serveraction.kerberos.stageutils.ResolvedKerberosKeytab;
import org.apache.ambari.server.stageplanner.RoleGraph;
import org.apache.ambari.server.stageplanner.RoleGraphFactory;
import org.apache.ambari.server.state.Cluster;
@@ -125,12 +129,14 @@ import org.apache.ambari.server.utils.StageUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang3.tuple.Pair;
import org.apache.directory.server.kerberos.shared.keytab.Keytab;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Sets;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Singleton;
@@ -202,6 +208,12 @@ public class KerberosHelperImpl implements KerberosHelper {
@Inject
private ArtifactDAO artifactDAO;
+ @Inject
+ private KerberosKeytabDAO kerberosKeytabDAO;
+
+ @Inject
+ KerberosPrincipalHostDAO kerberosPrincipalHostDAO;
+
/**
* The injector used to create new instances of helper classes like CreatePrincipalsServerAction
* and CreateKeytabFilesServerAction.
@@ -1484,9 +1496,10 @@ public class KerberosHelperImpl implements KerberosHelper {
@Override
public int addIdentities(KerberosIdentityDataFileWriter kerberosIdentityDataFileWriter,
Collection<KerberosIdentityDescriptor> identities,
- Collection<String> identityFilter, String hostname, String serviceName,
+ Collection<String> identityFilter, String hostname, Long hostId, String serviceName,
String componentName, Map<String, Map<String, String>> kerberosConfigurations,
- Map<String, Map<String, String>> configurations, boolean ignoreHeadless)
+ Map<String, Map<String, String>> configurations,
+ Map<String, ResolvedKerberosKeytab> resolvedKeytabs, String realm)
throws IOException {
int identitiesAdded = 0;
@@ -1514,7 +1527,6 @@ public class KerberosHelperImpl implements KerberosHelper {
String keytabFileGroupName = null;
String keytabFileGroupAccess = null;
String keytabFileConfiguration = null;
- boolean keytabIsCachable = false;
if (keytabDescriptor != null) {
keytabFilePath = variableReplacementHelper.replaceVariables(keytabDescriptor.getFile(), configurations);
@@ -1523,24 +1535,84 @@ public class KerberosHelperImpl implements KerberosHelper {
keytabFileGroupName = variableReplacementHelper.replaceVariables(keytabDescriptor.getGroupName(), configurations);
keytabFileGroupAccess = variableReplacementHelper.replaceVariables(keytabDescriptor.getGroupAccess(), configurations);
keytabFileConfiguration = variableReplacementHelper.replaceVariables(keytabDescriptor.getConfiguration(), configurations);
- keytabIsCachable = keytabDescriptor.isCachable();
+ }
+ // Evaluate the principal "pattern" found in the record to generate the "evaluated principal"
+ // by replacing the _HOST and _REALM variables.
+ String evaluatedPrincipal = principal.replace("_HOST", hostname).replace("_REALM", realm);
+
+ ResolvedKerberosKeytab resolvedKeytab = new ResolvedKerberosKeytab(
+ keytabFilePath,
+ keytabFileOwnerName,
+ keytabFileOwnerAccess,
+ keytabFileGroupName,
+ keytabFileGroupAccess,
+ Sets.newHashSet(Pair.of(hostId, evaluatedPrincipal)),
+ serviceName.equalsIgnoreCase("AMBARI"),
+ componentName.equalsIgnoreCase("AMBARI_SERVER_SELF")
+ );
+ if (resolvedKeytabs.containsKey(keytabFilePath)) {
+ ResolvedKerberosKeytab sameKeytab = resolvedKeytabs.get(keytabFilePath);
+ // validating owner and group
+ String warnTemplate = "Keytab '{}' on host '{}' have different {}, originally set to '{}' and '{}:{}' has '{}', using '{}'";
+ if (!resolvedKeytab.getOwnerName().equals(sameKeytab.getOwnerName())) {
+ LOG.warn(warnTemplate,
+ keytabFilePath, hostname, "owners", sameKeytab.getOwnerName(),
+ serviceName, componentName, resolvedKeytab.getOwnerName(),
+ sameKeytab.getOwnerName());
+ }
+ if (!resolvedKeytab.getOwnerAccess().equals(sameKeytab.getOwnerAccess())) {
+ LOG.warn(warnTemplate,
+ keytabFilePath, hostname, "owner access", sameKeytab.getOwnerAccess(),
+ serviceName, componentName, resolvedKeytab.getOwnerAccess(),
+ sameKeytab.getOwnerAccess());
+ }
+ // TODO probably fail on group difference. Some services can inject its principals to same keytab, but
+ // TODO with different owners, so make sure that keytabs are accessible through group acls
+ // TODO this includes same group name and group 'r' mode
+ if (!resolvedKeytab.getGroupName().equals(sameKeytab.getGroupName())) {
+ LOG.warn(warnTemplate,
+ keytabFilePath, hostname, "groups", sameKeytab.getGroupName(),
+ serviceName, componentName, resolvedKeytab.getGroupName(),
+ sameKeytab.getGroupName());
+ }
+ if (!resolvedKeytab.getGroupAccess().equals(sameKeytab.getGroupAccess())) {
+ LOG.warn(warnTemplate,
+ keytabFilePath, hostname, "group access", sameKeytab.getGroupAccess(),
+ serviceName, componentName, resolvedKeytab.getGroupAccess(),
+ sameKeytab.getGroupAccess());
+ }
+ // end validating
+ // merge principal to keytab
+ sameKeytab.getMappedPrincipals().addAll(resolvedKeytab.getMappedPrincipals());
+ // ensure that keytab file on ambari-server host creating jass file
+ if (sameKeytab.isMustWriteAmbariJaasFile() || resolvedKeytab.isMustWriteAmbariJaasFile()) {
+ sameKeytab.setMustWriteAmbariJaasFile(true);
+ }
+ // ensure that this keytab is ambari-keytab, server will distribute it manually
+ if (sameKeytab.isAmbariServerKeytab() || resolvedKeytab.isAmbariServerKeytab()) {
+ sameKeytab.setAmbariServerKeytab(true);
+ }
+ } else {
+ resolvedKeytabs.put(keytabFilePath, resolvedKeytab);
+ LOG.info("Keytab {} owner:'{}:{}', group:'{}:{}' is defined", keytabFilePath,
+ keytabFileOwnerName, keytabFileOwnerAccess, keytabFileGroupName, keytabFileGroupAccess);
}
// Append an entry to the action data file builder...
+ // TODO obsolete, move to ResolvedKerberosKeytab
if(kerberosIdentityDataFileWriter != null) {
kerberosIdentityDataFileWriter.writeRecord(
hostname,
serviceName,
componentName,
- principal,
+ evaluatedPrincipal,
principalType,
keytabFilePath,
keytabFileOwnerName,
keytabFileOwnerAccess,
keytabFileGroupName,
keytabFileGroupAccess,
- (keytabIsCachable) ? "true" : "false",
- (ignoreHeadless && principalDescriptor.getType() == KerberosPrincipalType.USER) ? "true" : "false");
+ "true");
}
// Add the principal-related configuration to the map of configurations
@@ -1793,6 +1865,46 @@ public class KerberosHelperImpl implements KerberosHelper {
}
}
+ /**
+ * Creates and saves underlying {@link org.apache.ambari.server.orm.entities.KerberosPrincipalEntity},
+ * {@link org.apache.ambari.server.orm.entities.KerberosKeytabEntity} and
+ * {@link org.apache.ambari.server.orm.entities.KerberosPrincipalHostEntity} entities in JPA storage.
+ *
+ * @param resolvedKerberosKeytab kerberos keytab to be persisted
+ */
+ @Override
+ public void processResolvedKeytab(ResolvedKerberosKeytab resolvedKerberosKeytab) {
+ if (kerberosKeytabDAO.find(resolvedKerberosKeytab.getFile()) == null) {
+ kerberosKeytabDAO.create(resolvedKerberosKeytab.getFile());
+ }
+ for (Pair<Long, String> principalPair : resolvedKerberosKeytab.getMappedPrincipals()) {
+ String principal = principalPair.getRight();
+ Long hostId = principalPair.getLeft();
+ if (!kerberosPrincipalDAO.exists(principal)) {
+ kerberosPrincipalDAO.create(principal, false);
+ }
+ if (hostId != null) {
+ if(!kerberosPrincipalHostDAO.exists(principal, hostId, resolvedKerberosKeytab.getFile())) {
+ kerberosPrincipalHostDAO.create(principal, hostId, resolvedKerberosKeytab.getFile());
+ }
+ }
+ }
+ }
+
+ @Override
+ public void removeStaleKeytabs(Collection<ResolvedKerberosKeytab> expectedKeytabs) {
+ List<KerberosKeytabEntity> allKeytabs = kerberosKeytabDAO.findAll();
+ Set<KerberosKeytabEntity> staleKeytabs;
+ staleKeytabs = allKeytabs != null ? new HashSet<>(allKeytabs) : Collections.emptySet();
+ for (ResolvedKerberosKeytab keytab : expectedKeytabs) {
+ staleKeytabs.remove(new KerberosKeytabEntity(keytab.getFile()));
+ }
+ for (KerberosKeytabEntity staleKeytab: staleKeytabs) {
+ kerberosPrincipalHostDAO.removeByKeytabPath(staleKeytab.getKeytabPath());
+ kerberosKeytabDAO.remove(staleKeytab);
+ }
+ }
+
@Override
public Map<String, Set<String>> translateConfigurationSpecifications(Collection<String> configurationSpecifications) {
Map<String, Set<String>> translation = null;
@@ -2181,6 +2293,17 @@ public class KerberosHelperImpl implements KerberosHelper {
if (sch.getState() == State.INSTALLED) {
String hostname = sch.getHostName();
+ if(kerberosKeytabDAO.find(keytabFilePath) == null) {
+ kerberosKeytabDAO.create(keytabFilePath);
+ }
+ // create principals
+ if (!kerberosPrincipalDAO.exists(principal)) {
+ kerberosPrincipalDAO.create(principal, false);
+ }
+ if (!kerberosPrincipalHostDAO.exists(principal, sch.getHost().getHostId(), keytabFilePath)) {
+ kerberosPrincipalHostDAO.create(principal, sch.getHost().getHostId(), keytabFilePath);
+ }
+
kerberosIdentityDataFileWriter.writeRecord(
hostname,
Service.Type.KERBEROS.name(),
@@ -2192,7 +2315,6 @@ public class KerberosHelperImpl implements KerberosHelper {
keytabFileOwnerAccess,
keytabFileGroupName,
keytabFileGroupAccess,
- "false",
"false");
hostsWithValidKerberosClient.add(hostname);
http://git-wip-us.apache.org/repos/asf/ambari/blob/d03c24b9/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HostKerberosIdentityResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HostKerberosIdentityResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HostKerberosIdentityResourceProvider.java
index bfaf7b4..0672500 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HostKerberosIdentityResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/HostKerberosIdentityResourceProvider.java
@@ -76,7 +76,7 @@ public class HostKerberosIdentityResourceProvider extends ReadOnlyResourceProvid
);
protected static final Set<String> PK_PROPERTY_IDS = Collections.unmodifiableSet(
- new HashSet<>(PK_PROPERTY_MAP.values())
+ new HashSet<>(PK_PROPERTY_MAP.values())
);
protected static final Set<String> PROPERTY_IDS = Collections.unmodifiableSet(
@@ -183,7 +183,7 @@ public class HostKerberosIdentityResourceProvider extends ReadOnlyResourceProvid
KerberosPrincipalType principalType = principalDescriptor.getType();
// Assume the principal is a service principal if not specified
- if(principalType == null) {
+ if (principalType == null) {
principalType = KerberosPrincipalType.SERVICE;
}
@@ -194,10 +194,17 @@ public class HostKerberosIdentityResourceProvider extends ReadOnlyResourceProvid
setResourceProperty(resource, KERBEROS_IDENTITY_PRINCIPAL_TYPE_PROPERTY_ID, principalType, requestPropertyIds);
setResourceProperty(resource, KERBEROS_IDENTITY_PRINCIPAL_LOCAL_USERNAME_PROPERTY_ID, principalDescriptor.getLocalUsername(), requestPropertyIds);
+ KerberosKeytabDescriptor keytabDescriptor = descriptor.getKeytabDescriptor();
+
String installedStatus;
+
if ((hostId != null) && kerberosPrincipalDAO.exists(principal)) {
- if (kerberosPrincipalHostDAO.exists(principal, hostId)) {
- installedStatus = "true";
+ if (keytabDescriptor != null) {
+ if (kerberosPrincipalHostDAO.exists(principal, hostId, keytabDescriptor.getFile())) {
+ installedStatus = "true";
+ } else {
+ installedStatus = "false";
+ }
} else {
installedStatus = "false";
}
@@ -207,7 +214,6 @@ public class HostKerberosIdentityResourceProvider extends ReadOnlyResourceProvid
setResourceProperty(resource, KERBEROS_IDENTITY_KEYTAB_FILE_INSTALLED_PROPERTY_ID, installedStatus, requestPropertyIds);
- KerberosKeytabDescriptor keytabDescriptor = descriptor.getKeytabDescriptor();
if (keytabDescriptor != null) {
String ownerAccess = keytabDescriptor.getOwnerAccess();
String groupAccess = keytabDescriptor.getGroupAccess();
http://git-wip-us.apache.org/repos/asf/ambari/blob/d03c24b9/ambari-server/src/main/java/org/apache/ambari/server/events/ServiceComponentUninstalledEvent.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/events/ServiceComponentUninstalledEvent.java b/ambari-server/src/main/java/org/apache/ambari/server/events/ServiceComponentUninstalledEvent.java
index 8acc401..b91135f 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/events/ServiceComponentUninstalledEvent.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/events/ServiceComponentUninstalledEvent.java
@@ -27,6 +27,7 @@ public class ServiceComponentUninstalledEvent extends ServiceEvent {
private final String m_componentName;
private final String m_hostName;
private final boolean m_recoveryEnabled;
+ private final Long m_hostId;
/**
* Constructor.
@@ -40,7 +41,7 @@ public class ServiceComponentUninstalledEvent extends ServiceEvent {
*/
public ServiceComponentUninstalledEvent(long clusterId, String stackName,
String stackVersion, String serviceName, String componentName,
- String hostName, boolean recoveryEnabled) {
+ String hostName, boolean recoveryEnabled, Long hostId) {
super(AmbariEventType.SERVICE_COMPONENT_UNINSTALLED_SUCCESS, clusterId,
stackName,
stackVersion, serviceName);
@@ -48,6 +49,7 @@ public class ServiceComponentUninstalledEvent extends ServiceEvent {
m_componentName = componentName;
m_hostName = hostName;
m_recoveryEnabled = recoveryEnabled;
+ m_hostId = hostId;
}
/**
@@ -71,6 +73,10 @@ public class ServiceComponentUninstalledEvent extends ServiceEvent {
return m_recoveryEnabled;
}
+ public Long getHostId() {
+ return m_hostId;
+ }
+
/**
* {@inheritDoc}
*/
@@ -84,11 +90,12 @@ public class ServiceComponentUninstalledEvent extends ServiceEvent {
buffer.append(", componentName=").append(m_componentName);
buffer.append(", hostName=").append(m_hostName);
buffer.append(", recoveryEnabled=").append(m_recoveryEnabled);
+ buffer.append(", hostId=").append(m_hostId);
buffer.append("}");
return buffer.toString();
}
public Component getComponent() {
- return new Component(getHostName(), getServiceName(), getComponentName());
+ return new Component(getHostName(), getServiceName(), getComponentName(), getHostId());
}
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/d03c24b9/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/KerberosKeytabDAO.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/KerberosKeytabDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/KerberosKeytabDAO.java
new file mode 100644
index 0000000..a8723b7
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/KerberosKeytabDAO.java
@@ -0,0 +1,110 @@
+/*
+ * 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.orm.dao;
+
+import java.util.Collection;
+import java.util.List;
+
+import javax.persistence.EntityManager;
+import javax.persistence.TypedQuery;
+
+import org.apache.ambari.server.orm.RequiresSession;
+import org.apache.ambari.server.orm.entities.HostEntity;
+import org.apache.ambari.server.orm.entities.KerberosKeytabEntity;
+
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+import com.google.inject.Singleton;
+import com.google.inject.persist.Transactional;
+
+@Singleton
+public class KerberosKeytabDAO {
+ @Inject
+ Provider<EntityManager> entityManagerProvider;
+
+ @Transactional
+ public void create(KerberosKeytabEntity kerberosKeytabEntity) {
+ entityManagerProvider.get().persist(kerberosKeytabEntity);
+ }
+
+ public void create(String keytabPath) {
+ create(new KerberosKeytabEntity(keytabPath));
+ }
+
+ @Transactional
+ public KerberosKeytabEntity merge(KerberosKeytabEntity kerberosKeytabEntity) {
+ return entityManagerProvider.get().merge(kerberosKeytabEntity);
+ }
+
+ @Transactional
+ public void remove(KerberosKeytabEntity kerberosKeytabEntity) {
+ entityManagerProvider.get().remove(merge(kerberosKeytabEntity));
+ }
+
+ public void remove(String keytabPath) {
+ KerberosKeytabEntity kke = find(keytabPath);
+ if (kke != null) {
+ remove(kke);
+ }
+ }
+
+ @Transactional
+ public void refresh(KerberosKeytabEntity kerberosKeytabEntity) {
+ entityManagerProvider.get().refresh(kerberosKeytabEntity);
+ }
+
+
+ @RequiresSession
+ public KerberosKeytabEntity find(String keytabPath) {
+ return entityManagerProvider.get().find(KerberosKeytabEntity.class, keytabPath);
+ }
+
+ @RequiresSession
+ public List<KerberosKeytabEntity> findAll() {
+ TypedQuery<KerberosKeytabEntity> query = entityManagerProvider.get().
+ createNamedQuery("KerberosKeytabEntity.findAll", KerberosKeytabEntity.class);
+
+ return query.getResultList();
+ }
+
+ @RequiresSession
+ public boolean exists(String keytabPath) {
+ return find(keytabPath) != null;
+ }
+
+ @RequiresSession
+ public Collection<KerberosKeytabEntity> findByHost(Long hostId) {
+ TypedQuery<KerberosKeytabEntity> query = entityManagerProvider.get().
+ createNamedQuery("KerberosKeytabEntity.findByHost", KerberosKeytabEntity.class);
+ query.setParameter("hostId", hostId);
+ return query.getResultList();
+ }
+
+ public Collection<KerberosKeytabEntity> findByHost(HostEntity hostEntity) {
+ return findByHost(hostEntity.getHostId());
+ }
+
+ public void remove(List<KerberosKeytabEntity> entities) {
+ if (entities != null) {
+ for (KerberosKeytabEntity entity : entities) {
+ entityManagerProvider.get().remove(entity);
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/d03c24b9/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/KerberosPrincipalDAO.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/KerberosPrincipalDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/KerberosPrincipalDAO.java
index 93c55c1..81e4b3d 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/KerberosPrincipalDAO.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/KerberosPrincipalDAO.java
@@ -161,4 +161,11 @@ public class KerberosPrincipalDAO {
return find(principalName) != null;
}
+ public void remove(List<KerberosPrincipalEntity> entities) {
+ if (entities != null) {
+ for (KerberosPrincipalEntity entity : entities) {
+ remove(entity);
+ }
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/d03c24b9/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/KerberosPrincipalHostDAO.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/KerberosPrincipalHostDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/KerberosPrincipalHostDAO.java
index 0c17f19..f27dc48 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/KerberosPrincipalHostDAO.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/KerberosPrincipalHostDAO.java
@@ -56,8 +56,8 @@ public class KerberosPrincipalHostDAO {
entityManagerProvider.get().persist(kerberosPrincipalHostEntity);
}
- public void create(String principal, Long hostId) {
- create(new KerberosPrincipalHostEntity(principal, hostId));
+ public void create(String principal, Long hostId, String keytabPath) {
+ create(new KerberosPrincipalHostEntity(principal, hostId, keytabPath));
}
/**
@@ -121,6 +121,19 @@ public class KerberosPrincipalHostDAO {
}
/**
+ * Find KerberosPrincipalHostEntities for the requested host
+ *
+ * @return a List of requested KerberosPrincipalHostEntities or null if none were found
+ */
+ @RequiresSession
+ public List<KerberosPrincipalHostEntity> findByKeytabPath(String keytabPath) {
+ final TypedQuery<KerberosPrincipalHostEntity> query = entityManagerProvider.get()
+ .createNamedQuery("KerberosPrincipalHostEntityFindByKeytabPath", KerberosPrincipalHostEntity.class);
+ query.setParameter("keytabPath", keytabPath);
+ return query.getResultList();
+ }
+
+ /**
* Find the KerberosPrincipalHostEntity for the specified primary key
*
* @param primaryKey a KerberosPrincipalHostEntityPK containing the requested principal and host names
@@ -139,9 +152,9 @@ public class KerberosPrincipalHostDAO {
* @return the KerberosPrincipalHostEntity or null if not found
*/
@RequiresSession
- public KerberosPrincipalHostEntity find(String principalName, Long hostId) {
+ public KerberosPrincipalHostEntity find(String principalName, Long hostId, String keytabPath) {
return entityManagerProvider.get().find(KerberosPrincipalHostEntity.class,
- new KerberosPrincipalHostEntityPK(principalName, hostId));
+ new KerberosPrincipalHostEntityPK(principalName, hostId, keytabPath));
}
/**
@@ -179,6 +192,15 @@ public class KerberosPrincipalHostDAO {
}
/**
+ * Remove KerberosPrincipalHostEntity instances for the specified host
+ *
+ * @param keytabPath a String indicating the keytab path of principal
+ */
+ @Transactional
+ public void removeByKeytabPath(String keytabPath) {
+ remove(findByKeytabPath(keytabPath));
+ }
+ /**
* Remove KerberosPrincipalHostEntity instance for the specified principal and host
*
* @param principalName a String indicating the name of the principal
@@ -186,8 +208,8 @@ public class KerberosPrincipalHostDAO {
* @see #remove(org.apache.ambari.server.orm.entities.KerberosPrincipalHostEntity)
*/
@Transactional
- public void remove(String principalName, Long hostId) {
- remove(new KerberosPrincipalHostEntity(principalName, hostId));
+ public void remove(String principalName, Long hostId, String keytabPath) {
+ remove(new KerberosPrincipalHostEntity(principalName, hostId, keytabPath));
}
/**
@@ -210,8 +232,8 @@ public class KerberosPrincipalHostDAO {
* @return true if the requested principal exists
*/
@RequiresSession
- public boolean exists(String principalName, Long hostId) {
- return find(principalName, hostId) != null;
+ public boolean exists(String principalName, Long hostId, String keytabPath) {
+ return find(principalName, hostId, keytabPath) != null;
}
/**
@@ -219,7 +241,7 @@ public class KerberosPrincipalHostDAO {
*
* @param entities a collection of KerberosPrincipalHostEntity items to remove
*/
- private void remove(List<KerberosPrincipalHostEntity> entities) {
+ public void remove(List<KerberosPrincipalHostEntity> entities) {
if (entities != null) {
for (KerberosPrincipalHostEntity entity : entities) {
entityManagerProvider.get().remove(entity);
http://git-wip-us.apache.org/repos/asf/ambari/blob/d03c24b9/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/KerberosKeytabEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/KerberosKeytabEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/KerberosKeytabEntity.java
new file mode 100644
index 0000000..a25931b
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/KerberosKeytabEntity.java
@@ -0,0 +1,86 @@
+/*
+ * 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.orm.entities;
+
+import java.util.Collection;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.Id;
+import javax.persistence.NamedQueries;
+import javax.persistence.NamedQuery;
+import javax.persistence.OneToMany;
+import javax.persistence.Table;
+
+@Entity
+@Table(name = "kerberos_keytab")
+@NamedQueries({
+ @NamedQuery(name = "KerberosKeytabEntity.findAll", query = "SELECT kk FROM KerberosKeytabEntity kk"),
+ @NamedQuery(name = "KerberosKeytabEntity.findByHost",
+ query = "SELECT kk FROM KerberosKeytabEntity kk JOIN kk.kerberosPrincipalHostEntities he WHERE he.hostId=:hostId")
+})
+public class KerberosKeytabEntity {
+ @Id
+ @Column(name = "keytab_path", insertable = true, updatable = false, nullable = false)
+ private String keytabPath = null;
+
+ @OneToMany(mappedBy = "keytabEntity", cascade = CascadeType.REMOVE, fetch = FetchType.LAZY)
+ private Collection<KerberosPrincipalHostEntity> kerberosPrincipalHostEntities;
+
+ public KerberosKeytabEntity(){
+
+ }
+
+ public KerberosKeytabEntity(String keytabPath){
+ setKeytabPath(keytabPath);
+ }
+
+ public String getKeytabPath() {
+ return keytabPath;
+ }
+
+ public void setKeytabPath(String keytabPath) {
+ this.keytabPath = keytabPath;
+ }
+
+ public Collection<KerberosPrincipalHostEntity> getKerberosPrincipalHostEntities() {
+ return kerberosPrincipalHostEntities;
+ }
+
+ public void setKerberosPrincipalHostEntities(Collection<KerberosPrincipalHostEntity> kerberosPrincipalHostEntities) {
+ this.kerberosPrincipalHostEntities = kerberosPrincipalHostEntities;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ KerberosKeytabEntity that = (KerberosKeytabEntity) o;
+
+ return keytabPath.equals(that.keytabPath);
+ }
+
+ @Override
+ public int hashCode() {
+ return keytabPath.hashCode();
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/d03c24b9/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/KerberosPrincipalHostEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/KerberosPrincipalHostEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/KerberosPrincipalHostEntity.java
index bb67131..d4e80c6 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/KerberosPrincipalHostEntity.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/KerberosPrincipalHostEntity.java
@@ -23,6 +23,7 @@ import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.IdClass;
import javax.persistence.JoinColumn;
+import javax.persistence.JoinColumns;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
@@ -40,7 +41,9 @@ import javax.persistence.Table;
@NamedQuery(name = "KerberosPrincipalHostEntityFindByPrincipal",
query = "SELECT kph FROM KerberosPrincipalHostEntity kph WHERE kph.principalName=:principalName"),
@NamedQuery(name = "KerberosPrincipalHostEntityFindByHost",
- query = "SELECT kph FROM KerberosPrincipalHostEntity kph WHERE kph.hostId=:hostId")
+ query = "SELECT kph FROM KerberosPrincipalHostEntity kph WHERE kph.hostId=:hostId"),
+ @NamedQuery(name = "KerberosPrincipalHostEntityFindByKeytabPath",
+ query = "SELECT kph FROM KerberosPrincipalHostEntity kph WHERE kph.keytabPath=:keytabPath"),
})
public class KerberosPrincipalHostEntity {
@@ -52,6 +55,10 @@ public class KerberosPrincipalHostEntity {
@Column(name = "host_id", insertable = true, updatable = false, nullable = false)
private Long hostId;
+ @Id
+ @Column(name = "keytab_path", updatable = false, nullable = false)
+ private String keytabPath;
+
@ManyToOne
@JoinColumn(name = "principal_name", referencedColumnName = "principal_name", nullable = false, insertable = false, updatable = false)
private KerberosPrincipalEntity principalEntity;
@@ -60,6 +67,14 @@ public class KerberosPrincipalHostEntity {
@JoinColumn(name = "host_id", referencedColumnName = "host_id", nullable = false, insertable = false, updatable = false)
private HostEntity hostEntity;
+ @ManyToOne
+ @JoinColumns({
+ @JoinColumn(name = "keytab_path", referencedColumnName = "keytab_path", nullable = false, insertable = false, updatable = false)
+ })
+ private KerberosKeytabEntity keytabEntity;
+
+ @Column(name = "is_distributed", insertable = true, updatable = true, nullable = false)
+ private Integer isDistributed = 0;
/**
* Constucts an empty KerberosPrincipalHostEntity
*/
@@ -72,9 +87,23 @@ public class KerberosPrincipalHostEntity {
* @param principalName a String indicating this KerberosPrincipalHostEntity's principal name
* @param hostId a Long indicating the KerberosPrincipalHostEntity's host id
*/
- public KerberosPrincipalHostEntity(String principalName, Long hostId) {
+ public KerberosPrincipalHostEntity(String principalName, Long hostId, String keytabPath) {
+ setPrincipalName(principalName);
+ setHostId(hostId);
+ setKeytabPath(keytabPath);
+ }
+
+ /**
+ * Constructs a new KerberosPrincipalHostEntity
+ *
+ * @param principalName a String indicating this KerberosPrincipalHostEntity's principal name
+ * @param hostId a Long indicating the KerberosPrincipalHostEntity's host id
+ */
+ public KerberosPrincipalHostEntity(String principalName, Long hostId, String keytabPath, boolean isDistributed) {
setPrincipalName(principalName);
setHostId(hostId);
+ setKeytabPath(keytabPath);
+ setDistributed(isDistributed);
}
/**
@@ -157,4 +186,28 @@ public class KerberosPrincipalHostEntity {
public void setPrincipalEntity(KerberosPrincipalEntity principalEntity) {
this.principalEntity = principalEntity;
}
+
+ public String getKeytabPath() {
+ return keytabPath;
+ }
+
+ public void setKeytabPath(String keytabPath) {
+ this.keytabPath = keytabPath;
+ }
+
+ public KerberosKeytabEntity getKeytabEntity() {
+ return keytabEntity;
+ }
+
+ public void setKeytabEntity(KerberosKeytabEntity keytabEntity) {
+ this.keytabEntity = keytabEntity;
+ }
+
+ public Boolean getDistributed() {
+ return isDistributed == 1;
+ }
+
+ public void setDistributed(Boolean isDistributed) {
+ this.isDistributed = (isDistributed) ? 1 : 0;
+ }
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/d03c24b9/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/KerberosPrincipalHostEntityPK.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/KerberosPrincipalHostEntityPK.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/KerberosPrincipalHostEntityPK.java
index 600bb8b..7e57e4a 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/KerberosPrincipalHostEntityPK.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/KerberosPrincipalHostEntityPK.java
@@ -36,12 +36,17 @@ public class KerberosPrincipalHostEntityPK implements Serializable{
@Column(name = "host_id", insertable = false, updatable = false, nullable = false)
private Long hostId = null;
+ @Id
+ @Column(name = "keytab_path", insertable = false, updatable = false, nullable = false)
+ private String keytabPath = null;
+
public KerberosPrincipalHostEntityPK() {
}
- public KerberosPrincipalHostEntityPK(String principalName, Long hostId) {
+ public KerberosPrincipalHostEntityPK(String principalName, Long hostId, String keytabPath) {
setPrincipalName(principalName);
setHostId(hostId);
+ setKeytabPath(keytabPath);
}
/**
@@ -92,11 +97,19 @@ public class KerberosPrincipalHostEntityPK implements Serializable{
KerberosPrincipalHostEntityPK that = (KerberosPrincipalHostEntityPK) o;
return this.principalName.equals(that.principalName) &&
- this.hostId.equals(that.hostId);
+ this.hostId.equals(that.hostId) && this.keytabPath.equals(that.keytabPath);
}
@Override
public int hashCode() {
- return 31 * principalName.hashCode() + hostId.hashCode();
+ return 31 * principalName.hashCode() + hostId.hashCode() + keytabPath.hashCode();
+ }
+
+ public String getKeytabPath() {
+ return keytabPath;
+ }
+
+ public void setKeytabPath(String keytabPath) {
+ this.keytabPath = keytabPath;
}
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/d03c24b9/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 7948a60..1dc8ca8 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
@@ -33,6 +33,7 @@ import java.util.Set;
import org.apache.ambari.server.AmbariException;
import org.apache.ambari.server.agent.CommandReport;
import org.apache.ambari.server.controller.KerberosHelper;
+import org.apache.ambari.server.serveraction.kerberos.stageutils.ResolvedKerberosKeytab;
import org.apache.ambari.server.state.Cluster;
import org.apache.ambari.server.state.ServiceComponentHost;
import org.apache.ambari.server.state.kerberos.KerberosComponentDescriptor;
@@ -77,13 +78,12 @@ public abstract class AbstractPrepareKerberosServerAction extends KerberosServer
Map<String, Map<String, String>> currentConfigurations,
Map<String, Map<String, String>> kerberosConfigurations,
boolean includeAmbariIdentity,
- Map<String, Set<String>> propertiesToBeIgnored,
- boolean excludeHeadless) throws AmbariException {
+ Map<String, Set<String>> propertiesToBeIgnored) throws AmbariException {
List<Component> components = new ArrayList<>();
for (ServiceComponentHost each : schToProcess) {
components.add(Component.fromServiceComponentHost(each));
}
- processServiceComponents(cluster, kerberosDescriptor, components, identityFilter, dataDirectory, currentConfigurations, kerberosConfigurations, includeAmbariIdentity, propertiesToBeIgnored, excludeHeadless);
+ processServiceComponents(cluster, kerberosDescriptor, components, identityFilter, dataDirectory, currentConfigurations, kerberosConfigurations, includeAmbariIdentity, propertiesToBeIgnored);
}
protected void processServiceComponents(Cluster cluster, KerberosDescriptor kerberosDescriptor,
@@ -92,8 +92,7 @@ public abstract class AbstractPrepareKerberosServerAction extends KerberosServer
Map<String, Map<String, String>> currentConfigurations,
Map<String, Map<String, String>> kerberosConfigurations,
boolean includeAmbariIdentity,
- Map<String, Set<String>> propertiesToBeIgnored,
- boolean excludeHeadless) throws AmbariException {
+ Map<String, Set<String>> propertiesToBeIgnored) throws AmbariException {
actionLog.writeStdOut("Processing Kerberos identities and configurations");
@@ -125,15 +124,17 @@ public abstract class AbstractPrepareKerberosServerAction extends KerberosServer
throw new AmbariException(message, e);
}
+ HashMap<String, ResolvedKerberosKeytab> resolvedKeytabs = new HashMap<>();
+ String realm = getDefaultRealm(getCommandParameters());
+
try {
Map<String, Set<String>> propertiesToIgnore = null;
-
// 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 (Component sch : schToProcess) {
String hostName = sch.getHostName();
-
+ Long hostId = sch.getHostId();
String serviceName = sch.getServiceName();
String componentName = sch.getServiceComponentName();
@@ -157,7 +158,8 @@ public abstract class AbstractPrepareKerberosServerAction extends KerberosServer
// Add service-level principals (and keytabs)
kerberosHelper.addIdentities(kerberosIdentityDataFileWriter, serviceIdentities,
- identityFilter, hostName, serviceName, componentName, kerberosConfigurations, currentConfigurations, excludeHeadless);
+ identityFilter, hostName, hostId, serviceName, componentName, kerberosConfigurations, currentConfigurations,
+ resolvedKeytabs, realm);
propertiesToIgnore = gatherPropertiesToIgnore(serviceIdentities, propertiesToIgnore);
KerberosComponentDescriptor componentDescriptor = serviceDescriptor.getComponent(componentName);
@@ -172,7 +174,8 @@ public abstract class AbstractPrepareKerberosServerAction extends KerberosServer
// Add component-level principals (and keytabs)
kerberosHelper.addIdentities(kerberosIdentityDataFileWriter, componentIdentities,
- identityFilter, hostName, serviceName, componentName, kerberosConfigurations, currentConfigurations, excludeHeadless);
+ identityFilter, hostName, hostId, serviceName, componentName, kerberosConfigurations, currentConfigurations,
+ resolvedKeytabs, realm);
propertiesToIgnore = gatherPropertiesToIgnore(componentIdentities, propertiesToIgnore);
}
}
@@ -193,7 +196,8 @@ public abstract class AbstractPrepareKerberosServerAction extends KerberosServer
List<KerberosIdentityDescriptor> componentIdentities = Collections.singletonList(identity);
kerberosHelper.addIdentities(kerberosIdentityDataFileWriter, componentIdentities,
- identityFilter, KerberosHelper.AMBARI_SERVER_HOST_NAME, "AMBARI", componentName, kerberosConfigurations, currentConfigurations, excludeHeadless);
+ identityFilter, StageUtils.getHostName(), ambariServerHostID(), "AMBARI",componentName, kerberosConfigurations, currentConfigurations,
+ resolvedKeytabs, realm);
propertiesToIgnore = gatherPropertiesToIgnore(componentIdentities, propertiesToIgnore);
}
}
@@ -202,6 +206,11 @@ public abstract class AbstractPrepareKerberosServerAction extends KerberosServer
if ((propertiesToBeIgnored != null) && (propertiesToIgnore != null)) {
propertiesToBeIgnored.putAll(propertiesToIgnore);
}
+
+ // create database records for keytabs that must be presented on cluster
+ for (ResolvedKerberosKeytab keytab : resolvedKeytabs.values()) {
+ kerberosHelper.processResolvedKeytab(keytab);
+ }
} catch (IOException e) {
String message = String.format("Failed to write index file - %s", identityDataFile.getAbsolutePath());
LOG.error(message, e);
http://git-wip-us.apache.org/repos/asf/ambari/blob/d03c24b9/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/CleanupServerAction.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/CleanupServerAction.java b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/CleanupServerAction.java
index dae8254..002076d 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/CleanupServerAction.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/CleanupServerAction.java
@@ -32,15 +32,24 @@ import org.apache.ambari.server.controller.spi.Resource;
import org.apache.ambari.server.controller.spi.ResourceProvider;
import org.apache.ambari.server.controller.utilities.ClusterControllerHelper;
import org.apache.ambari.server.controller.utilities.PredicateBuilder;
+import org.apache.ambari.server.orm.dao.KerberosKeytabDAO;
+import org.apache.ambari.server.orm.dao.KerberosPrincipalDAO;
import org.apache.ambari.server.state.Cluster;
import org.apache.ambari.server.state.SecurityType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import com.google.inject.Inject;
+
/**
* Used to perform Kerberos Cleanup Operations as part of the Unkerberization process
*/
public class CleanupServerAction extends KerberosServerAction {
+ @Inject
+ KerberosKeytabDAO kerberosKeytabDAO;
+
+ @Inject
+ KerberosPrincipalDAO kerberosPrincipalDAO;
private final static Logger LOG = LoggerFactory.getLogger(CleanupServerAction.class);
@@ -102,11 +111,12 @@ public class CleanupServerAction extends KerberosServerAction {
ClusterController clusterController = ClusterControllerHelper.getClusterController();
- ResourceProvider artifactProvider =
- clusterController.ensureResourceProvider(Resource.Type.Artifact);
+ ResourceProvider artifactProvider = clusterController.ensureResourceProvider(Resource.Type.Artifact);
try {
artifactProvider.deleteResources(new RequestImpl(null, null, null, null), predicate);
+ kerberosPrincipalDAO.remove(kerberosPrincipalDAO.findAll());
+ kerberosKeytabDAO.remove(kerberosKeytabDAO.findAll());
LOG.info("Kerberos descriptor removed successfully.");
actionLog.writeStdOut("Kerberos descriptor removed successfully.");
} catch (NoSuchResourceException e) {
http://git-wip-us.apache.org/repos/asf/ambari/blob/d03c24b9/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/Component.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/Component.java b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/Component.java
index 4f1ee52..ed7642c 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/Component.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/Component.java
@@ -25,18 +25,21 @@ public class Component {
private final String hostName;
private final String serviceName;
private final String serviceComponentName;
+ private final Long hostId;
public static Component fromServiceComponentHost(ServiceComponentHost serviceComponentHost) {
return new Component(
serviceComponentHost.getHostName(),
serviceComponentHost.getServiceName(),
- serviceComponentHost.getServiceComponentName());
+ serviceComponentHost.getServiceComponentName(),
+ serviceComponentHost.getHost().getHostId());
}
- public Component(String hostName, String serviceName, String serviceComponentName) {
+ public Component(String hostName, String serviceName, String serviceComponentName, Long hostId) {
this.hostName = hostName;
this.serviceName = serviceName;
this.serviceComponentName = serviceComponentName;
+ this.hostId = hostId;
}
public String getHostName() {
@@ -51,6 +54,10 @@ public class Component {
return serviceComponentName;
}
+ public Long getHostId() {
+ return hostId;
+ }
+
@Override
public boolean equals(Object o) {
if (this == o) return true;
@@ -60,6 +67,7 @@ public class Component {
.append(hostName, component.hostName)
.append(serviceName, component.serviceName)
.append(serviceComponentName, component.serviceComponentName)
+ .append(hostId, component.hostId)
.isEquals();
}
@@ -69,6 +77,7 @@ public class Component {
.append(hostName)
.append(serviceName)
.append(serviceComponentName)
+ .append(hostId)
.toHashCode();
}
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/d03c24b9/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/ConfigureAmbariIdentitiesServerAction.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/ConfigureAmbariIdentitiesServerAction.java b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/ConfigureAmbariIdentitiesServerAction.java
index fca1b6f..3384152 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/ConfigureAmbariIdentitiesServerAction.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/ConfigureAmbariIdentitiesServerAction.java
@@ -26,11 +26,10 @@ import java.util.concurrent.ConcurrentMap;
import org.apache.ambari.server.AmbariException;
import org.apache.ambari.server.actionmanager.HostRoleStatus;
import org.apache.ambari.server.agent.CommandReport;
-import org.apache.ambari.server.controller.KerberosHelper;
import org.apache.ambari.server.controller.utilities.KerberosChecker;
-import org.apache.ambari.server.orm.dao.HostDAO;
+import org.apache.ambari.server.orm.dao.KerberosKeytabDAO;
import org.apache.ambari.server.orm.dao.KerberosPrincipalHostDAO;
-import org.apache.ambari.server.orm.entities.HostEntity;
+import org.apache.ambari.server.orm.entities.KerberosPrincipalHostEntity;
import org.apache.ambari.server.serveraction.ActionLog;
import org.apache.ambari.server.utils.ShellCommandUtil;
import org.apache.ambari.server.utils.StageUtils;
@@ -63,7 +62,7 @@ public class ConfigureAmbariIdentitiesServerAction extends KerberosServerAction
private KerberosPrincipalHostDAO kerberosPrincipalHostDAO;
@Inject
- private HostDAO hostDAO;
+ private KerberosKeytabDAO kerberosKeytabDAO;
/**
* Called to execute this action. Upon invocation, calls
@@ -121,7 +120,8 @@ public class ConfigureAmbariIdentitiesServerAction extends KerberosServerAction
} else {
String hostName = identityRecord.get(KerberosIdentityDataFileReader.HOSTNAME);
- if (hostName != null && hostName.equalsIgnoreCase(KerberosHelper.AMBARI_SERVER_HOST_NAME)) {
+ String serviceName = identityRecord.get(KerberosIdentityDataFileReader.SERVICE);
+ if (hostName != null && serviceName.equals("AMBARI")) {
String destKeytabFilePath = identityRecord.get(KerberosIdentityDataFileReader.KEYTAB_FILE_PATH);
File hostDirectory = new File(dataDirectory, hostName);
File srcKeytabFile = new File(hostDirectory, DigestUtils.sha1Hex(destKeytabFilePath));
@@ -182,11 +182,7 @@ public class ConfigureAmbariIdentitiesServerAction extends KerberosServerAction
groupName, groupReadable, groupWritable);
String ambariServerHostName = StageUtils.getHostName();
- HostEntity ambariServerHostEntity = hostDAO.findByName(ambariServerHostName);
- Long ambariServerHostID = (ambariServerHostEntity == null)
- ? null
- : ambariServerHostEntity.getHostId();
-
+ Long ambariServerHostID = ambariServerHostID();
if (ambariServerHostID == null) {
String message = String.format("Failed to add the kerberos_principal_host record for %s on " +
"the Ambari server host since the host id for Ambari server host, %s, was not found." +
@@ -196,8 +192,19 @@ public class ConfigureAmbariIdentitiesServerAction extends KerberosServerAction
if (actionLog != null) {
actionLog.writeStdErr(message);
}
- } else if (!kerberosPrincipalHostDAO.exists(principal, ambariServerHostID)) {
- kerberosPrincipalHostDAO.create(principal, ambariServerHostID);
+ } else if (!kerberosPrincipalHostDAO.exists(principal, ambariServerHostID, destKeytabFilePath)) {
+ if (!kerberosKeytabDAO.exists(destKeytabFilePath)) {
+ kerberosKeytabDAO.create(destKeytabFilePath);
+ }
+ if(!kerberosPrincipalHostDAO.exists(principal, ambariServerHostID, destKeytabFilePath)) {
+ kerberosPrincipalHostDAO.create(
+ new KerberosPrincipalHostEntity(principal, ambariServerHostID, destKeytabFilePath, true)
+ );
+ } else {
+ KerberosPrincipalHostEntity kphe = kerberosPrincipalHostDAO.find(principal, ambariServerHostID, destKeytabFilePath);
+ kphe.setDistributed(true);
+ kerberosPrincipalHostDAO.merge(kphe);
+ }
}
if (actionLog != null) {
http://git-wip-us.apache.org/repos/asf/ambari/blob/d03c24b9/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/CreateKeytabFilesServerAction.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/CreateKeytabFilesServerAction.java b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/CreateKeytabFilesServerAction.java
index 355f515..aa65e61 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/CreateKeytabFilesServerAction.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/CreateKeytabFilesServerAction.java
@@ -205,33 +205,29 @@ public class CreateKeytabFilesServerAction extends KerberosServerAction {
ensureAmbariOnlyAccess(hostDirectory);
}
- if (hostDirectory.exists()) {
- File destinationKeytabFile = new File(hostDirectory, DigestUtils.sha1Hex(keytabFilePath));
- HostEntity hostEntity = hostDAO.findByName(hostName);
- // in case of ambari-server identity there's no host entity for ambari_server host
- if (hostEntity == null && !hostName.equalsIgnoreCase(KerberosHelper.AMBARI_SERVER_HOST_NAME)) {
- message = "Failed to find HostEntity for hostname = " + hostName;
- actionLog.writeStdErr(message);
- LOG.error(message);
- commandReport = createCommandReport(1, HostRoleStatus.FAILED, "{}", actionLog.getStdOut(), actionLog.getStdErr());
- return commandReport;
- }
+ if (hostDirectory.exists()) {
+ File destinationKeytabFile = new File(hostDirectory, DigestUtils.sha1Hex(keytabFilePath));
+ HostEntity hostEntity = hostDAO.findByName(hostName);
+ // in case of ambari-server identity there's no host entity for ambari_server host
+ if (hostEntity == null && !hostName.equalsIgnoreCase(KerberosHelper.AMBARI_SERVER_HOST_NAME)) {
+ message = "Failed to find HostEntity for hostname = " + hostName;
+ actionLog.writeStdErr(message);
+ LOG.error(message);
+ commandReport = createCommandReport(1, HostRoleStatus.FAILED, "{}", actionLog.getStdOut(), actionLog.getStdErr());
+ return commandReport;
+ }
- boolean regenerateKeytabs = getOperationType(getCommandParameters()) == OperationType.RECREATE_ALL;
- boolean onlyKeytabWrite = "true".equalsIgnoreCase(identityRecord.get(KerberosIdentityDataFileReader.ONLY_KEYTAB_WRITE));
- boolean grabKeytabFromCache = regenerateKeytabs && onlyKeytabWrite;
- // if grabKeytabFromCache=true we will try to get keytab from cache and send to agent, it will be true for
- // headless cached keytabs
- if (password == null) {
- if (!grabKeytabFromCache && (hostName.equalsIgnoreCase(KerberosHelper.AMBARI_SERVER_HOST_NAME) || kerberosPrincipalHostDAO
- .exists(evaluatedPrincipal, hostEntity.getHostId()))) {
- // There is nothing to do for this since it must already exist and we don't want to
- // regenerate the keytab
- message = String.format("Skipping keytab file for %s, missing password indicates nothing to do", evaluatedPrincipal);
- LOG.debug(message);
- } else {
- KerberosPrincipalEntity principalEntity = kerberosPrincipalDAO.find(evaluatedPrincipal);
- String cachedKeytabPath = (principalEntity == null) ? null : principalEntity.getCachedKeytabPath();
+ boolean regenerateKeytabs = getOperationType(getCommandParameters()) == OperationType.RECREATE_ALL;
+ if (password == null) {
+ if (!regenerateKeytabs && (hostName.equalsIgnoreCase(KerberosHelper.AMBARI_SERVER_HOST_NAME) || kerberosPrincipalHostDAO
+ .exists(evaluatedPrincipal, hostEntity.getHostId(), keytabFilePath))) {
+ // There is nothing to do for this since it must already exist and we don't want to
+ // regenerate the keytab
+ message = String.format("Skipping keytab file for %s, missing password indicates nothing to do", evaluatedPrincipal);
+ LOG.debug(message);
+ } else {
+ KerberosPrincipalEntity principalEntity = kerberosPrincipalDAO.find(evaluatedPrincipal);
+ String cachedKeytabPath = (principalEntity == null) ? null : principalEntity.getCachedKeytabPath();
if (cachedKeytabPath == null) {
message = String.format("Failed to create keytab for %s, missing cached file", evaluatedPrincipal);
@@ -250,9 +246,7 @@ public class CreateKeytabFilesServerAction extends KerberosServerAction {
}
}
} else {
- boolean canCache = ("true".equalsIgnoreCase(identityRecord.get(KerberosIdentityDataFileReader.KEYTAB_FILE_IS_CACHABLE)));
-
- Keytab keytab = createKeytab(evaluatedPrincipal, password, keyNumber, operationHandler, visitedPrincipalKeys != null, canCache, actionLog);
+ Keytab keytab = createKeytab(evaluatedPrincipal, password, keyNumber, operationHandler, visitedPrincipalKeys != null, true, actionLog);
if (keytab != null) {
try {
@@ -287,7 +281,7 @@ public class CreateKeytabFilesServerAction extends KerberosServerAction {
}
} else {
message = String.format("Failed to create keytab file for %s, the container directory does not exist: %s",
- evaluatedPrincipal, hostDirectory.getAbsolutePath());
+ evaluatedPrincipal, hostDirectory.getAbsolutePath());
actionLog.writeStdErr(message);
LOG.error(message);
commandReport = createCommandReport(1, HostRoleStatus.FAILED, "{}", actionLog.getStdOut(), actionLog.getStdErr());
@@ -299,10 +293,10 @@ public class CreateKeytabFilesServerAction extends KerberosServerAction {
}
}
} finally {
- if(commandReport != null && HostRoleStatus.FAILED.toString().equals(commandReport.getStatus())) {
+ if (commandReport != null && HostRoleStatus.FAILED.toString().equals(commandReport.getStatus())) {
auditEventBuilder.withReasonOfFailure(message == null ? "Unknown error" : message);
}
- if(commandReport != null || auditEventBuilder.hasPrincipal()) {
+ if (commandReport != null || auditEventBuilder.hasPrincipal()) {
auditLog(auditEventBuilder.build());
}
}
@@ -359,12 +353,12 @@ public class CreateKeytabFilesServerAction extends KerberosServerAction {
// and store that location so it can be reused rather than recreate it.
KerberosPrincipalEntity principalEntity = kerberosPrincipalDAO.find(principal);
if (principalEntity != null) {
- if (!principalEntity.isService() && canCache) {
+ if (canCache) {
File cachedKeytabFile = cacheKeytab(principal, keytab);
String previousCachedFilePath = principalEntity.getCachedKeytabPath();
String cachedKeytabFilePath = ((cachedKeytabFile == null) || !cachedKeytabFile.exists())
- ? null
- : cachedKeytabFile.getAbsolutePath();
+ ? null
+ : cachedKeytabFile.getAbsolutePath();
principalEntity.setCachedKeytabPath(cachedKeytabFilePath);
kerberosPrincipalDAO.merge(principalEntity);
http://git-wip-us.apache.org/repos/asf/ambari/blob/d03c24b9/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/CreatePrincipalsServerAction.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/CreatePrincipalsServerAction.java b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/CreatePrincipalsServerAction.java
index 1c0853b9..08e03bd 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/CreatePrincipalsServerAction.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/CreatePrincipalsServerAction.java
@@ -18,6 +18,7 @@
package org.apache.ambari.server.serveraction.kerberos;
+import java.io.File;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
@@ -30,6 +31,7 @@ import org.apache.ambari.server.audit.event.kerberos.CreatePrincipalKerberosAudi
import org.apache.ambari.server.orm.dao.KerberosPrincipalDAO;
import org.apache.ambari.server.orm.dao.KerberosPrincipalHostDAO;
import org.apache.ambari.server.orm.entities.KerberosPrincipalEntity;
+import org.apache.ambari.server.orm.entities.KerberosPrincipalHostEntity;
import org.apache.ambari.server.security.SecurePasswordHelper;
import org.apache.ambari.server.serveraction.ActionLog;
import org.apache.commons.lang.StringUtils;
@@ -128,27 +130,24 @@ public class CreatePrincipalsServerAction extends KerberosServerAction {
seenPrincipals.add(evaluatedPrincipal);
boolean processPrincipal;
+
+ // TODO add invalidate_principals option to make keytabs invalid all over the cluster.
+ KerberosPrincipalEntity kerberosPrincipalEntity = kerberosPrincipalDAO.find(evaluatedPrincipal);
+
boolean regenerateKeytabs = getOperationType(getCommandParameters()) == OperationType.RECREATE_ALL;
if (regenerateKeytabs) {
- // do not process cached identities that can be passed as is(headless identities)
- processPrincipal = "false".equals(identityRecord.get(KerberosIdentityDataFileReader.ONLY_KEYTAB_WRITE).toLowerCase());
+ // force recreation of principal due to keytab regeneration
+ processPrincipal = true;
+ } else if (kerberosPrincipalEntity == null) {
+ // This principal has not been processed before, process it.
+ processPrincipal = true;
+ } else if (!StringUtils.isEmpty(kerberosPrincipalEntity.getCachedKeytabPath())) {
+ // This principal has been processed and a keytab file has been cached for it... do not process it.
+ processPrincipal = false;
} else {
- KerberosPrincipalEntity kerberosPrincipalEntity = kerberosPrincipalDAO.find(evaluatedPrincipal);
-
- if (kerberosPrincipalEntity == null) {
- // This principal has not been processed before, process it.
- processPrincipal = true;
- } else if (!StringUtils.isEmpty(kerberosPrincipalEntity.getCachedKeytabPath())) {
- // This principal has been processed and a keytab file has been cached for it... do not process it.
- processPrincipal = false;
- } else if (kerberosPrincipalHostDAO.exists(evaluatedPrincipal)) {
- // This principal has been processed and a keytab file has been distributed... do not process it.
- processPrincipal = false;
- } else {
- // This principal has been processed but a keytab file for it has not been distributed... process it.
- processPrincipal = true;
- }
+ // This principal has been processed but a keytab file for it has not been distributed... process it.
+ processPrincipal = true;
}
if (processPrincipal) {
@@ -159,7 +158,6 @@ public class CreatePrincipalsServerAction extends KerberosServerAction {
if (password == null) {
boolean servicePrincipal = "service".equalsIgnoreCase(identityRecord.get(KerberosIdentityDataFileReader.PRINCIPAL_TYPE));
CreatePrincipalResult result = createPrincipal(evaluatedPrincipal, servicePrincipal, kerberosConfiguration, operationHandler, regenerateKeytabs, actionLog);
-
if (result == null) {
commandReport = createCommandReport(1, HostRoleStatus.FAILED, "{}", actionLog.getStdOut(), actionLog.getStdErr());
} else {
@@ -167,6 +165,20 @@ public class CreatePrincipalsServerAction extends KerberosServerAction {
principalPasswordMap.put(evaluatedPrincipal, result.getPassword());
principalKeyNumberMap.put(evaluatedPrincipal, result.getKeyNumber());
+ // invalidate given principal for all keytabs to make them redistributed again
+ for (KerberosPrincipalHostEntity kphe: kerberosPrincipalHostDAO.findByPrincipal(evaluatedPrincipal)) {
+ kphe.setDistributed(false);
+ kerberosPrincipalHostDAO.merge(kphe);
+ }
+ // invalidate principal cache
+ KerberosPrincipalEntity principalEntity = kerberosPrincipalDAO.find(evaluatedPrincipal);
+ try {
+ new File(principalEntity.getCachedKeytabPath()).delete();
+ } catch (Exception e) {
+ LOG.debug("Failed to delete cache file '{}'", principalEntity.getCachedKeytabPath());
+ }
+ principalEntity.setCachedKeytabPath(null);
+ kerberosPrincipalDAO.merge(principalEntity);
}
}
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/d03c24b9/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/KerberosIdentityDataFile.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/KerberosIdentityDataFile.java b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/KerberosIdentityDataFile.java
index ddf3d1b..ae1217c 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/KerberosIdentityDataFile.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/KerberosIdentityDataFile.java
@@ -36,6 +36,4 @@ public interface KerberosIdentityDataFile extends KerberosDataFile {
String KEYTAB_FILE_GROUP_NAME = "keytab_file_group_name";
String KEYTAB_FILE_GROUP_ACCESS = "keytab_file_group_access";
String KEYTAB_FILE_IS_CACHABLE = "keytab_file_is_cachable";
- String ONLY_KEYTAB_WRITE = "only_keytab_write";
-
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/d03c24b9/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/KerberosIdentityDataFileWriter.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/KerberosIdentityDataFileWriter.java b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/KerberosIdentityDataFileWriter.java
index ea742bd..f55c6f4 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/KerberosIdentityDataFileWriter.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/KerberosIdentityDataFileWriter.java
@@ -68,8 +68,7 @@ public class KerberosIdentityDataFileWriter extends AbstractKerberosDataFileWrit
String principal, String principalType,
String keytabFilePath, String keytabFileOwnerName,
String keytabFileOwnerAccess, String keytabFileGroupName,
- String keytabFileGroupAccess, String keytabFileCanCache,
- String onlyKeytabWrite)
+ String keytabFileGroupAccess, String keytabFileCanCache)
throws IOException {
super.appendRecord(hostName,
serviceName,
@@ -81,8 +80,7 @@ public class KerberosIdentityDataFileWriter extends AbstractKerberosDataFileWrit
keytabFileOwnerAccess,
keytabFileGroupName,
keytabFileGroupAccess,
- keytabFileCanCache,
- onlyKeytabWrite);
+ keytabFileCanCache);
}
@Override
@@ -97,7 +95,6 @@ public class KerberosIdentityDataFileWriter extends AbstractKerberosDataFileWrit
KEYTAB_FILE_OWNER_ACCESS,
KEYTAB_FILE_GROUP_NAME,
KEYTAB_FILE_GROUP_ACCESS,
- KEYTAB_FILE_IS_CACHABLE,
- ONLY_KEYTAB_WRITE);
+ KEYTAB_FILE_IS_CACHABLE);
}
}